Reland "Merge tag 'vulkan-sdk-1.4.350.0' into main"

This is a reland of commit 5de20d4f0bfe5449ceb4949f10f32d8877e85130

Original change's description:
> Merge tag 'vulkan-sdk-1.4.350.0' into main
>
> Bug: 510484520
> Change-Id: Ic62c603479a37b0237e219d0765ee2569bc7716f
> Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/Vulkan-Loader/+/1708871
> Reviewed-by: Craig Stout <cstout@google.com>

Bug: 510484520
Change-Id: Icf4720f8cef5f4cf9d90d1246fdae38f29ea99c3
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/Vulkan-Loader/+/1721770
SLSA-Policy-Verified: SLSA Policy Verification Service <devtools-gerritcodereview-exitgate@google.com>
Reviewed-by: Craig Stout <cstout@google.com>
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 3ba9d9c..151f98c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -37,14 +37,15 @@
     linux:
         needs: codegen
         runs-on: ${{matrix.os}}
+        timeout-minutes: 30
         strategy:
             matrix:
                 compiler: [ {cc: gcc, cxx: g++}, {cc: clang, cxx: clang++} ]
                 config: [ Debug, Release ]
-                os: [ ubuntu-20.04, ubuntu-22.04 ]
+                os: [ ubuntu-22.04, ubuntu-24.04 ]
         steps:
-            - uses: actions/checkout@v4
-            - uses: actions/setup-python@v5
+            - uses: actions/checkout@v6.0.2
+            - uses: actions/setup-python@v6
               with:
                 python-version: '3.11'
             - name: Test CMake min
@@ -53,15 +54,12 @@
               # practice to try and support them so they don't have to install
               # the CMake tarball. Ideally the minimum we use matches what the default
               # package provided by Ubuntu via APT.
-              if: ${{ matrix.os == 'ubuntu-20.04' }}
+              if: ${{ matrix.os == 'ubuntu-22.04' }}
               uses: lukka/get-cmake@latest
               with:
-                cmakeVersion: 3.17.2
+                cmakeVersion: 3.22.1
             - run: sudo apt update
             - run: sudo apt install --yes --no-install-recommends libwayland-dev libxrandr-dev
-            # This is to combat a bug when using 6.6 linux kernels with thread/address sanitizer
-            # https://github.com/google/sanitizers/issues/1716
-            - run: sudo sysctl vm.mmap_rnd_bits=28
             - run: |
                 cmake -S. -B build \
                 -D CMAKE_BUILD_TYPE=${{ matrix.config }} \
@@ -72,21 +70,23 @@
                 -D CMAKE_CXX_COMPILER=${{ matrix.compiler.cxx }} \
                 -D CMAKE_C_COMPILER=${{ matrix.compiler.cc }}
             - run: cmake --build build
-            - run: ctest --output-on-failure --test-dir build/
+            - run: ctest --parallel --output-on-failure --test-dir build/
             - run: cmake --install build --prefix /tmp
 
     codegen:
       runs-on: ubuntu-latest
+      timeout-minutes: 30
       steps:
-        - uses: actions/checkout@v4
+        - uses: actions/checkout@v6.0.2
         - run: scripts/update_deps.py --dir ext --no-build
         - run: scripts/generate_source.py --verify ext/Vulkan-Headers/registry/
 
     linux-no-asm:
         needs: codegen
-        runs-on: ubuntu-22.04
+        runs-on: ubuntu-24.04
+        timeout-minutes: 30
         steps:
-            - uses: actions/checkout@v4
+            - uses: actions/checkout@v6.0.2
             - run: sudo apt update
             - run: sudo apt install --yes --no-install-recommends libwayland-dev libxrandr-dev
             - run: |
@@ -100,22 +100,23 @@
                 -D CMAKE_CXX_COMPILER=clang++
             - run: cmake --build build
             - run: cmake --install build --prefix /tmp
-            - run: ctest --output-on-failure -E UnknownFunction --test-dir build/
+            - run: ctest --parallel --output-on-failure -E UnknownFunction --test-dir build/
 
     linux-32:
         needs: codegen
-        runs-on: ubuntu-22.04
+        runs-on: ubuntu-24.04
+        timeout-minutes: 30
         strategy:
             matrix:
                 config: [ Debug, Release ]
         steps:
-            - uses: actions/checkout@v4
-            - uses: actions/setup-python@v5
+            - uses: actions/checkout@v6.0.2
+            - uses: actions/setup-python@v6
               with:
                 python-version: '3.11'
             - uses: lukka/get-cmake@latest
               with:
-                cmakeVersion: 3.17.2
+                cmakeVersion: 3.22.1
             - name: Enable 32 bit
               run: sudo dpkg --add-architecture i386
             - run: sudo apt-get update
@@ -130,29 +131,28 @@
                 -D UPDATE_DEPS=ON \
                 -D BUILD_WERROR=ON \
                 -D SYSCONFDIR=/etc/not_vulkan \
-                -D PKG_CONFIG_EXECUTABLE=/usr/bin/i686-linux-gnu-pkg-config \
+                -D CMAKE_CXX_FLAGS=-m32 \
+                -D CMAKE_C_FLAGS=-m32 \
                 -G Ninja
               env:
-                CFLAGS: -m32
-                CXXFLAGS: -m32
-                LDFLAGS: -m32
-                ASFLAGS: --32
+                # https://gitlab.kitware.com/cmake/cmake/-/issues/25317
+                PKG_CONFIG_PATH: /usr/lib/i386-linux-gnu/pkgconfig
             - run: cmake --build build
             - run: cmake --install build --prefix /tmp
-            - run: ctest --output-on-failure
-              working-directory: build/
+            - run: ctest --parallel --output-on-failure --test-dir build/
 
     linux-32-no-asm:
         needs: codegen
-        runs-on: ubuntu-22.04
+        runs-on: ubuntu-24.04
+        timeout-minutes: 30
         steps:
-            - uses: actions/checkout@v4
-            - uses: actions/setup-python@v5
+            - uses: actions/checkout@v6.0.2
+            - uses: actions/setup-python@v6
               with:
                 python-version: '3.11'
             - uses: lukka/get-cmake@latest
               with:
-                cmakeVersion: 3.17.2
+                cmakeVersion: 3.22.1
             - name: Enable 32 bit
               run: sudo dpkg --add-architecture i386
             - run: sudo apt-get update
@@ -167,27 +167,78 @@
                 -D UPDATE_DEPS=ON \
                 -D BUILD_WERROR=ON \
                 -D USE_GAS=OFF \
-                -D PKG_CONFIG_EXECUTABLE=/usr/bin/i686-linux-gnu-pkg-config \
+                -D CMAKE_CXX_FLAGS=-m32 \
+                -D CMAKE_C_FLAGS=-m32 \
                 -G Ninja
               env:
-                CFLAGS: -m32
-                CXXFLAGS: -m32
-                LDFLAGS: -m32
-                ASFLAGS: --32
+                # https://gitlab.kitware.com/cmake/cmake/-/issues/25317
+                PKG_CONFIG_PATH: /usr/lib/i386-linux-gnu/pkgconfig
             - run: cmake --build build
-            - run: ctest --output-on-failure -E UnknownFunction
-              working-directory: build/
+            - run: ctest --parallel --output-on-failure -E UnknownFunction --test-dir build/
+
+    linux-arm:
+        needs: codegen
+        runs-on: ubuntu-24.04-arm
+        timeout-minutes: 30
+        steps:
+            - uses: actions/checkout@v6.0.2
+            - uses: actions/setup-python@v6
+              with:
+                python-version: '3.11'
+            - name: Test CMake min
+              uses: lukka/get-cmake@latest
+              with:
+                  cmakeVersion: 3.22.1
+            - run: sudo apt update
+            - run: sudo apt install --yes --no-install-recommends libwayland-dev libxrandr-dev
+            - run: |
+                  cmake -S. -B build \
+                  -D CMAKE_BUILD_TYPE=Debug \
+                  -D BUILD_TESTS=ON \
+                  -D UPDATE_DEPS=ON \
+                  -D LOADER_ENABLE_ADDRESS_SANITIZER=ON \
+                  -D BUILD_WERROR=ON
+            - run: cmake --build build
+            - run: ctest --parallel --output-on-failure --test-dir build/
+            - run: cmake --install build --prefix /tmp
+
+    linux-threading:
+        needs: codegen
+        runs-on: ubuntu-24.04-arm
+        timeout-minutes: 30
+        steps:
+            - uses: actions/checkout@v6.0.2
+            - uses: actions/setup-python@v6
+              with:
+                python-version: '3.11'
+            - name: Test CMake min
+              uses: lukka/get-cmake@latest
+              with:
+                  cmakeVersion: 3.22.1
+            - run: sudo apt update
+            - run: sudo apt install --yes --no-install-recommends libwayland-dev libxrandr-dev
+            - run: |
+                  cmake -S. -B build \
+                  -D CMAKE_BUILD_TYPE=Debug \
+                  -D BUILD_TESTS=ON \
+                  -D UPDATE_DEPS=ON \
+                  -D LOADER_ENABLE_THREAD_SANITIZER=ON \
+                  -D BUILD_WERROR=ON
+            - run: cmake --build build
+            - run: ctest --parallel --output-on-failure --test-dir build/
+            - run: cmake --install build --prefix /tmp
 
     windows_vs:
         # windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
         needs: linux-no-asm
         runs-on: windows-latest
+        timeout-minutes: 30
         strategy:
             matrix:
                 arch: [ Win32, x64 ]
                 config: [ Debug, Release ]
         steps:
-            - uses: actions/checkout@v4
+            - uses: actions/checkout@v6.0.2
             - run: |
                 cmake -S. -B build `
                 -D BUILD_TESTS=ON `
@@ -197,17 +248,18 @@
                 -D BUILD_WERROR=ON
             - run: cmake --build build/ --config ${{matrix.config}}
             - run: cmake --install build --prefix build/install --config ${{matrix.config}}
-            - run: ctest --output-on-failure -C ${{matrix.config}} --test-dir build/
+            - run: ctest --parallel --output-on-failure -C ${{matrix.config}} --test-dir build/
 
     windows_vs-no-asm:
         # windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
         needs: linux-no-asm
         runs-on: windows-latest
+        timeout-minutes: 30
         strategy:
             matrix:
                 arch: [ Win32, x64 ]
         steps:
-            - uses: actions/checkout@v4
+            - uses: actions/checkout@v6.0.2
             - run: |
                 cmake -S. -B build `
                 -D BUILD_TESTS=ON `
@@ -217,19 +269,20 @@
                 -A ${{ matrix.arch }} `
                 -D BUILD_WERROR=ON
             - run: cmake --build build/ --config Release
-            - run: ctest --output-on-failure -C Release -E UnknownFunction --test-dir build/
+            - run: ctest --parallel --output-on-failure -C Release -E UnknownFunction --test-dir build/
 
     # Test both clang and clang-cl (Chromium project uses clang-cl)
     windows_clang:
       # windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
-      needs: linux-no-asm
-      runs-on: windows-2022
-      strategy:
-        matrix:
-            compiler: [ clang, clang-cl ]
-            config: [ Debug, Release ]
-      steps:
-          - uses: actions/checkout@v4
+        needs: linux-no-asm
+        runs-on: windows-2022
+        timeout-minutes: 30
+        strategy:
+            matrix:
+                compiler: [ clang, clang-cl ]
+                config: [ Debug, Release ]
+        steps:
+          - uses: actions/checkout@v6.0.2
           - uses: ilammy/msvc-dev-cmd@v1
           - run: |
               cmake -S. -B build `
@@ -241,23 +294,23 @@
               -D BUILD_TESTS=ON `
               -G Ninja
           - run: cmake --build build/
-          - run: ctest --output-on-failure --test-dir build/
+          - run: ctest --parallel --output-on-failure --test-dir build/
           - run: cmake --install build --prefix build/install
 
     mac:
         # Mac is 10x expensive to run on GitHub machines, so only run if we know something else passed as well
         needs: windows_clang
-        runs-on: macos-13
+        runs-on: macos-14
+        timeout-minutes: 30
         strategy:
             matrix:
                 config: [ Debug, Release ]
                 static_build: [ APPLE_STATIC_LOADER=ON, APPLE_STATIC_LOADER=OFF ]
         steps:
-            - uses: actions/checkout@v4
-            - uses: actions/setup-python@v5
+            - uses: actions/checkout@v6.0.2
+            - uses: actions/setup-python@v6
               with:
                 python-version: '3.11'
-            - uses: lukka/get-cmake@latest
             - run: |
                 cmake -S. -B build \
                 -D CMAKE_BUILD_TYPE=${{matrix.config}} \
@@ -272,22 +325,22 @@
                 LDFLAGS: -Wl,-fatal_warnings
             - run: cmake --build build
             - run: cmake --install build --prefix /tmp
-            - run: ctest --output-on-failure --test-dir build/
+            - run: ctest --parallel --output-on-failure --test-dir build/
 
     apple-cross-compile:
-      # Mac is 10x expensive to run on GitHub machines, so only run if we know something else passed as well
-      needs: windows_clang
-      name: ${{ matrix.CMAKE_SYSTEM_NAME }}
-      runs-on: macos-13
-      strategy:
-          matrix:
-            CMAKE_SYSTEM_NAME: [ iOS, tvOS ]
-      steps:
-          - uses: actions/checkout@v4
-          - uses: actions/setup-python@v5
+        # Mac is 10x expensive to run on GitHub machines, so only run if we know something else passed as well
+        needs: windows_clang
+        name: ${{ matrix.CMAKE_SYSTEM_NAME }}
+        runs-on: macos-14
+        timeout-minutes: 30
+        strategy:
+            matrix:
+                CMAKE_SYSTEM_NAME: [ iOS, tvOS ]
+        steps:
+          - uses: actions/checkout@v6.0.2
+          - uses: actions/setup-python@v6
             with:
               python-version: '3.11'
-          - uses: lukka/get-cmake@latest
           - run: |
               cmake -S . -B build \
               -D CMAKE_SYSTEM_NAME=${{ matrix.CMAKE_SYSTEM_NAME }} \
@@ -312,16 +365,16 @@
         needs: windows_clang
         name: "Universal Binary Testing (STATIC ${{ matrix.static }}) w/ ${{ matrix.generator }}"
         runs-on: macos-latest
+        timeout-minutes: 30
         strategy:
             matrix:
                 static: [ 'ON', 'OFF' ]
                 generator: [ Ninja, Xcode ]
         steps:
-            - uses: actions/checkout@v4
-            - uses: actions/setup-python@v5
+            - uses: actions/checkout@v6.0.2
+            - uses: actions/setup-python@v6
               with:
                 python-version: '3.11'
-            - uses: lukka/get-cmake@latest
             - run: |
                 cmake -S. -B build \
                 -D CMAKE_BUILD_TYPE=Release \
@@ -334,7 +387,7 @@
               env:
                 LDFLAGS: -Wl,-fatal_warnings
             - run: cmake --build build --config Release
-            - run: ctest --output-on-failure --build-config Release -E UnknownFunction --test-dir build/
+            - run: ctest --parallel --output-on-failure --build-config Release -E UnknownFunction --test-dir build/
             - run: cmake --install build --config Release --prefix /tmp
             - name: Verify Universal Binary
               if: ${{ matrix.static == 'OFF' }}
@@ -343,102 +396,103 @@
                 vtool -show-build /tmp/lib/libvulkan.dylib | grep 'architecture arm64'
 
     chromium:
-      needs: codegen
-      runs-on: ubuntu-latest
-      steps:
-        - uses: actions/checkout@v4
-        - run: scripts/gn/gn.py
+        needs: codegen
+        runs-on: ubuntu-latest
+        timeout-minutes: 30
+        steps:
+            - uses: actions/checkout@v6.0.2
+            - run: scripts/gn/gn.py
 
     mingw:
-      # windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
-      needs: linux-no-asm
-      runs-on: windows-2022
-      defaults:
-        run:
-          shell: bash
-      steps:
-        - uses: actions/checkout@v4
-        - uses: actions/setup-python@v5
-          with:
-            python-version: '3.11'
-        - uses: lukka/get-cmake@latest
-        - name: Setup uasm
-          run: |
-            C:/msys64/usr/bin/pacman -Sy --noconfirm --needed mingw-w64-x86_64-uasm
-            printf '%s\n' 'C:/msys64/mingw64/bin' >> $GITHUB_PATH
-        - name: UASM Check
-          run: uasm -?
-        - run: |
-            cmake -S. -B build \
-            -D UPDATE_DEPS=ON \
-            -D CMAKE_BUILD_TYPE=Release \
-            -D BUILD_WERROR=ON \
-            -G Ninja
-        - run: cmake --build build
-        - run: cmake --install build --prefix /tmp
+        # windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
+        needs: linux-no-asm
+        runs-on: windows-latest
+        timeout-minutes: 30
+        defaults:
+            run:
+                shell: bash
+        steps:
+            - uses: actions/checkout@v6.0.2
+            - uses: actions/setup-python@v6
+              with:
+                python-version: '3.11'
+            - name: Setup uasm
+              run: |
+                C:/msys64/usr/bin/pacman -Sy --noconfirm --needed mingw-w64-x86_64-uasm
+                printf '%s\n' 'C:/msys64/mingw64/bin' >> $GITHUB_PATH
+            - name: UASM Check
+              run: uasm -?
+            - run: |
+                cmake -S. -B build \
+                -D UPDATE_DEPS=ON \
+                -D CMAKE_BUILD_TYPE=Release \
+                -D BUILD_WERROR=ON \
+                -G Ninja
+            - run: cmake --build build
+            - run: cmake --install build --prefix /tmp
 
     mingw-use-gas:
-      # windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
-      needs: linux-no-asm
-      runs-on: windows-2022
-      defaults:
-        run:
-          shell: bash
-      steps:
-        - uses: actions/checkout@v4
-        - uses: actions/setup-python@v5
-          with:
-            python-version: '3.11'
-        - uses: lukka/get-cmake@latest
-        - run: |
-            cmake -S. -B build \
-            -D UPDATE_DEPS=ON \
-            -D CMAKE_BUILD_TYPE=Release \
-            -D BUILD_WERROR=ON \
-            -D USE_GAS=ON \
-            -G Ninja
-        - run: cmake --build build
-        - run: cmake --install build --prefix /tmp
+        # windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
+        needs: linux-no-asm
+        runs-on: windows-2022
+        timeout-minutes: 30
+        defaults:
+            run:
+                shell: bash
+        steps:
+            - uses: actions/checkout@v6.0.2
+            - uses: actions/setup-python@v6
+              with:
+                python-version: '3.11'
+            - run: |
+                cmake -S. -B build \
+                -D UPDATE_DEPS=ON \
+                -D CMAKE_BUILD_TYPE=Release \
+                -D BUILD_WERROR=ON \
+                -D USE_GAS=ON \
+                -G Ninja
+            - run: cmake --build build
+            - run: cmake --install build --prefix /tmp
 
     mingw-no-asm:
-      # windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
-      needs: linux-no-asm
-      runs-on: windows-2022
-      defaults:
-        run:
-          shell: bash
-      steps:
-        - uses: actions/checkout@v4
-        - uses: actions/setup-python@v5
-          with:
-            python-version: '3.11'
-        - uses: lukka/get-cmake@latest
-        # Make sure this doesn't fail even without explicitly setting '-D USE_MASM=OFF' and without uasm
-        - run: |
-            cmake -S. -B build \
-            -D UPDATE_DEPS=ON \
-            -D CMAKE_BUILD_TYPE=Release \
-            -D BUILD_WERROR=ON \
-            -G Ninja
-        - run: cmake --build build
-        - run: cmake --install build --prefix /tmp
+        # windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
+        needs: linux-no-asm
+        runs-on: windows-2022
+        timeout-minutes: 30
+        defaults:
+            run:
+                shell: bash
+        steps:
+            - uses: actions/checkout@v6.0.2
+            - uses: actions/setup-python@v6
+              with:
+                python-version: '3.11'
+            # Make sure this doesn't fail even without explicitly setting '-D USE_MASM=OFF' and without uasm
+            - run: |
+                cmake -S. -B build \
+                -D UPDATE_DEPS=ON \
+                -D CMAKE_BUILD_TYPE=Release \
+                -D BUILD_WERROR=ON \
+                -G Ninja
+            - run: cmake --build build
+            - run: cmake --install build --prefix /tmp
 
     mingw-no-asm-explicit:
-      # windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
-      needs: linux-no-asm
-      runs-on: windows-2022
-      defaults:
-        run:
-          shell: bash
-      steps:
-        - uses: actions/checkout@v4
-        - uses: lukka/get-cmake@latest
-        - run: |
-            cmake -S. -B build \
-            -D UPDATE_DEPS=ON \
-            -D CMAKE_BUILD_TYPE=Release \
-            -D BUILD_WERROR=ON \
-            -D USE_MASM=OFF \
-            -G Ninja
-        - run: cmake --build build
-        - run: cmake --install build --prefix /tmp
+        # windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
+        needs: linux-no-asm
+        runs-on: windows-2022
+        timeout-minutes: 30
+        defaults:
+            run:
+                shell: bash
+        steps:
+            - uses: actions/checkout@v6.0.2
+            - run: |
+                cmake -S. -B build \
+                -D UPDATE_DEPS=ON \
+                -D CMAKE_BUILD_TYPE=Release \
+                -D BUILD_WERROR=ON \
+                -D USE_MASM=OFF \
+                -G Ninja
+            - run: cmake --build build
+            - run: cmake --install build --prefix /tmp
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 737ca11..9c621d0 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -49,11 +49,11 @@
 
     steps:
     - name: Checkout repository
-      uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+      uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v5.0.1
 
     # Initializes the CodeQL tools for scanning.
     - name: Initialize CodeQL
-      uses: github/codeql-action/init@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9
+      uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v3.29.5
       with:
         languages: ${{ matrix.language }}
     #     If you wish to specify custom queries, you can do so here or in a config file.
@@ -68,16 +68,12 @@
     # If this step fails, then you should remove it and run the build manually
     - name: Autobuild
       if: matrix.language == 'python' 
-      uses: github/codeql-action/autobuild@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9
+      uses: github/codeql-action/autobuild@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v3.29.5
 
-    - uses: actions/setup-python@v5
+    - uses: actions/setup-python@v6
       if: matrix.language == 'cpp'
       with:
         python-version: '3.11'
-    - uses: lukka/get-cmake@latest
-      if: matrix.language == 'cpp'
-      with:
-        cmakeVersion: 3.17.2
     - name: Install Dependencies
       if: matrix.language == 'cpp'
       run: |
@@ -96,6 +92,6 @@
       run: cmake --build build
     
     - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9
+      uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v3.29.5
       with:
         category: "/language:${{matrix.language}}"
diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml
index fd6f741..496b484 100644
--- a/.github/workflows/format.yml
+++ b/.github/workflows/format.yml
@@ -1,17 +1,7 @@
-# Copyright (c) 2023 Valve Corporation
-# Copyright (c) 2023 LunarG, Inc.
+# Copyright 2026 Valve Corporation
+# Copyright 2026 LunarG, Inc.
 #
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
 
 name: format
 
@@ -28,16 +18,18 @@
   clang-format:
     name: clang-format
     runs-on: ubuntu-latest
-    strategy:
-      fail-fast: false
-      matrix:
-        path:
-          - 'loader'
-          - 'tests'
+
+    env:
+      CLANG_FORMAT_VERSION: 16
+      CLANG_FORMAT_FILES: "*.c *.h *.cpp *.hpp"
+
     steps:
-    - uses: actions/checkout@v4
-    - name: Run clang-format
-      uses: jidicula/clang-format-action@v4.14.0
-      with:
-        clang-format-version: '16'
-        check-path: ${{ matrix.path }}
+    - uses: actions/checkout@v6.0.2
+    - name: Check formatting
+      run: |
+        for f in $(git ls-files -- ${CLANG_FORMAT_FILES}); do
+          echo "Checking $f"
+          clang-format-${CLANG_FORMAT_VERSION} -i --Werror "$f"
+        done
+
+        git diff --exit-code
diff --git a/BUILD.gn b/BUILD.gn
index dad5b13..07b18a2 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -272,7 +272,10 @@
       deps += [ ":gen_loader_rc" ]
     }
     if (is_linux || is_chromeos) {
-      libs = [ "dl" ]
+      libs = [
+        "dl",
+        "pthread",
+      ]
       sources += [
         "loader/loader_linux.c",
         "loader/loader_linux.h",
diff --git a/BUILD.md b/BUILD.md
index 88f6f6d..062e8ec 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -1,61 +1,60 @@
-# Build Instructions
+# Build Instructions <!-- omit from toc -->
 
 Instructions for building this repository on Linux, Windows, and MacOS.
 
-## Table Of Contents
+## Table Of Contents <!-- omit from toc -->
 
-- [Build Instructions](#build-instructions)
-  - [Table Of Contents](#table-of-contents)
-  - [Contributing to the Repository](#contributing-to-the-repository)
-  - [Repository Content](#repository-content)
-    - [Installed Files](#installed-files)
-  - [Build Requirements](#build-requirements)
-    - [Test Requirements](#test-requirements)
-  - [Repository Set-Up](#repository-set-up)
-    - [Display Drivers](#display-drivers)
-    - [Repository Dependencies](#repository-dependencies)
-      - [Vulkan-Headers](#vulkan-headers)
-      - [Test Dependencies](#test-dependencies)
-    - [Warnings as errors off by default!](#warnings-as-errors-off-by-default)
-    - [Build and Install Directory Locations](#build-and-install-directory-locations)
-    - [Building Dependent Repositories with Known-Good Revisions](#building-dependent-repositories-with-known-good-revisions)
-      - [Automatically](#automatically)
-      - [Manually](#manually)
-        - [Notes About the Manual Option](#notes-about-the-manual-option)
-    - [Generated source code](#generated-source-code)
-    - [Build Options](#build-options)
-  - [Building On Windows](#building-on-windows)
-    - [Windows Development Environment Requirements](#windows-development-environment-requirements)
-    - [Windows Build - Microsoft Visual Studio](#windows-build---microsoft-visual-studio)
-      - [Windows Quick Start](#windows-quick-start)
-      - [Use `CMake` to Create the Visual Studio Project Files](#use-cmake-to-create-the-visual-studio-project-files)
-      - [Build the Solution From the Command Line](#build-the-solution-from-the-command-line)
-      - [Build the Solution With Visual Studio](#build-the-solution-with-visual-studio)
-      - [Windows Install Target](#windows-install-target)
-  - [Building On Linux](#building-on-linux)
-    - [Linux Development Environment Requirements](#linux-development-environment-requirements)
-      - [Required Package List](#required-package-list)
-    - [Linux Build](#linux-build)
-      - [Linux Quick Start](#linux-quick-start)
-      - [Use CMake to Create the Make Files](#use-cmake-to-create-the-make-files)
-      - [Build the Project](#build-the-project)
-    - [Linux Notes](#linux-notes)
-      - [WSI Support Build Options](#wsi-support-build-options)
-      - [Linux Install to System Directories](#linux-install-to-system-directories)
-      - [Linux 32-bit support](#linux-32-bit-support)
-  - [Building on MacOS](#building-on-macos)
-    - [MacOS Development Environment Requirements](#macos-development-environment-requirements)
-    - [Clone the Repository](#clone-the-repository)
-    - [MacOS build](#macos-build)
-      - [Building with the Unix Makefiles Generator](#building-with-the-unix-makefiles-generator)
-      - [Building with the Xcode Generator](#building-with-the-xcode-generator)
-  - [Building on Fuchsia](#building-on-fuchsia)
-    - [SDK Symbols](#sdk-symbols)
-  - [Building on QNX](#building-on-qnx)
-  - [Cross Compilation](#cross-compilation)
-    - [Unknown function handling which requires explicit assembly implementations](#unknown-function-handling-which-requires-explicit-assembly-implementations)
-      - [Platforms which fully support unknown function handling](#platforms-which-fully-support-unknown-function-handling)
-  - [Tests](#tests)
+- [Contributing to the Repository](#contributing-to-the-repository)
+- [Repository Content](#repository-content)
+  - [Installed Files](#installed-files)
+- [Build Requirements](#build-requirements)
+  - [Building with Code Generation Requirements](#building-with-code-generation-requirements)
+  - [Test Requirements](#test-requirements)
+- [Repository Set-Up](#repository-set-up)
+  - [Display Drivers](#display-drivers)
+  - [Repository Dependencies](#repository-dependencies)
+    - [Vulkan-Headers](#vulkan-headers)
+    - [Test Dependencies](#test-dependencies)
+  - [Warnings as errors off by default!](#warnings-as-errors-off-by-default)
+  - [Build and Install Directory Locations](#build-and-install-directory-locations)
+  - [Building Dependent Repositories with Known-Good Revisions](#building-dependent-repositories-with-known-good-revisions)
+    - [Automatically](#automatically)
+    - [Manually](#manually)
+      - [Notes About the Manual Option](#notes-about-the-manual-option)
+  - [Generated source code](#generated-source-code)
+  - [Build Options](#build-options)
+- [Building On Windows](#building-on-windows)
+  - [Windows Development Environment Requirements](#windows-development-environment-requirements)
+  - [Windows Build - Microsoft Visual Studio](#windows-build---microsoft-visual-studio)
+    - [Windows Quick Start](#windows-quick-start)
+    - [Use `CMake` to Create the Visual Studio Project Files](#use-cmake-to-create-the-visual-studio-project-files)
+    - [Build the Solution From the Command Line](#build-the-solution-from-the-command-line)
+    - [Build the Solution With Visual Studio](#build-the-solution-with-visual-studio)
+    - [Windows Install Target](#windows-install-target)
+- [Building On Linux](#building-on-linux)
+  - [Linux Development Environment Requirements](#linux-development-environment-requirements)
+    - [Required Package List](#required-package-list)
+  - [Linux Build](#linux-build)
+    - [Linux Quick Start](#linux-quick-start)
+    - [Use CMake to Create the Make Files](#use-cmake-to-create-the-make-files)
+    - [Build the Project](#build-the-project)
+  - [Linux Notes](#linux-notes)
+    - [WSI Support Build Options](#wsi-support-build-options)
+    - [Linux Install to System Directories](#linux-install-to-system-directories)
+    - [Linux 32-bit support](#linux-32-bit-support)
+- [Building on MacOS](#building-on-macos)
+  - [MacOS Development Environment Requirements](#macos-development-environment-requirements)
+  - [Clone the Repository](#clone-the-repository)
+  - [MacOS build](#macos-build)
+    - [Building with the Unix Makefiles Generator](#building-with-the-unix-makefiles-generator)
+    - [Building with the Xcode Generator](#building-with-the-xcode-generator)
+- [Building on Fuchsia](#building-on-fuchsia)
+  - [SDK Symbols](#sdk-symbols)
+- [Building on QNX](#building-on-qnx)
+- [Cross Compilation](#cross-compilation)
+  - [Unknown function handling which requires explicit assembly implementations](#unknown-function-handling-which-requires-explicit-assembly-implementations)
+    - [Platforms which fully support unknown function handling](#platforms-which-fully-support-unknown-function-handling)
+- [Tests](#tests)
 
 
 ## Contributing to the Repository
@@ -81,9 +80,15 @@
 ## Build Requirements
 
 1. `C99` capable compiler
-2. `CMake` version 3.17.2 or greater
+2. `CMake` version 3.22.1 or greater
 3. `Git`
 
+### Building with Code Generation Requirements
+
+1. `Python 3.11`
+2. `clang-format` version 14 or higher
+   * Only required when submitting changes
+
 ### Test Requirements
 
 1. `C++17` capable compiler
@@ -225,6 +230,11 @@
 cmake --build . --target loader_codegen
 ```
 
+`clang-format` is run on generated code files so that the generator scripts do
+not need format their output manually.
+If `clang-format` is not available when running code generation, a warning will
+be issued but does not stop code generation from occurring.
+
 ### Build Options
 
 When generating build files through CMake, several options can be specified to
@@ -271,7 +281,7 @@
     - [2019](https://www.visualstudio.com/vs/older-downloads/)
   - The Community Edition of each of the above versions is sufficient, as
     well as any more capable edition.
-- [CMake 3.17.2](https://cmake.org/files/v3.17/cmake-3.17.2-win64-x64.zip) is recommended.
+- [CMake 3.22.1](https://cmake.org/files/v3.22.1/cmake-3.22.1-win64-x64.zip) is recommended.
   - Use the installer option to add CMake to the system PATH
 - Git Client Support
   - [Git for Windows](http://git-scm.com/download/win) is a popular solution
@@ -382,7 +392,7 @@
 versions, although earlier versions may work.
 It is be straightforward to adapt this repository to other Linux distributions.
 
-[CMake 3.17.2](https://cmake.org/files/v3.17/cmake-3.17.2-Linux-x86_64.tar.gz) is recommended.
+[CMake 3.22.1](https://cmake.org/files/v3.22.1/cmake-3.22.1-Linux-x86_64.tar.gz) is recommended.
 
 #### Required Package List
 
@@ -522,22 +532,22 @@
 
 `gcc-multilib gcc-multilib g++-multilib libc6:i386 libc6-dev-i386 libgcc-s1:i386 libwayland-dev:i386 libxrandr-dev:i386`
 
-This list may vary depending on your distribution and which windowing systems
-you are building for.
+This list may vary depending on your distribution and which windowing systems you are building for.
 
-Set up your environment for building 32-bit targets:
+Set up your environment for building 32-bit targets when configuring your build:
 
-    export CFLAGS=-m32
-    export CXXFLAGS=-m32
-    export LDFLAGS=-m32
-    export ASFLAGS=--32
+      cmake ... -D CMAKE_CXX_FLAGS=-m32 -D CMAKE_C_FLAGS=-m32
+
+However, you may find that pkg-config picks incorrect libraries. This is due to a CMake implementation issue:
+https://gitlab.kitware.com/cmake/cmake/-/issues/25317
 
 Your PKG_CONFIG configuration may be different, depending on your distribution.
 
+You can the `PKG_CONFIG_PATH` environment variable to address this issue.
+
 Finally, build the repository normally as explained above.
 
-These notes are taken from the Github Actions workflow `linux-32` which is run
-regularly as a part of CI.
+These notes are taken from the Github Actions workflow `linux-32` which is run regularly as a part of CI.
 
 ## Building on MacOS
 
@@ -561,7 +571,7 @@
 
 ### MacOS build
 
-[CMake 3.17.2](https://cmake.org/files/v3.17/cmake-3.17.2-Darwin-x86_64.tar.gz) is recommended.
+[CMake 3.22.1](https://cmake.org/files/v3.22.1/cmake-3.22.1-Darwin-x86_64.tar.gz) is recommended.
 
 #### Building with the Unix Makefiles Generator
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6deec3a..4622e0a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,9 +16,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # ~~~
-cmake_minimum_required(VERSION 3.17.2)
+cmake_minimum_required(VERSION 3.22.1)
 
-project(VULKAN_LOADER VERSION 1.4.304 LANGUAGES C)
+project(VULKAN_LOADER VERSION 1.4.350 LANGUAGES C)
 
 option(CODE_COVERAGE "Enable Code Coverage" OFF)
 if (CODE_COVERAGE)
@@ -52,7 +52,10 @@
     set(BUILD_DLL_VERSIONINFO "" CACHE STRING "Set the version to be used in the loader.rc file. Default value is the currently generated header version")
 endif()
 
-find_package(VulkanHeaders CONFIG QUIET)
+find_package(VulkanHeaders ${PROJECT_VERSION} CONFIG QUIET)
+if (${VulkanHeaders_VERSION} VERSION_GREATER ${PROJECT_VERSION})
+    message(WARNING "The Vulkan Headers version ${VulkanHeaders_VERSION} is newer than the expected version ${PROJECT_VERSION} used by the Vulkan-Loader. May cause issues.")
+endif()
 
 include(GNUInstallDirs)
 
@@ -108,7 +111,7 @@
     if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
         target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_MACOS_MVK)
     endif()
-elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|DragonFly|GNU")
+elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|DragonFly|GNU|CYGWIN")
     option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON)
     option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON)
     option(BUILD_WSI_XLIB_XRANDR_SUPPORT "Build X11 Xrandr WSI support" ON)
@@ -125,14 +128,12 @@
     endif()
     if(BUILD_WSI_XLIB_SUPPORT)
         pkg_check_modules(X11 REQUIRED QUIET IMPORTED_TARGET x11)
-        pkg_get_variable(XLIB_INCLUDE_DIRS x11 includedir)
         target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_XLIB_KHR)
-        target_include_directories(platform_wsi INTERFACE ${XLIB_INCLUDE_DIRS})
+        target_include_directories(platform_wsi INTERFACE ${X11_INCLUDE_DIRS})
         if(BUILD_WSI_XLIB_XRANDR_SUPPORT)
             pkg_check_modules(XRANDR REQUIRED QUIET IMPORTED_TARGET xrandr)
-            pkg_get_variable(XLIB_XRANDR_INCLUDE_DIRS xrandr includedir)
             target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_XLIB_XRANDR_EXT)
-            target_include_directories(platform_wsi INTERFACE ${XLIB_XRANDR_INCLUDE_DIRS})
+            target_include_directories(platform_wsi INTERFACE ${XRANDR_INCLUDE_DIRS})
         endif()
     endif()
     if(BUILD_WSI_WAYLAND_SUPPORT)
@@ -227,10 +228,21 @@
     # Enable control flow guard
     target_link_options(loader_common_options INTERFACE "LINKER:/guard:cf")
 
+    # Enable CET for 32-bit and 64-bit x86 architectures
+    if (CMAKE_GENERATOR_PLATFORM MATCHES "Win32|x64")
+        target_link_options(loader_common_options INTERFACE "LINKER:/cetcompat")
+    endif()
+
+    # Enable EH Continuation Metadata for 64-bit architectures
+    if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+        target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:/guard:ehcont>)
+        target_link_options(loader_common_options INTERFACE "LINKER:/guard:ehcont")
+    endif()
+
     # Prevent <windows.h> from polluting the code. guards against things like MIN and MAX
     target_compile_definitions(loader_common_options INTERFACE WIN32_LEAN_AND_MEAN)
 
-    # For some reason Advapi32.lib needs to be explicitely linked to when building for Arm (32 bit) on Windows, but isn't required on any other architecture
+    # For some reason Advapi32.lib needs to be explicitly linked to when building for Arm (32 bit) on Windows, but isn't required on any other architecture
     if (SYSTEM_PROCESSOR MATCHES "arm" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
         target_link_libraries(loader_common_options INTERFACE Advapi32)
     endif()
@@ -241,7 +253,7 @@
 target_compile_definitions(loader_common_options INTERFACE $<$<CONFIG:DEBUG>:DEBUG;GIT_BRANCH_NAME="${GIT_BRANCH_NAME}";GIT_TAG_INFO="${GIT_TAG_INFO}">)
 
 if (NOT (WIN32 OR APPLE))
-    # Check for the existance of the secure_getenv or __secure_getenv commands
+    # Check for the existence of the secure_getenv or __secure_getenv commands
     include(CheckFunctionExists)
 
     check_function_exists(secure_getenv HAVE_SECURE_GETENV)
@@ -254,7 +266,20 @@
         target_compile_definitions(loader_common_options INTERFACE HAVE___SECURE_GETENV)
     endif()
     if (NOT (HAVE_SECURE_GETENV OR HAVE___SECURE_GETENV))
-        message(WARNING "Using non-secure environmental lookups. This loader will not properly disable environent variables when run with elevated permissions.")
+        message(WARNING "Using non-secure environmental lookups. This loader will not properly disable environment variables when run with elevated permissions.")
+    endif()
+endif()
+
+if (NOT (WIN32))
+    # Check for the existence of the realpath() command
+    include(CheckFunctionExists)
+
+    check_function_exists(realpath HAVE_REALPATH)
+
+    if (HAVE_REALPATH)
+        target_compile_definitions(loader_common_options INTERFACE HAVE_REALPATH)
+    else()
+        message(INFO "Platform support for realpath() is missing. Using fallback path normalization implementation.")
     endif()
 endif()
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8b826a0..e3c717b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -72,7 +72,7 @@
 * Run **clang-format** on your changes to maintain consistent formatting
   * There are `.clang-format` files present in the repository to define
     clang-format settings which are found and used automatically by clang-format.
-  * **clang-format** binaries are available from the LLVM orginization, here:
+  * **clang-format** binaries are available from the LLVM organization, here:
     [LLVM](https://clang.llvm.org/).
     Our CI system currently uses clang-format version 16 to
     check that the lines of code you have changed are formatted properly.
diff --git a/docs/LoaderDebugging.md b/docs/LoaderDebugging.md
index 47d5ae2..343e6f7 100644
--- a/docs/LoaderDebugging.md
+++ b/docs/LoaderDebugging.md
@@ -99,57 +99,59 @@
 the following:
 
 ```
-LAYER: Searching for layer manifest files
-LAYER:  In following locations:
-LAYER:   /home/${USER}/.config/vulkan/implicit_layer.d
-LAYER:   /etc/xdg/vulkan/implicit_layer.d
-LAYER:   /usr/local/etc/vulkan/implicit_layer.d
-LAYER:   /etc/vulkan/implicit_layer.d
-LAYER:   /home/${USER}/.local/share/vulkan/implicit_layer.d
-LAYER:   /home/${USER}/.local/share/flatpak/exports/share/vulkan/implicit_layer.d
-LAYER:   /var/lib/flatpak/exports/share/vulkan/implicit_layer.d
-LAYER:   /usr/local/share/vulkan/implicit_layer.d
-LAYER:   /usr/share/vulkan/implicit_layer.d
-LAYER:  Found the following files:
-LAYER:   /home/${USER}/.local/share/vulkan/implicit_layer.d/renderdoc_capture.json
-LAYER:   /home/${USER}/.local/share/vulkan/implicit_layer.d/steamfossilize_i386.json
-LAYER:   /home/${USER}/.local/share/vulkan/implicit_layer.d/steamfossilize_x86_64.json
-LAYER:   /home/${USER}/.local/share/vulkan/implicit_layer.d/steamoverlay_i386.json
-LAYER:   /home/${USER}/.local/share/vulkan/implicit_layer.d/steamoverlay_x86_64.json
-LAYER:   /usr/share/vulkan/implicit_layer.d/nvidia_layers.json
-LAYER:   /usr/share/vulkan/implicit_layer.d/VkLayer_MESA_device_select.json
+[Vulkan Loader] LAYER: Searching for implicit layer manifest files
+[Vulkan Loader] LAYER:  In following locations:
+[Vulkan Loader] LAYER:   /home/${USER}/.config/vulkan/implicit_layer.d
+[Vulkan Loader] LAYER:   /etc/xdg/vulkan/implicit_layer.d
+[Vulkan Loader] LAYER:   /usr/local/etc/vulkan/implicit_layer.d
+[Vulkan Loader] LAYER:   /etc/vulkan/implicit_layer.d
+[Vulkan Loader] LAYER:   /home/${USER}/.local/share/vulkan/implicit_layer.d
+[Vulkan Loader] LAYER:   /home/${USER}/.local/share/flatpak/exports/share/vulkan/implicit_layer.d
+[Vulkan Loader] LAYER:   /var/lib/flatpak/exports/share/vulkan/implicit_layer.d
+[Vulkan Loader] LAYER:   /usr/local/share/vulkan/implicit_layer.d
+[Vulkan Loader] LAYER:   /usr/share/vulkan/implicit_layer.d
+[Vulkan Loader] LAYER:  Found the following files:
+[Vulkan Loader] LAYER:   /home/${USER}/.local/share/vulkan/implicit_layer.d/renderdoc_capture.json
+[Vulkan Loader] LAYER:   /home/${USER}/.local/share/vulkan/implicit_layer.d/steamfossilize_i386.json
+[Vulkan Loader] LAYER:   /home/${USER}/.local/share/vulkan/implicit_layer.d/steamfossilize_x86_64.json
+[Vulkan Loader] LAYER:   /home/${USER}/.local/share/vulkan/implicit_layer.d/steamoverlay_i386.json
+[Vulkan Loader] LAYER:   /home/${USER}/.local/share/vulkan/implicit_layer.d/steamoverlay_x86_64.json
+[Vulkan Loader] LAYER:   /usr/share/vulkan/implicit_layer.d/nvidia_layers.json
+[Vulkan Loader] LAYER:   /usr/share/vulkan/implicit_layer.d/VkLayer_MESA_device_select.json
 ```
 
 Then, the loading of layer libraries is reported similar to this:
 
 ```
-LAYER | DEBUG: Loading layer library libVkLayer_khronos_validation.so
-LAYER | INFO: Insert instance layer VK_LAYER_KHRONOS_validation (libVkLayer_khronos_validation.so)
-LAYER | DEBUG: Loading layer library libVkLayer_MESA_device_select.so
-LAYER | INFO: Insert instance layer VK_LAYER_MESA_device_select (libVkLayer_MESA_device_select.so)
+[Vulkan Loader] DEBUG | LAYER : Loading layer library libVkLayer_khronos_validation.so
+[Vulkan Loader] INFO | LAYER : Insert instance layer VK_LAYER_KHRONOS_validation (libVkLayer_khronos_validation.so)
+[Vulkan Loader] DEBUG | LAYER : Loading layer library libVkLayer_MESA_device_select.so
+[Vulkan Loader] INFO | LAYER : Insert instance layer VK_LAYER_MESA_device_select (libVkLayer_MESA_device_select.so)
 ```
 
 Finally, when the Vulkan instance is created, you can see the full instance
 call-chain from a functional standpoint with output like this:
 
 ```
-LAYER: vkCreateInstance layer callstack setup to:
-LAYER:  <Application>
-LAYER:    ||
-LAYER:  <Loader>
-LAYER:    ||
-LAYER:  VK_LAYER_MESA_device_select
-LAYER:      Type: Implicit
-LAYER:         Disable Env Var:  NODEVICE_SELECT
-LAYER:      Manifest: /usr/share/vulkan/implicit_layer.d/VkLayer_MESA_device_select.json
-LAYER:      Library:  libVkLayer_MESA_device_select.so
-LAYER:    ||
-LAYER:  VK_LAYER_KHRONOS_validation
-LAYER:      Type: Explicit
-LAYER:      Manifest: /usr/share/vulkan/explicit_layer.d/VkLayer_khronos_validation.json
-LAYER:      Library:  libVkLayer_khronos_validation.so
-LAYER:    ||
-LAYER:  <Drivers>
+[Vulkan Loader] LAYER: vkCreateInstance layer callstack setup to:
+[Vulkan Loader] LAYER:  <Application>
+[Vulkan Loader] LAYER:    ||
+[Vulkan Loader] LAYER:  <Loader>
+[Vulkan Loader] LAYER:    ||
+[Vulkan Loader] LAYER:  VK_LAYER_MESA_device_select
+[Vulkan Loader] LAYER:      Type: Implicit
+[Vulkan Loader] LAYER:      Enabled By: Implicit Layer
+[Vulkan Loader] LAYER:         Disable Env Var:  NODEVICE_SELECT
+[Vulkan Loader] LAYER:      Manifest: /usr/share/vulkan/implicit_layer.d/VkLayer_MESA_device_select.json
+[Vulkan Loader] LAYER:      Library:  libVkLayer_MESA_device_select.so
+[Vulkan Loader] LAYER:    ||
+[Vulkan Loader] LAYER:  VK_LAYER_KHRONOS_validation
+[Vulkan Loader] LAYER:      Type: Explicit
+[Vulkan Loader] LAYER:      Enabled By: By the Application
+[Vulkan Loader] LAYER:      Manifest: /usr/share/vulkan/explicit_layer.d/VkLayer_khronos_validation.json
+[Vulkan Loader] LAYER:      Library:  libVkLayer_khronos_validation.so
+[Vulkan Loader] LAYER:    ||
+[Vulkan Loader] LAYER:  <Drivers>
 ```
 
 In this scenario, two layers were used (the same two that were loaded earlier):
@@ -186,9 +188,9 @@
 layers to the logging output when layer logging is enabled in the following way:
 
 ```
-WARNING | LAYER:  Implicit layer "VK_LAYER_MESA_device_select" forced disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'.
-WARNING | LAYER:  Implicit layer "VK_LAYER_AMD_switchable_graphics_64" forced disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'.
-WARNING | LAYER:  Implicit layer "VK_LAYER_Twitch_Overlay" forced disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'.
+[Vulkan Loader] WARNING | LAYER:  Implicit layer "VK_LAYER_MESA_device_select" forced disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'.
+[Vulkan Loader] WARNING | LAYER:  Implicit layer "VK_LAYER_AMD_switchable_graphics_64" forced disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'.
+[Vulkan Loader] WARNING | LAYER:  Implicit layer "VK_LAYER_Twitch_Overlay" forced disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'.
 ```
 
 ### Selectively Re-enable Layers
@@ -283,34 +285,34 @@
 output for easier reading):
 
 ```
-DRIVER: Searching for driver manifest files
-DRIVER:    In following folders:
-DRIVER:       /home/$(USER)/.config/vulkan/icd.d
-DRIVER:       /etc/xdg/vulkan/icd.d
-DRIVER:       /etc/vulkan/icd.d
-DRIVER:       /home/$(USER)/.local/share/vulkan/icd.d
-DRIVER:       /home/$(USER)/.local/share/flatpak/exports/share/vulkan/icd.d
-DRIVER:       /var/lib/flatpak/exports/share/vulkan/icd.d
-DRIVER:       /usr/local/share/vulkan/icd.d
-DRIVER:       /usr/share/vulkan/icd.d
-DRIVER:    Found the following files:
-DRIVER:       /usr/share/vulkan/icd.d/intel_icd.x86_64.json
-DRIVER:       /usr/share/vulkan/icd.d/lvp_icd.x86_64.json
-DRIVER:       /usr/share/vulkan/icd.d/radeon_icd.x86_64.json
-DRIVER:       /usr/share/vulkan/icd.d/lvp_icd.i686.json
-DRIVER:       /usr/share/vulkan/icd.d/radeon_icd.i686.json
-DRIVER:       /usr/share/vulkan/icd.d/intel_icd.i686.json
-DRIVER:       /usr/share/vulkan/icd.d/nvidia_icd.json
-DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/intel_icd.x86_64.json, version "1.0.0"
-DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/lvp_icd.x86_64.json, version "1.0.0"
-DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/radeon_icd.x86_64.json, version "1.0.0"
-DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/lvp_icd.i686.json, version "1.0.0"
-DRIVER: Requested driver /usr/lib/libvulkan_lvp.so was wrong bit-type. Ignoring this JSON
-DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/radeon_icd.i686.json, version "1.0.0"
-DRIVER: Requested driver /usr/lib/libvulkan_radeon.so was wrong bit-type. Ignoring this JSON
-DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/intel_icd.i686.json, version "1.0.0"
-DRIVER: Requested driver /usr/lib/libvulkan_intel.so was wrong bit-type. Ignoring this JSON
-DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/nvidia_icd.json, version "1.0.0"
+[Vulkan Loader] DRIVER: Searching for driver manifest files
+[Vulkan Loader] DRIVER:    In following folders:
+[Vulkan Loader] DRIVER:       /home/$(USER)/.config/vulkan/icd.d
+[Vulkan Loader] DRIVER:       /etc/xdg/vulkan/icd.d
+[Vulkan Loader] DRIVER:       /etc/vulkan/icd.d
+[Vulkan Loader] DRIVER:       /home/$(USER)/.local/share/vulkan/icd.d
+[Vulkan Loader] DRIVER:       /home/$(USER)/.local/share/flatpak/exports/share/vulkan/icd.d
+[Vulkan Loader] DRIVER:       /var/lib/flatpak/exports/share/vulkan/icd.d
+[Vulkan Loader] DRIVER:       /usr/local/share/vulkan/icd.d
+[Vulkan Loader] DRIVER:       /usr/share/vulkan/icd.d
+[Vulkan Loader] DRIVER:    Found the following files:
+[Vulkan Loader] DRIVER:       /usr/share/vulkan/icd.d/intel_icd.x86_64.json
+[Vulkan Loader] DRIVER:       /usr/share/vulkan/icd.d/lvp_icd.x86_64.json
+[Vulkan Loader] DRIVER:       /usr/share/vulkan/icd.d/radeon_icd.x86_64.json
+[Vulkan Loader] DRIVER:       /usr/share/vulkan/icd.d/lvp_icd.i686.json
+[Vulkan Loader] DRIVER:       /usr/share/vulkan/icd.d/radeon_icd.i686.json
+[Vulkan Loader] DRIVER:       /usr/share/vulkan/icd.d/intel_icd.i686.json
+[Vulkan Loader] DRIVER:       /usr/share/vulkan/icd.d/nvidia_icd.json
+[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/intel_icd.x86_64.json, version "1.0.0"
+[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/lvp_icd.x86_64.json, version "1.0.0"
+[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/radeon_icd.x86_64.json, version "1.0.0"
+[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/lvp_icd.i686.json, version "1.0.0"
+[Vulkan Loader] DRIVER: Requested driver /usr/lib/libvulkan_lvp.so was wrong bit-type. Ignoring this JSON
+[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/radeon_icd.i686.json, version "1.0.0"
+[Vulkan Loader] DRIVER: Requested driver /usr/lib/libvulkan_radeon.so was wrong bit-type. Ignoring this JSON
+[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/intel_icd.i686.json, version "1.0.0"
+[Vulkan Loader] DRIVER: Requested driver /usr/lib/libvulkan_intel.so was wrong bit-type. Ignoring this JSON
+[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/nvidia_icd.json, version "1.0.0"
 ```
 
 Then when the application selects the device to use, you will see the Vulkan
@@ -318,13 +320,13 @@
 been removed from the output for easier reading):
 
 ```
-DRIVER: vkCreateDevice layer callstack setup to:
-DRIVER:    <Application>
-DRIVER:      ||
-DRIVER:    <Loader>
-DRIVER:      ||
-DRIVER:    <Device>
-DRIVER:        Using "Intel(R) UHD Graphics 630 (CFL GT2)" with driver: "/usr/lib64/libvulkan_intel.so"
+[Vulkan Loader] DRIVER: vkCreateDevice layer callstack setup to:
+[Vulkan Loader] DRIVER:    <Application>
+[Vulkan Loader] DRIVER:      ||
+[Vulkan Loader] DRIVER:    <Loader>
+[Vulkan Loader] DRIVER:      ||
+[Vulkan Loader] DRIVER:    <Device>
+[Vulkan Loader] DRIVER:        Using "Intel(R) UHD Graphics 630 (CFL GT2)" with driver: "/usr/lib64/libvulkan_intel.so"
 ```
 
 
@@ -351,8 +353,8 @@
 are used:
 
 ```
-WARNING | DRIVER: Driver "intel_icd.x86_64.json" ignored because not selected by env var 'VK_LOADER_DRIVERS_SELECT'
-WARNING | DRIVER: Driver "radeon_icd.x86_64.json" ignored because it was disabled by env var 'VK_LOADER_DRIVERS_DISABLE'
+[Vulkan Loader] WARNING | DRIVER: Driver "intel_icd.x86_64.json" ignored because not selected by env var 'VK_LOADER_DRIVERS_SELECT'
+[Vulkan Loader] WARNING | DRIVER: Driver "radeon_icd.x86_64.json" ignored because it was disabled by env var 'VK_LOADER_DRIVERS_DISABLE'
 ```
 
 For more info on how to use the filtering environment variables, refer to the
diff --git a/docs/LoaderDriverInterface.md b/docs/LoaderDriverInterface.md
index e86c83e..791c64c 100644
--- a/docs/LoaderDriverInterface.md
+++ b/docs/LoaderDriverInterface.md
@@ -172,7 +172,7 @@
 This message will look like the following:
 
 ```
-WARNING | DRIVER: Driver "intel_icd.x86_64.json" ignored because not selected by env var 'VK_LOADER_DRIVERS_SELECT'
+[Vulkan Loader] WARNING | DRIVER: Driver "intel_icd.x86_64.json" ignored because not selected by env var 'VK_LOADER_DRIVERS_SELECT'
 ```
 
 If no drivers are found with a manifest filename that matches any of the
@@ -190,7 +190,7 @@
 This message will look like the following:
 
 ```
-WARNING | DRIVER: Driver "radeon_icd.x86_64.json" ignored because it was disabled by env var 'VK_LOADER_DRIVERS_DISABLE'
+[Vulkan Loader] WARNING | DRIVER: Driver "radeon_icd.x86_64.json" ignored because it was disabled by env var 'VK_LOADER_DRIVERS_DISABLE'
 ```
 
 If no drivers are found with a manifest filename that matches any of the
diff --git a/docs/LoaderInterfaceArchitecture.md b/docs/LoaderInterfaceArchitecture.md
index 35734fd..b0b52c9 100644
--- a/docs/LoaderInterfaceArchitecture.md
+++ b/docs/LoaderInterfaceArchitecture.md
@@ -557,6 +557,12 @@
 This is useful if you disable all layers/drivers with the intent of only
 enabling a smaller subset of specific layers/drivers for issue triaging.
 
+### Multiple Filtering
+
+When multiple `VK_LOADER_<DEVICE|VENDOR|DRIVER>_ID_FILTER`s are provided, they
+apply cummulatively. Only devices matching all of the filters will be presented
+to the application.
+
 ## Table of Debug Environment Variables
 
 The following are all the Debug Environment Variables available for use with the
@@ -667,6 +673,8 @@
         continue to work.
     </small></td>
     <td><small>
+        This functionality is only available with Loaders built with version
+        1.3.207 of the Vulkan headers and later.<br/>
         It is recommended to use absolute paths to JSON files.
         Relative paths may have issues due to how the loader transforms relative library
         paths into absolute ones.
@@ -765,7 +773,7 @@
         other devices in the return order of <i>vkGetPhysicalDevices<i> and
         <i>vkGetPhysicalDeviceGroups<i> functions.<br/>
         The value should be "<hex vendor id>:<hex device id>".<br/>
-        <b>NOTE:</b> This DOES NOT REMOVE devices from the list on reorders them.
+        <b>NOTE:</b> This DOES NOT REMOVE devices from the list, only reorders them.
     </small></td>
     <td><small>
         <b>Linux Only</b>
@@ -886,9 +894,7 @@
         Known layers are those which are found by the loader taking into account
         default search paths and other environment variables
         (like <i>VK_LAYER_PATH</i>).
-        <br/>
-        This has replaced the older deprecated environment variable
-        <i>VK_INSTANCE_LAYERS</i>
+        </i>
     </small></td>
     <td><small>
         This functionality is only available with Loaders built with version
@@ -986,6 +992,75 @@
         &nbsp;&nbsp;VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING=1<br/><br/>
     </small></td>
   </tr>
+  <tr>
+    <td><small>
+        <i>VK_LOADER_DEVICE_ID_FILTER</i>
+    </small></td>
+    <td><small>
+        If set, causes the loader to only enumerate physical devices matching the
+        filter. The filter is a comma-delimited list of device ids or device id
+        ranges, where ids may be provided as decimal or hexadecimal values and ranges
+        are colon-delimited. A device passes if any one of the filters match its
+        device id as provided by <i>VkPhysicalDeviceProperties::deviceID<i>.
+    </small></td>
+    <td><small>
+        This functionality is only available with Loaders built with version
+        1.4.326 of the Vulkan headers and later.
+    </small></td>
+    <td><small>
+        export<br/>
+        &nbsp;&nbsp;VK_LOADER_DEVICE_ID_FILTER=0x7460:0x747e,29827<br/>
+        <br/>
+        set<br/>
+        &nbsp;&nbsp;VK_LOADER_DEVICE_ID_FILTER=0x7460:0x747e,29827<br/><br/>
+    </small></td>
+  </tr>
+  <tr>
+    <td><small>
+        <i>VK_LOADER_VENDOR_ID_FILTER</i>
+    </small></td>
+    <td><small>
+        If set, causes the loader to only enumerate physical devices matching the
+        filter. The filter is a comma-delimited list of vendor ids or vendor id
+        ranges, where ids may be provided as decimal or hexadecimal values and ranges
+        are colon-delimited. A device passes if any one of the filters match its
+        vendor id as provided by <i>VkPhysicalDeviceProperties::vendorID<i>.
+    </small></td>
+    <td><small>
+        This functionality is only available with Loaders built with version
+        1.4.326 of the Vulkan headers and later.
+    </small></td>
+    <td><small>
+        export<br/>
+        &nbsp;&nbsp;VK_LOADER_VENDOR_ID_FILTER=65541<br/>
+        <br/>
+        set<br/>
+        &nbsp;&nbsp;VK_LOADER_VENDOR_ID_FILTER=65541<br/><br/>
+    </small></td>
+  </tr>
+  <tr>
+    <td><small>
+        <i>VK_LOADER_DRIVER_ID_FILTER</i>
+    </small></td>
+    <td><small>
+        If set, causes the loader to only enumerate physical devices matching the
+        filter. The filter is a comma-delimited list of driver ids or driver id
+        ranges, where ids may be provided as decimal or hexadecimal values and ranges
+        are colon-delimited. A device passes if any one of the filters match its
+        driver id as provided by <i>VkPhysicalDeviceDriverProperties::driverID<i>.
+    </small></td>
+    <td><small>
+        This functionality is only available with Loaders built with version
+        1.4.326 of the Vulkan headers and later.
+    </small></td>
+    <td><small>
+        export<br/>
+        &nbsp;&nbsp;VK_LOADER_DRIVER_ID_FILTER=1-3:13<br/>
+        <br/>
+        set<br/>
+        &nbsp;&nbsp;VK_LOADER_DRIVER_ID_FILTER=1-3:13<br/><br/>
+    </small></td>
+  </tr>
 </table>
 
 <br/>
@@ -1043,8 +1118,7 @@
         <i>ppEnabledLayerNames</i>.
     </small></td>
     <td><small>
-        This has been deprecated by <i>VK_LOADER_LAYERS_ENABLE</i>.
-        It also overrides any layers disabled with
+        It overrides any layers disabled with
         <i>VK_LOADER_LAYERS_DISABLE</i>.
     </small></td>
     <td><small>
diff --git a/docs/LoaderLayerInterface.md b/docs/LoaderLayerInterface.md
index 68d00d8..ea175e1 100644
--- a/docs/LoaderLayerInterface.md
+++ b/docs/LoaderLayerInterface.md
@@ -486,7 +486,7 @@
 This message will look like the following:
 
 ```
-WARNING | LAYER:  Layer "VK_LAYER_LUNARG_wrap_objects" force enabled due to env var 'VK_LOADER_LAYERS_ENABLE'
+[Vulkan Loader] WARNING | LAYER:  Layer "VK_LAYER_LUNARG_wrap_objects" force enabled due to env var 'VK_LOADER_LAYERS_ENABLE'
 ```
 
 #### Layer Disable Filtering
@@ -508,7 +508,7 @@
 This message will look like the following:
 
 ```
-WARNING | LAYER:  Layer "VK_LAYER_LUNARG_wrap_objects" disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'
+[Vulkan Loader] WARNING | LAYER:  Layer "VK_LAYER_LUNARG_wrap_objects" disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'
 ```
 
 #### Layer Special Case Disable
@@ -563,7 +563,7 @@
 
 ##### `VK_INSTANCE_LAYERS`
 
-The original `VK_INSTANCE_LAYERS` can be viewed as a special case of the new
+The original `VK_INSTANCE_LAYERS` can be viewed as a special case of
 `VK_LOADER_LAYERS_ENABLE`.
 Because of this, any layers enabled via `VK_INSTANCE_LAYERS` will be treated the
 same as layers enabled with `VK_LOADER_LAYERS_ENABLE` and will therefore
diff --git a/docs/LoaderSettingsFile.md b/docs/LoaderSettingsFile.md
new file mode 100644
index 0000000..d73f410
--- /dev/null
+++ b/docs/LoaderSettingsFile.md
@@ -0,0 +1,114 @@
+<!-- markdownlint-disable MD041 -->
+[![Khronos Vulkan][1]][2]
+
+[1]: https://vulkan.lunarg.com/img/Vulkan_100px_Dec16.png "https://www.khronos.org/vulkan/"
+[2]: https://www.khronos.org/vulkan/
+
+# Loader Settings File <!-- omit from toc -->
+
+[![Creative Commons][3]][4]
+
+<!-- Copyright &copy; 2025 LunarG, Inc. -->
+
+[3]: https://i.creativecommons.org/l/by-nd/4.0/88x31.png "Creative Commons License"
+[4]: https://creativecommons.org/licenses/by-nd/4.0/
+
+
+## Table of Contents <!-- omit from toc -->
+
+- [Purpose of the Settings File](#purpose-of-the-settings-file)
+- [Settings File Discovery](#settings-file-discovery)
+  - [Windows](#windows)
+  - [Linux/MacOS/BSD/QNX/Fuchsia/GNU](#linuxmacosbsdqnxfuchsiagnu)
+  - [Other Platforms](#other-platforms)
+  - [Exception for Elevated Privileges](#exception-for-elevated-privileges)
+- [Per-Application Settings File](#per-application-settings-file)
+- [File Format](#file-format)
+- [Example Settings File](#example-settings-file)
+  - [Fields](#fields)
+- [Behavior](#behavior)
+
+
+## Purpose of the Settings File
+
+The purpose of the Loader Settings File is to give developers superb control over the
+behavior of the Vulkan-Loader.
+It enables enhanced controls over which layers to load, the order layers in the call chain,
+logging, and which drivers are available.
+
+The Loader Settings File is intended to be used by "Developer Control Panels" for the Vulkan API, such as the Vulkan Configurator, as a replacement for setting debug envrionment variables.
+
+## Settings File Discovery
+
+The Loader Settings File is located by searching in specific file system paths or through
+platform specific mechanisms such as the Windows Registry.
+
+### Windows
+
+The Vulkan Loader first searches the Registry Key  HKEY_CURRENT_USER\SOFTWARE\Khronos\Vulkan\LoaderSettings for a DWORD value whose name is
+a valid path to a file named 'vk_loader_settings.json'.
+If there are no matching values or the file doesn't exist, the Vulkan Loader performs the
+same behavior as described above for the Registry Key  HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\LoaderSettings.
+
+### Linux/MacOS/BSD/QNX/Fuchsia/GNU
+
+The Loader Settings File is located by searching for a file named vk_loader_settings.json in the following locations:
+
+`$HOME/.local/share/vulkan/loader_settings.d/`
+`$XDG_DATA_HOME/vulkan/loader_settings.d/`
+`/etc/vulkan/loader_settings.d/`
+
+Where $HOME and %XDG_DATA_HOME refer to the values contained in the environment variables of the same name.
+If a given environment variables is not present, that path is ignored.
+
+### Other Platforms
+
+Platforms not listed above currently do not support the Loader Settings File due to not having an appropriate search mechanism.
+
+### Exception for Elevated Privileges
+
+Because the Loader Settings File contains paths to Layer and ICD manifests, which contain
+the paths to various executable binaries, it is necessary to restrict the use of the Loader
+Settings File when the application is running with elevated privileges.
+
+This is accomplished by not using any Loader Settings Files that are found in non-privileged locations.
+
+On Windows, running with Elevated Privileges will ignore HKEY_CURRENT_USER\SOFTWARE\Khronos\Vulkan\LoaderSettings.
+
+On Linux/MacOS/BSD/QNX/Fuchsia/GNU, running with Elevated Privileges will use a secure method of querying $HOME and $XDG_DATA_HOME to prevent
+malicious injection of unsecure search directories.
+
+## Per-Application Settings File
+
+## File Format
+
+The Loader Settings File is a JSON file with a
+
+
+## Example Settings File
+
+
+```json
+{
+   "file_format_version" : "1.0.1",
+   "settings": {
+
+   }
+}
+```
+
+### Fields
+
+<table style="width:100%">
+  <tr>
+    <th>JSON Node</th>
+    <th>Description and Notes</th>
+    <th>Restrictions</th>
+    <th>Parent</th>
+    <th>Introspection Query</th>
+  </tr>
+
+
+
+
+## Behavior
diff --git a/docs/images/loader_layer_order.png b/docs/images/loader_layer_order.png
index 46cdbd1..4f4efe8 100644
--- a/docs/images/loader_layer_order.png
+++ b/docs/images/loader_layer_order.png
Binary files differ
diff --git a/docs/images/loader_layer_order_calls.png b/docs/images/loader_layer_order_calls.png
index 01dc08c..18ca25c 100644
--- a/docs/images/loader_layer_order_calls.png
+++ b/docs/images/loader_layer_order_calls.png
Binary files differ
diff --git a/docs/images/svgs/loader_layer_order.svg b/docs/images/svgs/loader_layer_order.svg
index e6cafac..dd4eca2 100755
--- a/docs/images/svgs/loader_layer_order.svg
+++ b/docs/images/svgs/loader_layer_order.svg
@@ -5,9 +5,9 @@
    viewBox="0 0 1121.6842 464.72108"
    id="svg11653"
    version="1.1"
-   inkscape:version="1.1 (c68e22c387, 2021-05-23)"
+   inkscape:version="1.4.2 (ebf0e940, 2025-05-08)"
    sodipodi:docname="loader_layer_order.svg"
-   inkscape:export-filename="/home/marky/dev/khronos/hub/loader/docs/images/loader_layer_order.png"
+   inkscape:export-filename="../loader_layer_order.png"
    inkscape:export-xdpi="96"
    inkscape:export-ydpi="96"
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
@@ -503,7 +503,7 @@
        x2="55.75"
        y2="1014.3622" />
     <linearGradient
-       gradientTransform="matrix(0.42278504,0,0,0.84489936,242.9873,360.48785)"
+       gradientTransform="matrix(0.42278504,0,0,0.67890197,242.9873,478.73812)"
        inkscape:collect="always"
        xlink:href="#Brown-4"
        id="linearGradient4620-0-16-5-1-9"
@@ -517,7 +517,7 @@
        xlink:href="#Shine-2"
        id="linearGradient12776-3"
        gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.4214325,0,0,2.8666228,335.27106,-1883.8742)"
+       gradientTransform="matrix(1.4214325,0,0,2.3034174,335.27106,-1324.6741)"
        x1="55.75"
        y1="994.11218"
        x2="55.75"
@@ -527,7 +527,7 @@
        xlink:href="#Brown-4"
        id="linearGradient1713"
        gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.4,0,0,0.52738304,175.56564,509.86797)"
+       gradientTransform="matrix(0.4,0,0,0.52738304,182.905,523.52732)"
        x1="402"
        y1="711.36218"
        x2="401"
@@ -537,7 +537,7 @@
        xlink:href="#Shine-2"
        id="linearGradient1715"
        gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.3448276,0,0,1.7893346,262.87598,-891.05379)"
+       gradientTransform="matrix(1.3448276,0,0,1.7893346,270.21534,-877.39444)"
        x1="55.75"
        y1="994.11218"
        x2="55.75"
@@ -726,16 +726,16 @@
      borderopacity="1.0"
      inkscape:pageopacity="0.0"
      inkscape:pageshadow="2"
-     inkscape:zoom="0.7071068"
-     inkscape:cx="605.9905"
-     inkscape:cy="48.08326"
+     inkscape:zoom="0.98876832"
+     inkscape:cx="500.62284"
+     inkscape:cy="220.982"
      inkscape:document-units="px"
-     inkscape:current-layer="layer2"
+     inkscape:current-layer="layer3"
      showgrid="false"
-     inkscape:window-width="2086"
-     inkscape:window-height="1137"
-     inkscape:window-x="750"
-     inkscape:window-y="54"
+     inkscape:window-width="1440"
+     inkscape:window-height="770"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
      inkscape:window-maximized="0"
      showguides="false"
      units="px"
@@ -744,7 +744,9 @@
      fit-margin-left="0"
      fit-margin-right="0"
      fit-margin-bottom="0"
-     inkscape:pagecheckerboard="0" />
+     inkscape:pagecheckerboard="0"
+     inkscape:showpageshadow="2"
+     inkscape:deskcolor="#d1d1d1" />
   <metadata
      id="metadata11658">
     <rdf:RDF>
@@ -760,7 +762,8 @@
      inkscape:groupmode="layer"
      id="layer2"
      inkscape:label="Background"
-     transform="translate(11.848806,7.6125679)">
+     transform="translate(11.848806,7.6125679)"
+     style="display:inline">
     <rect
        style="opacity:1;fill:#e2dbe3;fill-opacity:1;stroke:none;stroke-width:2.38071;stroke-miterlimit:4;stroke-dasharray:7.1421, 7.1421;stroke-dashoffset:0;stroke-opacity:1"
        id="rect3742"
@@ -774,6 +777,56 @@
        inkscape:export-filename="/home/marky/dev/khronos/hub/loader/docs/images/loader_layer_order.png" />
   </g>
   <g
+     inkscape:groupmode="layer"
+     id="layer3"
+     inkscape:label="Arrows">
+    <path
+       style="opacity:0.995;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker4972)"
+       d="M 901.84772,693.48473 H 941.0171"
+       id="path4968"
+       transform="translate(11.848806,-624.74961)" />
+    <path
+       style="opacity:0.995;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker5116)"
+       d="m 901.04291,774.37003 37.97113,52.38031"
+       id="path5112"
+       transform="translate(11.848806,-624.74961)" />
+    <path
+       style="opacity:0.995;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker5266)"
+       d="m 899.92176,821.44965 40.56793,110.20673"
+       id="path5262"
+       transform="translate(11.848806,-624.74961)" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker7572)"
+       d="m 169.4233,708.78045 h 54.92836"
+       id="path8841"
+       transform="translate(11.848806,-624.74961)" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker7572-9)"
+       d="m 166.68169,810.66057 h 54.92836"
+       id="path8841-3"
+       transform="translate(11.848806,-624.74961)" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker4554-3);marker-end:url(#marker4436-7)"
+       d="m 573.65806,227.74688 0.24384,46.78299"
+       id="path4432-3" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker4554-5);marker-end:url(#marker4436-9)"
+       d="m 359.65806,227.74688 0.24384,46.78299"
+       id="path4432-2" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker4554-5-7);marker-end:url(#marker4436-9-9)"
+       d="m 790.67609,226.01411 0.24384,46.78299"
+       id="path4432-2-6" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6.4, 6.4;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker2880)"
+       d="m 435.6676,327.24592 h 54.96685"
+       id="path3863" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1.62235;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6.48941, 6.48941;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker2880-0)"
+       d="m 651.91326,327.75457 h 56.51326"
+       id="path3863-2" />
+  </g>
+  <g
      inkscape:label="Layer 1"
      inkscape:groupmode="layer"
      id="layer1"
@@ -1180,23 +1233,23 @@
     </g>
     <g
        id="g1241"
-       transform="translate(134.15673,-76.742015)">
+       transform="translate(141.49609,-63.082703)">
       <rect
-         ry="27.459229"
+         ry="22.064314"
          y="962.36218"
          x="336"
-         height="168.97987"
+         height="135.7804"
          width="169.11401"
          id="rect3336-9-5-9-0-5-8"
-         style="fill:url(#linearGradient4620-0-16-5-1-9);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.49419;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+         style="fill:url(#linearGradient4620-0-16-5-1-9);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.33939;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
       <rect
-         style="fill:url(#linearGradient12776-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.49418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         style="fill:url(#linearGradient12776-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.33938;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
          id="rect4476-4-7-3-9"
          width="169.11401"
-         height="168.97986"
+         height="135.7804"
          x="336"
          y="962.36218"
-         ry="26.086267" />
+         ry="20.9611" />
       <text
          id="text4545-3-5-7-2"
          y="1025.8623"
@@ -1212,16 +1265,11 @@
            y="1057.1123"
            x="419.28979"
            sodipodi:role="line"
-           id="tspan1486">Enabled</tspan><tspan
+           id="tspan1488">Enabled</tspan><tspan
            style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
            y="1088.3623"
            x="419.28979"
            sodipodi:role="line"
-           id="tspan1488">Explicit</tspan><tspan
-           style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-           y="1119.6123"
-           x="419.28979"
-           sodipodi:role="line"
            id="tspan1490">Layers</tspan></text>
       <g
          transform="matrix(0.08921554,0,0,0.08921554,373.7707,910.64134)"
@@ -1249,7 +1297,7 @@
           </g>
           <polygon
              style="fill:#ffffff"
-             points="829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 "
+             points="787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 829.91,237.33 774.18,291.62 836.19,385.06 "
              id="polygon13-6-7-1-6-4-7" />
           <path
              style="fill:#ffffff"
@@ -1293,10 +1341,24 @@
              id="path31-6-2-4-7-0-5" />
         </g>
       </g>
+      <text
+         xml:space="preserve"
+         style="text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000"
+         x="425.56219"
+         y="1111.0922"
+         id="text1"><tspan
+           sodipodi:role="line"
+           id="tspan1"
+           x="425.56219"
+           y="1111.0922" /><tspan
+           sodipodi:role="line"
+           id="tspan2"
+           x="425.56219"
+           y="1126.0922" /></text>
     </g>
     <g
        id="g1266"
-       transform="translate(146.15673,-76.742015)">
+       transform="translate(153.49609,-63.082664)">
       <rect
          ry="27.428976"
          y="962.36218"
@@ -1365,7 +1427,7 @@
           </g>
           <polygon
              style="fill:#ffffff"
-             points="829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 "
+             points="836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 829.91,237.33 774.18,291.62 "
              id="polygon13-6-7-1-6-6-7" />
           <path
              style="fill:#ffffff"
@@ -1412,8 +1474,8 @@
     </g>
     <rect
        ry="17.13995"
-       y="885.55573"
-       x="263.56564"
+       y="899.21509"
+       x="270.905"
        height="105.47661"
        width="160"
        id="rect3336-9-5-9-0-52-9"
@@ -1423,27 +1485,27 @@
        id="rect4476-4-7-5-4"
        width="160"
        height="105.47656"
-       x="263.56564"
-       y="885.55573"
+       x="270.905"
+       y="899.21509"
        ry="16.282944" />
     <text
        id="text4545-3-5-4-8"
-       y="951.05591"
-       x="347.02975"
+       y="964.71527"
+       x="354.36911"
        style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
        xml:space="preserve"><tspan
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="951.05591"
-         x="347.02975"
+         y="964.71527"
+         x="354.36911"
          sodipodi:role="line"
          id="tspan1484-2">Implicit</tspan><tspan
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="982.30591"
-         x="347.02975"
+         y="995.96527"
+         x="354.36911"
          sodipodi:role="line"
          id="tspan1813">Layers</tspan></text>
     <g
-       transform="matrix(0.08921554,0,0,0.08921554,293.33634,833.83483)"
+       transform="matrix(0.08921554,0,0,0.08921554,300.6757,847.49418)"
        id="g4455-3-0-2-5-4-9">
       <g
          transform="translate(-72.428508,584.97477)"
@@ -1468,7 +1530,7 @@
         </g>
         <polygon
            style="fill:#ffffff"
-           points="781.89,237.33 829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 "
+           points="774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 829.91,237.33 "
            id="polygon13-6-7-1-6-68-5" />
         <path
            style="fill:#ffffff"
@@ -1714,54 +1776,4 @@
       </g>
     </g>
   </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer3"
-     inkscape:label="Arrows">
-    <path
-       style="opacity:0.995;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker4972)"
-       d="M 901.84772,693.48473 H 941.0171"
-       id="path4968"
-       transform="translate(11.848806,-624.74961)" />
-    <path
-       style="opacity:0.995;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker5116)"
-       d="m 901.04291,774.37003 37.97113,52.38031"
-       id="path5112"
-       transform="translate(11.848806,-624.74961)" />
-    <path
-       style="opacity:0.995;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker5266)"
-       d="m 899.92176,821.44965 40.56793,110.20673"
-       id="path5262"
-       transform="translate(11.848806,-624.74961)" />
-    <path
-       style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker7572)"
-       d="m 169.4233,708.78045 h 54.92836"
-       id="path8841"
-       transform="translate(11.848806,-624.74961)" />
-    <path
-       style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker7572-9)"
-       d="m 166.68169,810.66057 h 54.92836"
-       id="path8841-3"
-       transform="translate(11.848806,-624.74961)" />
-    <path
-       style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker4554-3);marker-end:url(#marker4436-7)"
-       d="m 574.65894,218.43902 0.24384,46.78299"
-       id="path4432-3" />
-    <path
-       style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker4554-5);marker-end:url(#marker4436-9)"
-       d="m 360.65894,218.43902 0.24384,46.78299"
-       id="path4432-2" />
-    <path
-       style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker4554-5-7);marker-end:url(#marker4436-9-9)"
-       d="m 791.67697,216.70625 0.24384,46.78299"
-       id="path4432-2-6" />
-    <path
-       style="fill:none;stroke:#000000;stroke-width:1.6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6.4, 6.4;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker2880)"
-       d="m 428.32824,313.58657 h 54.96685"
-       id="path3863" />
-    <path
-       style="fill:none;stroke:#000000;stroke-width:1.6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6.4, 6.4;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker2880-0)"
-       d="m 656.82552,313.36962 h 54.96685"
-       id="path3863-2" />
-  </g>
 </svg>
diff --git a/docs/images/svgs/loader_layer_order_calls.svg b/docs/images/svgs/loader_layer_order_calls.svg
index 51e2e8e..098fe89 100644
--- a/docs/images/svgs/loader_layer_order_calls.svg
+++ b/docs/images/svgs/loader_layer_order_calls.svg
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <svg
-   width="1640.5771"
+   width="1436.9304"
    height="277.24231"
-   viewBox="0 0 1640.5771 277.24231"
+   viewBox="0 0 1436.9304 277.24231"
    id="svg16410"
    version="1.1"
-   inkscape:version="1.1 (c68e22c387, 2021-05-23)"
+   inkscape:version="1.4.2 (ebf0e940, 2025-05-08)"
    sodipodi:docname="loader_layer_order_calls.svg"
    inkscape:export-filename="/home/marky/dev/khronos/hub/loader/docs/images/loader_layer_order_calls.png"
    inkscape:export-xdpi="96"
@@ -366,7 +366,7 @@
        x2="55.75"
        y2="1014.3622" />
     <linearGradient
-       gradientTransform="matrix(0.41145364,0,0,0.8430316,763.48864,277.81813)"
+       gradientTransform="matrix(0.41145364,0,0,0.71103834,549.48015,384.74126)"
        inkscape:collect="always"
        xlink:href="#Brown-4"
        id="linearGradient4620-0-16-5-3-2"
@@ -380,13 +380,13 @@
        xlink:href="#Shine-2"
        id="linearGradient12476-8-9"
        gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.4188057,0,0,3.010828,851.17081,-2115.491)"
+       gradientTransform="matrix(1.4188057,0,0,2.4889158,637.16232,-1583.6253)"
        x1="55.75"
        y1="994.11218"
        x2="55.75"
        y2="1014.3622" />
     <linearGradient
-       gradientTransform="matrix(0.4,0,0,0.82806544,976.00847,290.47946)"
+       gradientTransform="matrix(0.4,0,0,0.82806544,769.95766,292.96251)"
        inkscape:collect="always"
        xlink:href="#Brown-4"
        id="linearGradient4620-0-16-5-9-2"
@@ -400,7 +400,7 @@
        xlink:href="#Shine-2"
        id="linearGradient12476-4-8"
        gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.3793103,0,0,2.9573762,1061.2498,-2060.3408)"
+       gradientTransform="matrix(1.3793103,0,0,2.9573762,855.19899,-2057.8577)"
        x1="55.75"
        y1="994.11218"
        x2="55.75"
@@ -418,7 +418,7 @@
          id="stop5705" />
     </linearGradient>
     <linearGradient
-       gradientTransform="matrix(0.36535919,0,0,0.4,1396.3162,-322.41721)"
+       gradientTransform="matrix(0.36535919,0,0,0.4,1190.2654,-319.93416)"
        inkscape:collect="always"
        xlink:href="#Blue-2"
        id="linearGradient4620-0-16-5-1-0-3"
@@ -432,13 +432,13 @@
        xlink:href="#Shine-2"
        id="linearGradient4815-5"
        gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.2598591,0,0,1.4285715,1474.1752,-1457.9896)"
+       gradientTransform="matrix(1.2598591,0,0,1.4285715,1268.1244,-1455.5065)"
        x1="55.75"
        y1="994.11218"
        x2="55.75"
        y2="1014.3622" />
     <linearGradient
-       gradientTransform="matrix(0.4,0,0,0.53747337,1188.6953,-346.34807)"
+       gradientTransform="matrix(0.4,0,0,0.53747337,982.64449,-343.86502)"
        inkscape:collect="always"
        xlink:href="#Red-1"
        id="linearGradient4620-3"
@@ -456,49 +456,13 @@
        x2="55.75"
        y2="1014.3622"
        gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.3793103,0,0,1.9195479,1273.9366,-1872.1979)" />
-    <marker
-       inkscape:stockid="Arrow1Lend"
-       orient="auto"
-       refY="0"
-       refX="0"
-       id="Arrow1Lend-6-4-3"
-       style="overflow:visible"
-       inkscape:isstock="true"
-       inkscape:collect="always">
-      <path
-         id="path5046-2-4-6"
-         d="M 0,0 5,-5 -12.5,0 5,5 Z"
-         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
-         transform="matrix(-0.8,0,0,-0.8,-10,0)"
-         inkscape:connector-curvature="0" />
-    </marker>
-    <linearGradient
-       gradientTransform="matrix(0.4,0,0,0.52850836,554.73765,533.06117)"
-       inkscape:collect="always"
-       xlink:href="#Brown-4"
-       id="linearGradient4620-0-16-5-7"
-       x1="402"
-       y1="711.36218"
-       x2="401"
-       y2="909.36218"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#Shine-2"
-       id="linearGradient12476-1-5"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.3793103,0,0,1.8875293,639.97901,-967.3369)"
-       x1="55.75"
-       y1="994.11218"
-       x2="55.75"
-       y2="1014.3622" />
+       gradientTransform="matrix(1.3793103,0,0,1.9195479,1067.8858,-1869.7148)" />
     <linearGradient
        inkscape:collect="always"
        xlink:href="#Blue-2"
        id="linearGradient2678"
        gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.36535919,0,0,0.4,1395.2815,-235.23188)"
+       gradientTransform="matrix(0.36535919,0,0,0.4,1189.2307,-232.74883)"
        x1="402"
        y1="711.36218"
        x2="401"
@@ -508,7 +472,7 @@
        xlink:href="#Shine-2"
        id="linearGradient2680"
        gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.2598591,0,0,1.4285715,1473.1405,-1370.8043)"
+       gradientTransform="matrix(1.2598591,0,0,1.4285715,1267.0897,-1368.3212)"
        x1="55.75"
        y1="994.11218"
        x2="55.75"
@@ -518,7 +482,7 @@
        xlink:href="#Blue-2"
        id="linearGradient2787"
        gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.36535919,0,0,0.4,1395.2815,-147.23188)"
+       gradientTransform="matrix(0.36535919,0,0,0.4,1189.2307,-144.74883)"
        x1="402"
        y1="711.36218"
        x2="401"
@@ -528,7 +492,7 @@
        xlink:href="#Shine-2"
        id="linearGradient2789"
        gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.2598591,0,0,1.4285715,1473.1405,-1282.8043)"
+       gradientTransform="matrix(1.2598591,0,0,1.4285715,1267.0897,-1280.3212)"
        x1="55.75"
        y1="994.11218"
        x2="55.75"
@@ -542,15 +506,15 @@
      inkscape:pageopacity="0.0"
      inkscape:pageshadow="2"
      inkscape:zoom="1.0606602"
-     inkscape:cx="1497.1807"
-     inkscape:cy="188.5618"
+     inkscape:cx="1113.9289"
+     inkscape:cy="133.40748"
      inkscape:document-units="px"
-     inkscape:current-layer="layer2"
+     inkscape:current-layer="layer1"
      showgrid="false"
-     inkscape:window-width="2399"
-     inkscape:window-height="863"
-     inkscape:window-x="750"
-     inkscape:window-y="540"
+     inkscape:window-width="1440"
+     inkscape:window-height="770"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
      inkscape:window-maximized="0"
      units="px"
      inkscape:document-rotation="0"
@@ -558,7 +522,9 @@
      fit-margin-left="0"
      fit-margin-right="0"
      fit-margin-bottom="0"
-     inkscape:pagecheckerboard="0" />
+     inkscape:pagecheckerboard="0"
+     inkscape:showpageshadow="2"
+     inkscape:deskcolor="#d1d1d1" />
   <metadata
      id="metadata16415">
     <rdf:RDF>
@@ -576,25 +542,25 @@
      inkscape:label="Background"
      transform="translate(0.62160975,46.138115)">
     <rect
-       style="opacity:1;fill:#e2dbe3;fill-opacity:1;stroke:none;stroke-width:2.22385;stroke-miterlimit:4;stroke-dasharray:6.67151, 6.67151;stroke-dashoffset:0;stroke-opacity:1"
+       style="opacity:1;fill:#e2dbe3;fill-opacity:1;stroke:none;stroke-width:2.08125;stroke-miterlimit:4;stroke-dasharray:6.24372, 6.24372;stroke-dashoffset:0;stroke-opacity:1"
        id="rect3742"
-       width="1640.5771"
+       width="1436.9304"
        height="277.24231"
        x="-0.62160975"
        y="-46.138115"
        ry="13.977314" />
     <rect
        ry="13"
-       y="-37.472317"
-       x="1476.6952"
+       y="-34.989262"
+       x="1270.6444"
        height="80"
        width="146.14368"
        id="rect3336-9-5-9-0-5-3-6"
        style="fill:url(#linearGradient4620-0-16-5-1-0-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.95572;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
     <rect
        ry="13"
-       y="-37.472317"
-       x="1476.6952"
+       y="-34.989262"
+       x="1270.6444"
        height="80"
        width="146.14365"
        id="rect4775-2"
@@ -602,16 +568,16 @@
     <text
        xml:space="preserve"
        style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="1548.6617"
-       y="26.027687"
+       x="1342.611"
+       y="28.510742"
        id="text4811-9"><tspan
          sodipodi:role="line"
          id="tspan4813-1"
-         x="1548.6617"
-         y="26.027687"
+         x="1342.611"
+         y="28.510742"
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1">Driver</tspan></text>
     <g
-       transform="matrix(0.08921554,0,0,0.08921554,1500.4659,-89.19318)"
+       transform="matrix(0.08921554,0,0,0.08921554,1294.4151,-86.710125)"
        id="g4455-3-0-2-5-6-7-2">
       <g
          transform="translate(-72.428508,584.97477)"
@@ -636,7 +602,7 @@
         </g>
         <polygon
            style="fill:#ffffff"
-           points="730.84,296.19 730.74,290.47 781.89,237.33 829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 "
+           points="829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 "
            id="polygon13-6-7-1-6-4-3-0" />
         <path
            style="fill:#ffffff"
@@ -682,16 +648,16 @@
     </g>
     <rect
        ry="13"
-       y="49.713013"
-       x="1475.6605"
+       y="52.196068"
+       x="1269.6097"
        height="80"
        width="146.14368"
        id="rect3336-9-5-9-0-5-3-6-3"
        style="fill:url(#linearGradient2678);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.95572;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
     <rect
        ry="13"
-       y="49.713013"
-       x="1475.6605"
+       y="52.196068"
+       x="1269.6097"
        height="80"
        width="146.14365"
        id="rect4775-2-5"
@@ -699,16 +665,16 @@
     <text
        xml:space="preserve"
        style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="1547.6271"
-       y="113.21301"
+       x="1341.5763"
+       y="115.69607"
        id="text4811-9-6"><tspan
          sodipodi:role="line"
          id="tspan4813-1-2"
-         x="1547.6271"
-         y="113.21301"
+         x="1341.5763"
+         y="115.69607"
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1">Driver</tspan></text>
     <g
-       transform="matrix(0.08921554,0,0,0.08921554,1499.4312,-2.007851)"
+       transform="matrix(0.08921554,0,0,0.08921554,1293.3804,0.47520379)"
        id="g4455-3-0-2-5-6-7-2-9">
       <g
          transform="translate(-72.428508,584.97477)"
@@ -733,7 +699,7 @@
         </g>
         <polygon
            style="fill:#ffffff"
-           points="836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 829.91,237.33 774.18,291.62 "
+           points="730.74,290.47 781.89,237.33 829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 "
            id="polygon13-6-7-1-6-4-3-0-3" />
         <path
            style="fill:#ffffff"
@@ -779,16 +745,16 @@
     </g>
     <rect
        ry="13"
-       y="137.71301"
-       x="1475.6605"
+       y="140.19606"
+       x="1269.6097"
        height="80"
        width="146.14368"
        id="rect3336-9-5-9-0-5-3-6-7"
        style="fill:url(#linearGradient2787);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.95572;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
     <rect
        ry="13"
-       y="137.71301"
-       x="1475.6605"
+       y="140.19606"
+       x="1269.6097"
        height="80"
        width="146.14365"
        id="rect4775-2-59"
@@ -796,16 +762,16 @@
     <text
        xml:space="preserve"
        style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="1547.6271"
-       y="201.21301"
+       x="1341.5763"
+       y="203.69606"
        id="text4811-9-2"><tspan
          sodipodi:role="line"
          id="tspan4813-1-28"
-         x="1547.6271"
-         y="201.21301"
+         x="1341.5763"
+         y="203.69606"
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1">Driver</tspan></text>
     <g
-       transform="matrix(0.08921554,0,0,0.08921554,1499.4312,85.992149)"
+       transform="matrix(0.08921554,0,0,0.08921554,1293.3804,88.475204)"
        id="g4455-3-0-2-5-6-7-2-97">
       <g
          transform="translate(-72.428508,584.97477)"
@@ -830,7 +796,7 @@
         </g>
         <polygon
            style="fill:#ffffff"
-           points="829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 "
+           points="787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 829.91,237.33 774.18,291.62 836.19,385.06 "
            id="polygon13-6-7-1-6-4-3-0-1" />
         <path
            style="fill:#ffffff"
@@ -876,38 +842,38 @@
     </g>
     <rect
        ry="17.467884"
-       y="36.527683"
-       x="1276.6952"
+       y="39.010738"
+       x="1070.6444"
        height="107.49467"
        width="160"
        id="rect3336-9-8"
        style="fill:url(#linearGradient4620-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.81966;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
     <rect
        ry="17.467884"
-       y="36.527683"
-       x="1276.6952"
+       y="39.010738"
+       x="1070.6444"
        height="107.49467"
        width="160"
        id="rect3336-3-1-4"
        style="fill:url(#linearGradient4159-3-8);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.840676;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
     <text
        id="text4545-4-7-3"
-       y="98.664352"
-       x="1358.0118"
+       y="101.14741"
+       x="1151.9611"
        style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
        xml:space="preserve"><tspan
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="98.664352"
-         x="1358.0118"
+         y="101.14741"
+         x="1151.9611"
          id="tspan4547-3-8-1"
          sodipodi:role="line">Loader</tspan><tspan
          id="tspan17295-1-4"
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="129.91435"
-         x="1358.0118"
+         y="132.3974"
+         x="1151.9611"
          sodipodi:role="line">Terminator</tspan></text>
     <g
-       transform="matrix(0.08921554,0,0,0.08921554,1308.466,-16.556583)"
+       transform="matrix(0.08921554,0,0,0.08921554,1102.4152,-14.073528)"
        id="g4455-3-75-9">
       <g
          transform="translate(-72.428508,584.97477)"
@@ -932,7 +898,7 @@
         </g>
         <polygon
            style="fill:#ffffff"
-           points="730.74,290.47 781.89,237.33 829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 "
+           points="774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 829.91,237.33 "
            id="polygon13-6-3-2" />
         <path
            style="fill:#ffffff"
@@ -978,15 +944,15 @@
     </g>
     <path
        style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker1563)"
-       d="m 1435.9586,86.326981 40.9853,-90.947467"
+       d="m 1229.9078,88.810036 40.9853,-90.9474672"
        id="path1535" />
     <path
        style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker1543)"
-       d="m 1435.9586,86.326981 h 40.1301"
+       d="m 1229.9078,88.810036 h 40.1301"
        id="path1537" />
     <path
        style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker1553)"
-       d="m 1435.9586,86.326981 37.92,96.605589"
+       d="m 1229.9078,88.810036 37.92,96.605584"
        id="path1539" />
   </g>
   <g
@@ -996,13 +962,13 @@
      transform="translate(0.62160975,-826.22405)">
     <path
        style="opacity:0.987;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend-6-33)"
-       d="m 1144.0085,962.36215 h 130"
+       d="M 937.95769,964.8452 H 1067.9577"
        id="path5037-2-5"
        inkscape:connector-curvature="0"
        sodipodi:nodetypes="cc" />
     <path
        style="opacity:0.987;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend-6-6)"
-       d="M 934.00847,962.36215 H 1064.0085"
+       d="M 727.95766,964.8452 H 857.95769"
        id="path5037-2-0"
        inkscape:connector-curvature="0"
        sodipodi:nodetypes="cc" />
@@ -1077,7 +1043,7 @@
         </g>
         <polygon
            style="fill:#ffffff"
-           points="829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 "
+           points="836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 829.91,237.33 774.18,291.62 "
            id="polygon13-6" />
         <path
            style="fill:#ffffff"
@@ -1179,7 +1145,7 @@
         </g>
         <polygon
            style="fill:#ffffff"
-           points="730.84,296.19 730.74,290.47 781.89,237.33 829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 "
+           points="781.89,237.33 829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 "
            id="polygon13-6-0" />
         <path
            style="fill:#ffffff"
@@ -1224,49 +1190,44 @@
       </g>
     </g>
     <rect
-       ry="27.398527"
-       y="878.36218"
-       x="854.00848"
-       height="168.60632"
+       ry="23.108746"
+       y="891.2583"
+       x="640"
+       height="142.20767"
        width="164.58147"
        id="rect3336-9-5-9-0-6-0"
-       style="fill:url(#linearGradient4620-0-16-5-3-2);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.47239;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+       style="fill:url(#linearGradient4620-0-16-5-3-2);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.35222;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
     <rect
-       style="fill:url(#linearGradient12476-8-9);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.52989;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       style="fill:url(#linearGradient12476-8-9);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.39098;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
        id="rect4476-4-7-5-6"
        width="164.58147"
-       height="168.60635"
-       x="854.00848"
-       y="878.36218"
-       ry="27.398533" />
+       height="139.37927"
+       x="640"
+       y="891.2583"
+       ry="22.649132" />
     <text
        id="text4545-3-5-3-7"
-       y="941.8623"
-       x="934.63275"
+       y="954.75842"
+       x="720.62427"
        style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
        xml:space="preserve"><tspan
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="941.8623"
-         x="934.63275"
+         y="954.75842"
+         x="720.62427"
          id="tspan4547-0-9-0-4"
          sodipodi:role="line">Environment</tspan><tspan
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="973.1123"
-         x="934.63275"
+         y="986.00842"
+         x="720.62427"
          sodipodi:role="line"
-         id="tspan1178">Enabled</tspan><tspan
+         id="tspan1180">Enabled</tspan><tspan
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="1004.3623"
-         x="934.63275"
-         sodipodi:role="line"
-         id="tspan1180">Explicit</tspan><tspan
-         style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="1035.6123"
-         x="934.63275"
+         y="1017.2584"
+         x="720.62427"
          sodipodi:role="line"
          id="tspan1182">Layers</tspan></text>
     <g
-       transform="matrix(0.08921554,0,0,0.08921554,887.77917,826.6423)"
+       transform="matrix(0.08921554,0,0,0.08921554,673.77068,839.53839)"
        id="g4455-3-23">
       <g
          transform="translate(-72.428508,584.97477)"
@@ -1291,7 +1252,7 @@
         </g>
         <polygon
            style="fill:#ffffff"
-           points="829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 "
+           points="730.74,290.47 781.89,237.33 829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 "
            id="polygon13-6-9" />
         <path
            style="fill:#ffffff"
@@ -1337,8 +1298,8 @@
     </g>
     <rect
        ry="26.912127"
-       y="880.36218"
-       x="1064.0084"
+       y="882.84521"
+       x="857.95758"
        height="165.61308"
        width="160"
        id="rect3336-9-5-9-0-1-2"
@@ -1348,37 +1309,37 @@
        id="rect4476-4-7-7-0"
        width="160"
        height="165.61305"
-       x="1064.0084"
-       y="880.36218"
+       x="857.95758"
+       y="882.84521"
        ry="26.912123" />
     <text
        id="text4545-3-5-8-6"
-       y="943.8623"
-       x="1142.6327"
+       y="946.34534"
+       x="936.58185"
        style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
        xml:space="preserve"><tspan
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="943.8623"
-         x="1142.6327"
+         y="946.34534"
+         x="936.58185"
          id="tspan4547-0-9-2-7"
          sodipodi:role="line">Application</tspan><tspan
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="975.1123"
-         x="1142.6327"
+         y="977.59534"
+         x="936.58185"
          sodipodi:role="line"
          id="tspan1184">Enabled</tspan><tspan
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="1006.3623"
-         x="1142.6327"
+         y="1008.8453"
+         x="936.58185"
          sodipodi:role="line"
          id="tspan1186">Explicit</tspan><tspan
          style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="1037.6123"
-         x="1142.6327"
+         y="1040.0953"
+         x="936.58185"
          sodipodi:role="line"
          id="tspan1188">Layers</tspan></text>
     <g
-       transform="matrix(0.08921554,0,0,0.08921554,1093.7792,828.6423)"
+       transform="matrix(0.08921554,0,0,0.08921554,887.72839,831.12535)"
        id="g4455-3-7">
       <g
          transform="translate(-72.428508,584.97477)"
@@ -1403,7 +1364,7 @@
         </g>
         <polygon
            style="fill:#ffffff"
-           points="730.84,296.19 730.74,290.47 781.89,237.33 829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 "
+           points="829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 "
            id="polygon13-6-6" />
         <path
            style="fill:#ffffff"
@@ -1505,7 +1466,7 @@
         </g>
         <polygon
            style="fill:#ffffff"
-           points="829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 "
+           points="836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 829.91,237.33 774.18,291.62 "
            id="polygon13-6-3" />
         <path
            style="fill:#ffffff"
@@ -1549,113 +1510,5 @@
            id="path31-6-3" />
       </g>
     </g>
-    <path
-       style="opacity:0.987;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend-6-4-3)"
-       d="m 722.73765,961.5507 h 130"
-       id="path5037-2-1-9"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <rect
-       ry="17.176521"
-       y="909.55066"
-       x="642.73767"
-       height="105.70168"
-       width="160"
-       id="rect3336-9-5-9-0-1"
-       style="fill:url(#linearGradient4620-0-16-5-7);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.14947;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
-    <rect
-       style="fill:url(#linearGradient12476-1-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.19435;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect4476-4-7-0-2"
-       width="160"
-       height="105.70163"
-       x="642.73767"
-       y="909.55066"
-       ry="17.176516" />
-    <text
-       id="text4545-3-5-1-7"
-       y="973.05078"
-       x="721.37415"
-       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       xml:space="preserve"><tspan
-         style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="973.05078"
-         x="721.37415"
-         sodipodi:role="line"
-         id="tspan1176-9">Override</tspan><tspan
-         style="font-size:25px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"
-         y="1004.3008"
-         x="721.37415"
-         sodipodi:role="line"
-         id="tspan2591">Layer</tspan></text>
-    <g
-       transform="matrix(0.08921554,0,0,0.08921554,672.50835,857.8308)"
-       id="g4455-3-2-3">
-      <g
-         transform="translate(-72.428508,584.97477)"
-         id="g3-6-7-6">
-        <path
-           style="fill:#ffffff"
-           inkscape:connector-curvature="0"
-           d="m 724.1,385.06 h -40.57 c 0,0 0,-98.97 0,-129.66 12.96,7.22 30.09,20.54 40.57,33.32 z"
-           id="path5-7-0-0" />
-        <g
-           id="g7-5-9-6">
-          <path
-             style="fill:#ffffff"
-             inkscape:connector-curvature="0"
-             d="M 381.75,385.06 H 331.17 L 265.16,181.03 h 46.01 l 45.44,143.45 h 0.57 l 46,-143.45 h 46.29 z"
-             id="path9-3-3-2" />
-          <path
-             style="fill:#ffffff"
-             inkscape:connector-curvature="0"
-             d="m 585.51,385.06 h -38.58 v -20.57 h -0.85 c -5.15,8.58 -11.81,14.77 -20.01,18.58 -8.19,3.81 -16.57,5.71 -25.15,5.71 -10.86,0 -19.76,-1.43 -26.72,-4.28 -6.95,-2.85 -12.43,-6.91 -16.43,-12.14 -4.01,-5.24 -6.82,-11.62 -8.44,-19.15 -1.61,-7.52 -2.42,-15.86 -2.42,-25 v -90.88 h 40.58 v 83.44 c 0,12.19 1.91,21.29 5.72,27.29 3.81,6.01 10.57,9 20.29,9 11.05,0 19.05,-3.28 24,-9.86 4.96,-6.58 7.43,-17.39 7.43,-32.44 v -77.44 h 40.59 v 147.74 z"
-             id="path11-5-6-6" />
-        </g>
-        <polygon
-           style="fill:#ffffff"
-           points="829.91,237.33 774.18,291.62 836.19,385.06 787.04,385.06 730.84,296.19 730.74,290.47 781.89,237.33 "
-           id="polygon13-6-0-1" />
-        <path
-           style="fill:#ffffff"
-           inkscape:connector-curvature="0"
-           d="m 843.62,282.76 c 0.57,-9.52 2.96,-17.43 7.15,-23.72 4.19,-6.29 9.52,-11.33 16,-15.14 6.48,-3.81 13.77,-6.53 21.87,-8.14 8.09,-1.62 16.24,-2.43 24.43,-2.43 7.43,0 14.95,0.52 22.57,1.57 7.63,1.05 14.57,3.1 20.86,6.15 6.28,3.05 11.43,7.29 15.44,12.71 4,5.43 6,12.62 6,21.58 v 76.87 c 0,6.67 0.38,13.06 1.14,19.15 0.76,6.1 2.1,10.67 4.01,13.72 h -41.15 c -0.76,-2.28 -1.38,-4.62 -1.86,-7 -0.47,-2.38 -0.81,-4.8 -1,-7.29 -6.48,6.68 -14.11,11.34 -22.87,14.01 -8.76,2.66 -17.72,4 -26.86,4 -7.05,0 -13.63,-0.86 -19.71,-2.57 -6.1,-1.71 -11.44,-4.38 -16,-8 -4.58,-3.62 -8.16,-8.19 -10.72,-13.72 -2.57,-5.52 -3.86,-12.09 -3.86,-19.71 0,-8.38 1.48,-15.29 4.43,-20.72 2.96,-5.43 6.76,-9.76 11.44,-13 4.67,-3.24 10,-5.67 16,-7.29 6,-1.62 12.05,-2.91 18.14,-3.86 6.1,-0.94 12.1,-1.71 18.01,-2.28 5.91,-0.57 11.14,-1.43 15.71,-2.57 4.58,-1.15 8.19,-2.81 10.86,-5.01 2.67,-2.19 3.91,-5.38 3.72,-9.57 0,-4.38 -0.72,-7.86 -2.15,-10.43 -1.43,-2.57 -3.33,-4.57 -5.71,-6 -2.38,-1.43 -5.14,-2.38 -8.29,-2.86 -3.15,-0.48 -6.52,-0.72 -10.14,-0.72 -8,0 -14.29,1.71 -18.86,5.15 -4.57,3.43 -7.24,9.14 -8,17.15 h -40.6 z m 93.73,30.01 c -1.72,1.53 -3.86,2.71 -6.43,3.57 -2.57,0.87 -5.33,1.58 -8.29,2.15 -2.95,0.57 -6.05,1.05 -9.28,1.43 -3.24,0.38 -6.48,0.85 -9.72,1.43 -3.05,0.57 -6.05,1.34 -9,2.28 -2.95,0.96 -5.53,2.24 -7.72,3.86 -2.19,1.62 -3.95,3.67 -5.29,6.14 -1.33,2.48 -2,5.62 -2,9.43 0,3.62 0.67,6.67 2,9.14 1.34,2.48 3.15,4.43 5.43,5.86 2.29,1.43 4.95,2.43 8,3 3.05,0.57 6.19,0.85 9.43,0.85 8,0 14.2,-1.33 18.58,-3.99 4.38,-2.67 7.63,-5.86 9.71,-9.58 2.09,-3.71 3.39,-7.47 3.85,-11.28 0.48,-3.81 0.71,-6.86 0.72,-9.14 v -15.15 z"
-           id="path15-2-6-8" />
-        <path
-           style="fill:#ffffff"
-           inkscape:connector-curvature="0"
-           d="m 1004.21,237.33 h 38.59 v 20.57 h 0.85 c 5.14,-8.57 11.81,-14.81 20,-18.71 8.19,-3.91 16.58,-5.86 25.14,-5.86 10.87,0 19.77,1.48 26.73,4.43 6.95,2.96 12.42,7.05 16.43,12.29 4,5.24 6.81,11.62 8.43,19.14 1.62,7.53 2.43,15.86 2.43,25.01 v 90.87 h -40.57 v -83.44 c 0,-12.2 -1.91,-21.29 -5.71,-27.29 -3.82,-6 -10.58,-9 -20.3,-9 -11.05,0 -19.04,3.29 -24,9.86 -4.96,6.56 -7.43,17.38 -7.43,32.43 v 77.44 h -40.58 V 237.33 Z"
-           id="path17-9-2-7" />
-        <g
-           id="g19-1-6-9">
-          <path
-             style="fill:#ffffff"
-             inkscape:connector-curvature="0"
-             d="m 612.37,211.84 v 173.23 h 40.58 V 234.21 c -13.02,-7.98 -26.59,-15.47 -40.58,-22.37 z"
-             id="path21-2-1-2" />
-        </g>
-        <path
-           style="fill:#ffffff"
-           inkscape:connector-curvature="0"
-           d="m 198.43,219.21 c 23.52,-68.89 164.15,-94.16 314.15,-56.43 89.97,22.62 163.49,66.5 211.51,109.89 C 702.3,215.12 596.65,133.08 451.18,104.96 286.7,73.16 124.47,101.11 104.39,174.1 89.89,226.83 153.57,288.6 252.05,330.84 207.81,295.02 186.29,254.78 198.43,219.21 Z"
-           id="path23-7-8-0" />
-        <g
-           id="g25-0-7-2">
-          <path
-             style="fill:#ffffff"
-             inkscape:connector-curvature="0"
-             d="m 724.16,247.62 v -66.59 h -40.59 v 20.22 c 17.31,15.46 31.04,31.2 40.59,46.37 z"
-             id="path27-9-9-3" />
-        </g>
-      </g>
-      <g
-         transform="translate(-72.428508,584.97477)"
-         id="g29-3-2-7">
-        <path
-           style="fill:#ffffff"
-           inkscape:connector-curvature="0"
-           d="m 1214.52,363.68 c 0,12.26 -9.63,21.89 -22.15,21.89 -12.4,0 -22.29,-9.63 -22.29,-21.89 0,-12 9.89,-21.63 22.29,-21.63 12.53,0.01 22.15,9.63 22.15,21.63 z m -38.9,0 c 0,9.63 7.12,17.27 16.88,17.27 9.49,0 16.48,-7.65 16.48,-17.14 0,-9.63 -6.99,-17.41 -16.62,-17.41 -9.62,0.01 -16.74,7.79 -16.74,17.28 z m 13.32,11.34 h -5.01 V 353.4 c 1.98,-0.4 4.75,-0.66 8.31,-0.66 4.09,0 5.93,0.66 7.52,1.58 1.19,0.92 2.11,2.64 2.11,4.75 0,2.37 -1.85,4.22 -4.48,5.01 v 0.26 c 2.11,0.79 3.3,2.37 3.96,5.27 0.66,3.3 1.05,4.62 1.58,5.41 h -5.41 c -0.66,-0.79 -1.05,-2.77 -1.71,-5.27 -0.4,-2.37 -1.71,-3.43 -4.48,-3.43 h -2.37 v 8.7 z m 0.13,-12.26 h 2.37 c 2.77,0 5.01,-0.92 5.01,-3.17 0,-1.98 -1.45,-3.3 -4.62,-3.3 -1.32,0 -2.24,0.13 -2.77,0.26 v 6.21 z"
-           id="path31-6-0-5" />
-      </g>
-    </g>
   </g>
 </svg>
diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt
index 1497018..d9f983d 100644
--- a/loader/CMakeLists.txt
+++ b/loader/CMakeLists.txt
@@ -228,10 +228,10 @@
 
             find_package(Python3 REQUIRED QUIET)
             # Run parse_asm_values.py on asm_offset's assembly file to generate the gen_defines.asm, which the asm code depends on
-            add_custom_command(TARGET asm_offset POST_BUILD
+            add_custom_command(OUTPUT gen_defines.asm
+                DEPENDS asm_offset
                 COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/scripts/parse_asm_values.py "${CMAKE_CURRENT_BINARY_DIR}/gen_defines.asm"
                     "$<TARGET_FILE_DIR:asm_offset>/asm_offset.asm" "${LOADER_ASM_DIALECT}" "${CMAKE_C_COMPILER_ID}" "${SYSTEM_PROCESSOR}"
-                BYPRODUCTS gen_defines.asm
             )
         endif()
         add_custom_target(loader_asm_gen_files DEPENDS gen_defines.asm)
@@ -310,42 +310,38 @@
     endif()
 
     if(ASSEMBLER_WORKS)
-        add_executable(asm_offset asm_offset.c)
-        target_link_libraries(asm_offset loader_specific_options)
-        # If not cross compiling, run asm_offset to generage gen_defines.asm
+        # If not cross compiling, run asm_offset to generate gen_defines.asm
         if (NOT CMAKE_CROSSCOMPILING)
+            add_executable(asm_offset asm_offset.c)
+            target_link_libraries(asm_offset loader_specific_options)
             add_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset GAS)
         else()
+            add_library(asm_offset OBJECT asm_offset.c)
+            target_link_libraries(asm_offset loader_specific_options)
             # Forces compiler to write the intermediate asm file, needed so that we can get sizeof/offset of info out of it.
             # If with lto, compiler will output IR instead of asm, so we need to explicitly disable lto here.
             if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
-                target_compile_options(asm_offset PRIVATE -save-temps=obj -fno-lto)
+                target_compile_options(asm_offset PRIVATE -S -fno-lto)
             elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
-                target_compile_options(asm_offset PRIVATE -save-temps=obj -fno-lto -fno-whole-program-vtables -fno-virtual-function-elimination)
+                target_compile_options(asm_offset PRIVATE -S -fno-lto -fno-whole-program-vtables -fno-virtual-function-elimination)
             else()
-                target_compile_options(asm_offset PRIVATE -save-temps=obj)
+                target_compile_options(asm_offset PRIVATE -S)
             endif()
-            if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
-                set(ASM_OFFSET_EXECUTABLE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/gen_defines.asm")
-                set(ASM_OFFSET_INTERMEDIATE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/CMakeFiles/asm_offset.dir/asm_offset.c.s")
-            elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang")
-                set(ASM_OFFSET_EXECUTABLE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/gen_defines.asm")
-                set(ASM_OFFSET_INTERMEDIATE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/CMakeFiles/asm_offset.dir/asm_offset.s")
-            elseif(CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
-            # Need to use the current binary dir since the asm_offset.s file is in that folder rather than the bundle
-                set(ASM_OFFSET_EXECUTABLE_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/gen_defines.asm")
-                set(ASM_OFFSET_INTERMEDIATE_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/asm_offset.dir/asm_offset.s")
-            else()
+            if(NOT CMAKE_C_COMPILER_ID STREQUAL "GNU" AND
+               NOT CMAKE_C_COMPILER_ID STREQUAL "Clang" AND
+               NOT CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
                 message(FATAL_ERROR "C_COMPILER_ID not supported!")
             endif()
+            set(ASM_OFFSET_EXECUTABLE_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/gen_defines.asm")
+            set(ASM_OFFSET_INTERMEDIATE_LOCATION "$<TARGET_OBJECTS:asm_offset>")
             message(STATUS "CMAKE_CROSSCOMPILING FALSE")
 
             find_package(Python3 REQUIRED QUIET)
             # Run parse_asm_values.py on asm_offset's assembly file to generate the gen_defines.asm, which the asm code depends on
-            add_custom_command(TARGET asm_offset POST_BUILD
+            add_custom_command(OUTPUT gen_defines.asm
+                DEPENDS asm_offset
                 COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/scripts/parse_asm_values.py "${ASM_OFFSET_EXECUTABLE_LOCATION}"
                     "${ASM_OFFSET_INTERMEDIATE_LOCATION}" "GAS" "${CMAKE_C_COMPILER_ID}" "${ASM_OFFSET_SYSTEM_PROCESSOR}"
-                BYPRODUCTS gen_defines.asm
             )
         endif()
         add_custom_target(loader_asm_gen_files DEPENDS gen_defines.asm)
@@ -393,6 +389,10 @@
         set_target_properties(vulkan
                               PROPERTIES
                               PREFIX "")
+        # let the linker just fix up the stdcall mangling, like on msvc
+        if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+            target_link_options(vulkan PRIVATE "-Wl,--enable-stdcall-fixup")
+        endif()
     endif()
 
     if(MSVC AND ENABLE_WIN10_ONECORE)
@@ -430,17 +430,18 @@
     set_target_properties(vulkan PROPERTIES OUTPUT_NAME ${API_TYPE})
 
     if (LOADER_ENABLE_ADDRESS_SANITIZER)
-        target_compile_options(vulkan PUBLIC -fsanitize=address)
-        target_link_options(vulkan PUBLIC -fsanitize=address)
+        target_compile_options(vulkan PUBLIC -fsanitize=address,undefined)
+        target_link_options(vulkan PUBLIC -fsanitize=address,undefined)
+        # workaround regression in macOS SDK 15 when address sanitizer is enabled in debug mode
+        # https://developer.apple.com/forums/thread/774632
+        if (APPLE)
+            target_compile_options(vulkan PRIVATE -mllvm -asan-globals=0)
+        endif()
     endif()
     if (LOADER_ENABLE_THREAD_SANITIZER)
         target_compile_options(vulkan PUBLIC -fsanitize=thread)
         target_link_options(vulkan PUBLIC -fsanitize=thread)
     endif()
-    if (LOADER_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER)
-        target_compile_options(vulkan PUBLIC -fsanitize=undefined)
-        target_link_options(vulkan PUBLIC -fsanitize=undefined)
-    endif()
 
     if(APPLE)
         find_library(COREFOUNDATION_LIBRARY NAMES CoreFoundation)
@@ -517,6 +518,10 @@
     add_dependencies(vulkan loader_asm_gen_files)
 endif()
 
+if (BUILD_TESTS)
+    target_compile_definitions(vulkan PRIVATE SHOULD_EXPORT_TEST_FUNCTIONS)
+endif()
+
 if (APPLE_STATIC_LOADER)
     # TLDR: This feature only exists at the request of Google for Chromium. No other project should use this!
     message(NOTICE "Apple STATIC lib: it will be built but not installed, and vulkan.pc and VulkanLoaderConfig.cmake won't be generated!")
diff --git a/loader/LoaderAndLayerInterface.md b/loader/LoaderAndLayerInterface.md
index 41ddf78..3a3249c 100644
--- a/loader/LoaderAndLayerInterface.md
+++ b/loader/LoaderAndLayerInterface.md
@@ -15,5 +15,5 @@
 
 This document has been renamed to
 [LoaderInterfaceArchitecture.md](../docs/LoaderInterfaceArchitecture.md) and can be
-found in the top-level docs folder of the Loader GitHb repo.
+found in the top-level docs folder of the Loader GitHub repo.
 Please refer to that document going forward.
diff --git a/loader/allocation.c b/loader/allocation.c
index 3397ef9..4ad6802 100644
--- a/loader/allocation.c
+++ b/loader/allocation.c
@@ -98,6 +98,10 @@
 #endif
     } else {
         pNewMem = realloc(pMemory, size);
+        // Clear out the newly allocated memory
+        if (size > orig_size) {
+            memset((uint8_t *)pNewMem + orig_size, 0, size - orig_size);
+        }
     }
     return pNewMem;
 }
diff --git a/loader/allocation.h b/loader/allocation.h
index e9c5bc5..8cfb498 100644
--- a/loader/allocation.h
+++ b/loader/allocation.h
@@ -30,6 +30,9 @@
 
 #include "loader_common.h"
 
+// The loader always aligns memory allocations to the largest unit size which is the size of a uint64_t
+#define loader_aligned_size(x) ((((x) + sizeof(uint64_t) - 1) / sizeof(uint64_t)) * sizeof(uint64_t))
+
 void *loader_instance_heap_alloc(const struct loader_instance *instance, size_t size, VkSystemAllocationScope allocation_scope);
 void *loader_instance_heap_calloc(const struct loader_instance *instance, size_t size, VkSystemAllocationScope allocation_scope);
 void loader_instance_heap_free(const struct loader_instance *instance, void *pMemory);
diff --git a/loader/cJSON.c b/loader/cJSON.c
index 307f9b4..f249cfb 100644
--- a/loader/cJSON.c
+++ b/loader/cJSON.c
@@ -59,8 +59,6 @@
 
 #include "cJSON.h"
 
-#include <vulkan/vulkan_core.h>
-
 #include "allocation.h"
 
 /* define our own boolean type */
@@ -151,7 +149,7 @@
 }
 
 /* Delete a cJSON structure. */
-CJSON_PUBLIC(void) loader_cJSON_Delete(cJSON *item) {
+TEST_FUNCTION_EXPORT CJSON_PUBLIC(void) loader_cJSON_Delete(cJSON *item) {
     cJSON *next = NULL;
     while (item != NULL) {
         next = item->next;
@@ -826,8 +824,8 @@
     cJSON *item = NULL;
 
     /* reset error position */
-    global_error.json = NULL;
-    global_error.position = 0;
+    // global_error.json = NULL;
+    // global_error.position = 0;
 
     if (value == NULL || 0 == buffer_length) {
         goto fail;
@@ -883,7 +881,7 @@
             *return_parse_end = (const char *)local_error.json + local_error.position;
         }
 
-        global_error = local_error;
+        // global_error = local_error;
     }
 
     return NULL;
@@ -950,7 +948,9 @@
 }
 
 /* Render a cJSON item/entity/structure to text. */
-CJSON_PUBLIC(char *) loader_cJSON_Print(const cJSON *item, bool *out_of_memory) { return (char *)print(item, true, out_of_memory); }
+TEST_FUNCTION_EXPORT CJSON_PUBLIC(char *) loader_cJSON_Print(const cJSON *item, bool *out_of_memory) {
+    return (char *)print(item, true, out_of_memory);
+}
 
 CJSON_PUBLIC(char *) loader_cJSON_PrintUnformatted(const cJSON *item, bool *out_of_memory) {
     return (char *)print(item, false, out_of_memory);
diff --git a/loader/cJSON.h b/loader/cJSON.h
index 85f6f07..f700ec3 100644
--- a/loader/cJSON.h
+++ b/loader/cJSON.h
@@ -88,6 +88,10 @@
 #include <stddef.h>
 #include <stdbool.h>
 
+#include <vulkan/vulkan_core.h>
+
+#include "vk_loader_platform.h"
+
 /* cJSON Types: */
 #define cJSON_Invalid (0)
 #define cJSON_False (1 << 0)
@@ -102,10 +106,6 @@
 #define cJSON_IsReference 256
 #define cJSON_StringIsConst 512
 
-/* loader type declarations for allocation hooks */
-typedef struct VkAllocationCallbacks VkAllocationCallbacks;
-struct loader_instance;
-
 /* The cJSON structure: */
 typedef struct cJSON {
     /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
@@ -127,7 +127,7 @@
     /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
     char *string;
     /* pointer to the allocation callbacks to use */
-    const VkAllocationCallbacks *pAllocator;
+    const struct VkAllocationCallbacks *pAllocator;
 } cJSON;
 
 typedef int cJSON_bool;
@@ -144,26 +144,27 @@
 #define CJSON_CIRCULAR_LIMIT 10000
 #endif
 
-/* Memory Management: the caller is always responsible to free instthe results from all variants of loader_cJSON_Parse (with
+/* Memory Management: the caller is always responsible to free the results from all variants of loader_cJSON_Parse (with
  * loader_cJSON_Delete) and loader_loader_cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The
  * exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
 /* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
-CJSON_PUBLIC(cJSON *) loader_cJSON_Parse(const VkAllocationCallbacks *pAllocator, const char *value, bool *out_of_memory);
+CJSON_PUBLIC(cJSON *) loader_cJSON_Parse(const struct VkAllocationCallbacks *pAllocator, const char *value, bool *out_of_memory);
 CJSON_PUBLIC(cJSON *)
-loader_cJSON_ParseWithLength(const VkAllocationCallbacks *pAllocator, const char *value, size_t buffer_length, bool *out_of_memory);
+loader_cJSON_ParseWithLength(const struct VkAllocationCallbacks *pAllocator, const char *value, size_t buffer_length,
+                             bool *out_of_memory);
 /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte
  * parsed. */
 /* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will
  * match cJSON_GetErrorPtr(). */
 CJSON_PUBLIC(cJSON *)
-loader_cJSON_ParseWithOpts(const VkAllocationCallbacks *pAllocator, const char *value, const char **return_parse_end,
+loader_cJSON_ParseWithOpts(const struct VkAllocationCallbacks *pAllocator, const char *value, const char **return_parse_end,
                            cJSON_bool require_null_terminated, bool *out_of_memory);
 CJSON_PUBLIC(cJSON *)
-loader_cJSON_ParseWithLengthOpts(const VkAllocationCallbacks *pAllocator, const char *value, size_t buffer_length,
+loader_cJSON_ParseWithLengthOpts(const struct VkAllocationCallbacks *pAllocator, const char *value, size_t buffer_length,
                                  const char **return_parse_end, cJSON_bool require_null_terminated, bool *out_of_memory);
 
 /* Render a cJSON entity to text for transfer/storage. */
-CJSON_PUBLIC(char *) loader_cJSON_Print(const cJSON *item, bool *out_of_memory);
+TEST_FUNCTION_EXPORT CJSON_PUBLIC(char *) loader_cJSON_Print(const cJSON *item, bool *out_of_memory);
 /* Render a cJSON entity to text for transfer/storage without any formatting. */
 CJSON_PUBLIC(char *) loader_cJSON_PrintUnformatted(const cJSON *item, bool *out_of_memory);
 /* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces
@@ -177,7 +178,7 @@
 CJSON_PUBLIC(cJSON_bool)
 loader_cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
 /* Delete a cJSON entity and all subentities. */
-CJSON_PUBLIC(void) loader_cJSON_Delete(cJSON *item);
+TEST_FUNCTION_EXPORT CJSON_PUBLIC(void) loader_cJSON_Delete(cJSON *item);
 
 /* Returns the number of items in an array (or object). */
 CJSON_PUBLIC(int) loader_cJSON_GetArraySize(const cJSON *array);
diff --git a/loader/debug_utils.c b/loader/debug_utils.c
index 1506dc5..01d8baa 100644
--- a/loader/debug_utils.c
+++ b/loader/debug_utils.c
@@ -612,43 +612,29 @@
                                   debug_utils_extension_info);
 }
 
-void check_for_enabled_debug_extensions(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) {
-    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
-            ptr_instance->enabled_known_extensions.ext_debug_report = 1;
-        } else if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) {
-            ptr_instance->enabled_known_extensions.ext_debug_utils = 1;
-        }
-    }
-}
-
 bool debug_extensions_InstanceGpa(struct loader_instance *ptr_instance, const char *name, void **addr) {
     bool ret_type = false;
 
     *addr = NULL;
 
     if (!strcmp("vkCreateDebugReportCallbackEXT", name)) {
-        *addr =
-            ptr_instance->enabled_known_extensions.ext_debug_report == 1 ? (void *)debug_utils_CreateDebugReportCallbackEXT : NULL;
+        *addr = ptr_instance->enabled_extensions.ext_debug_report == 1 ? (void *)debug_utils_CreateDebugReportCallbackEXT : NULL;
         ret_type = true;
     } else if (!strcmp("vkDestroyDebugReportCallbackEXT", name)) {
-        *addr =
-            ptr_instance->enabled_known_extensions.ext_debug_report == 1 ? (void *)debug_utils_DestroyDebugReportCallbackEXT : NULL;
+        *addr = ptr_instance->enabled_extensions.ext_debug_report == 1 ? (void *)debug_utils_DestroyDebugReportCallbackEXT : NULL;
         ret_type = true;
     } else if (!strcmp("vkDebugReportMessageEXT", name)) {
-        *addr = ptr_instance->enabled_known_extensions.ext_debug_report == 1 ? (void *)debug_utils_DebugReportMessageEXT : NULL;
+        *addr = ptr_instance->enabled_extensions.ext_debug_report == 1 ? (void *)debug_utils_DebugReportMessageEXT : NULL;
         return true;
     }
     if (!strcmp("vkCreateDebugUtilsMessengerEXT", name)) {
-        *addr =
-            ptr_instance->enabled_known_extensions.ext_debug_utils == 1 ? (void *)debug_utils_CreateDebugUtilsMessengerEXT : NULL;
+        *addr = ptr_instance->enabled_extensions.ext_debug_utils == 1 ? (void *)debug_utils_CreateDebugUtilsMessengerEXT : NULL;
         ret_type = true;
     } else if (!strcmp("vkDestroyDebugUtilsMessengerEXT", name)) {
-        *addr =
-            ptr_instance->enabled_known_extensions.ext_debug_utils == 1 ? (void *)debug_utils_DestroyDebugUtilsMessengerEXT : NULL;
+        *addr = ptr_instance->enabled_extensions.ext_debug_utils == 1 ? (void *)debug_utils_DestroyDebugUtilsMessengerEXT : NULL;
         ret_type = true;
     } else if (!strcmp("vkSubmitDebugUtilsMessageEXT", name)) {
-        *addr = ptr_instance->enabled_known_extensions.ext_debug_utils == 1 ? (void *)debug_utils_SubmitDebugUtilsMessageEXT : NULL;
+        *addr = ptr_instance->enabled_extensions.ext_debug_utils == 1 ? (void *)debug_utils_SubmitDebugUtilsMessageEXT : NULL;
         ret_type = true;
     }
 
diff --git a/loader/extension_manual.c b/loader/extension_manual.c
index de55a48..590cbb0 100644
--- a/loader/extension_manual.c
+++ b/loader/extension_manual.c
@@ -105,20 +105,14 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
 
-    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface);
-
-    // Unwrap the surface if needed
-    VkSurfaceKHR unwrapped_surface = surface;
-    if (NULL != phys_dev_term->this_icd_term->surface_list.list &&
-        phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-        phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) {
-        unwrapped_surface = phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index];
+    VkResult res = wsi_unwrap_icd_surface(icd_term, &surface);
+    if (res != VK_SUCCESS) {
+        return res;
     }
 
     if (NULL != icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT) {
         // Pass the call to the driver
-        return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT(phys_dev_term->phys_dev, unwrapped_surface,
-                                                                           pSurfaceCapabilities);
+        return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT(phys_dev_term->phys_dev, surface, pSurfaceCapabilities);
     } else {
         // Emulate the call
         loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
@@ -127,8 +121,7 @@
                    icd_term->scanned_icd->lib_name);
 
         VkSurfaceCapabilitiesKHR surface_caps;
-        VkResult res =
-            icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, unwrapped_surface, &surface_caps);
+        res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface, &surface_caps);
         pSurfaceCapabilities->minImageCount = surface_caps.minImageCount;
         pSurfaceCapabilities->maxImageCount = surface_caps.maxImageCount;
         pSurfaceCapabilities->currentExtent = surface_caps.currentExtent;
@@ -274,19 +267,17 @@
                    "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceSurfacePresentModes2EXT");
         abort();
     }
-    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
-    if (NULL != icd_term->surface_list.list &&
-        icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-        icd_term->surface_list.list[icd_surface->surface_index]) {
-        VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy;
-        surface_info_copy.sType = pSurfaceInfo->sType;
-        surface_info_copy.pNext = pSurfaceInfo->pNext;
-        surface_info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index];
-        return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, &surface_info_copy,
-                                                                           pPresentModeCount, pPresentModes);
+
+    VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy = *pSurfaceInfo;
+    if (VK_NULL_HANDLE != pSurfaceInfo->surface) {
+        VkResult res = wsi_unwrap_icd_surface(icd_term, &surface_info_copy.surface);
+        if (res != VK_SUCCESS) {
+            return res;
+        }
     }
-    return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, pSurfaceInfo, pPresentModeCount,
-                                                                       pPresentModes);
+
+    return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, &surface_info_copy,
+                                                                       pPresentModeCount, pPresentModes);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL GetDeviceGroupSurfacePresentModes2EXT(VkDevice device,
@@ -321,18 +312,17 @@
                    "[VUID-vkGetDeviceGroupSurfacePresentModes2EXT-pSurfaceInfo-parameter]");
         abort(); /* Intentionally fail so user can correct issue. */
     }
-    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
-    if (NULL != icd_term->surface_list.list &&
-        icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-        icd_term->surface_list.list[icd_surface->surface_index]) {
-        VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy;
-        surface_info_copy.sType = pSurfaceInfo->sType;
-        surface_info_copy.pNext = pSurfaceInfo->pNext;
-        surface_info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index];
-        return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, &surface_info_copy,
-                                                                                                        pModes);
+
+    VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy = *pSurfaceInfo;
+    if (VK_NULL_HANDLE != pSurfaceInfo->surface) {
+        VkResult res = wsi_unwrap_icd_surface(icd_term, &surface_info_copy.surface);
+        if (res != VK_SUCCESS) {
+            return res;
+        }
     }
-    return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes);
+
+    return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, &surface_info_copy,
+                                                                                                    pModes);
 }
 
 #endif  // VK_USE_PLATFORM_WIN32_KHR
diff --git a/loader/generated/vk_layer_dispatch_table.h b/loader/generated/vk_layer_dispatch_table.h
index b85e22a..9e97eb9 100644
--- a/loader/generated/vk_layer_dispatch_table.h
+++ b/loader/generated/vk_layer_dispatch_table.h
@@ -2,9 +2,9 @@
 // See loader_extension_generator.py for modifications
 
 /*
- * Copyright (c) 2015-2022 The Khronos Group Inc.
- * Copyright (c) 2015-2022 Valve Corporation
- * Copyright (c) 2015-2022 LunarG, Inc.
+ * Copyright (c) 2015-2025 The Khronos Group Inc.
+ * Copyright (c) 2015-2025 Valve Corporation
+ * Copyright (c) 2015-2025 LunarG, Inc.
  * Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  * Copyright (c) 2023-2023 RasterGrid Kft.
  *
@@ -22,16 +22,14 @@
  *
  * Author: Mark Lobodzinski <mark@lunarg.com>
  * Author: Mark Young <marky@lunarg.com>
+ * Author: Charles Giessen <charles@lunarg.com>
  */
 
 // clang-format off
 #pragma once
 
 #include <vulkan/vulkan.h>
-
-#if !defined(PFN_GetPhysicalDeviceProcAddr)
-typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName);
-#endif
+#include <vulkan/vk_layer.h>
 
 // Instance function pointer dispatch table
 typedef struct VkLayerInstanceDispatchTable_ {
@@ -227,6 +225,9 @@
     PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT;
     PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT;
 
+    // ---- VK_EXT_descriptor_heap extension commands
+    PFN_vkGetPhysicalDeviceDescriptorSizeEXT GetPhysicalDeviceDescriptorSizeEXT;
+
     // ---- VK_EXT_sample_locations extension commands
     PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT GetPhysicalDeviceMultisamplePropertiesEXT;
 
@@ -288,11 +289,46 @@
     PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX GetPhysicalDeviceScreenPresentationSupportQNX;
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_ARM_tensors extension commands
+    PFN_vkGetPhysicalDeviceExternalTensorPropertiesARM GetPhysicalDeviceExternalTensorPropertiesARM;
+
     // ---- VK_NV_optical_flow extension commands
     PFN_vkGetPhysicalDeviceOpticalFlowImageFormatsNV GetPhysicalDeviceOpticalFlowImageFormatsNV;
 
+    // ---- VK_NV_cooperative_vector extension commands
+    PFN_vkGetPhysicalDeviceCooperativeVectorPropertiesNV GetPhysicalDeviceCooperativeVectorPropertiesNV;
+
+    // ---- VK_ARM_data_graph extension commands
+    PFN_vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM;
+    PFN_vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM;
+
+    // ---- VK_ARM_data_graph_instruction_set_tosa extension commands
+    PFN_vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM;
+
+    // ---- VK_OHOS_surface extension commands
+#if defined(VK_USE_PLATFORM_OHOS)
+    PFN_vkCreateSurfaceOHOS CreateSurfaceOHOS;
+#endif // VK_USE_PLATFORM_OHOS
+
     // ---- VK_NV_cooperative_matrix2 extension commands
     PFN_vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV;
+
+    // ---- VK_ARM_performance_counters_by_region extension commands
+    PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM;
+
+    // ---- VK_ARM_shader_instrumentation extension commands
+    PFN_vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM EnumeratePhysicalDeviceShaderInstrumentationMetricsARM;
+
+    // ---- VK_ARM_data_graph_optical_flow extension commands
+    PFN_vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM;
+
+    // ---- VK_SEC_ubm_surface extension commands
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    PFN_vkCreateUbmSurfaceSEC CreateUbmSurfaceSEC;
+#endif // VK_USE_PLATFORM_UBM_SEC
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    PFN_vkGetPhysicalDeviceUbmPresentationSupportSEC GetPhysicalDeviceUbmPresentationSupportSEC;
+#endif // VK_USE_PLATFORM_UBM_SEC
 } VkLayerInstanceDispatchTable;
 
 // Device function pointer dispatch table
@@ -327,30 +363,50 @@
     PFN_vkWaitForFences WaitForFences;
     PFN_vkCreateSemaphore CreateSemaphore;
     PFN_vkDestroySemaphore DestroySemaphore;
-    PFN_vkCreateEvent CreateEvent;
-    PFN_vkDestroyEvent DestroyEvent;
-    PFN_vkGetEventStatus GetEventStatus;
-    PFN_vkSetEvent SetEvent;
-    PFN_vkResetEvent ResetEvent;
     PFN_vkCreateQueryPool CreateQueryPool;
     PFN_vkDestroyQueryPool DestroyQueryPool;
     PFN_vkGetQueryPoolResults GetQueryPoolResults;
     PFN_vkCreateBuffer CreateBuffer;
     PFN_vkDestroyBuffer DestroyBuffer;
-    PFN_vkCreateBufferView CreateBufferView;
-    PFN_vkDestroyBufferView DestroyBufferView;
     PFN_vkCreateImage CreateImage;
     PFN_vkDestroyImage DestroyImage;
     PFN_vkGetImageSubresourceLayout GetImageSubresourceLayout;
     PFN_vkCreateImageView CreateImageView;
     PFN_vkDestroyImageView DestroyImageView;
+    PFN_vkCreateCommandPool CreateCommandPool;
+    PFN_vkDestroyCommandPool DestroyCommandPool;
+    PFN_vkResetCommandPool ResetCommandPool;
+    PFN_vkAllocateCommandBuffers AllocateCommandBuffers;
+    PFN_vkFreeCommandBuffers FreeCommandBuffers;
+    PFN_vkBeginCommandBuffer BeginCommandBuffer;
+    PFN_vkEndCommandBuffer EndCommandBuffer;
+    PFN_vkResetCommandBuffer ResetCommandBuffer;
+    PFN_vkCmdCopyBuffer CmdCopyBuffer;
+    PFN_vkCmdCopyImage CmdCopyImage;
+    PFN_vkCmdCopyBufferToImage CmdCopyBufferToImage;
+    PFN_vkCmdCopyImageToBuffer CmdCopyImageToBuffer;
+    PFN_vkCmdUpdateBuffer CmdUpdateBuffer;
+    PFN_vkCmdFillBuffer CmdFillBuffer;
+    PFN_vkCmdPipelineBarrier CmdPipelineBarrier;
+    PFN_vkCmdBeginQuery CmdBeginQuery;
+    PFN_vkCmdEndQuery CmdEndQuery;
+    PFN_vkCmdResetQueryPool CmdResetQueryPool;
+    PFN_vkCmdWriteTimestamp CmdWriteTimestamp;
+    PFN_vkCmdCopyQueryPoolResults CmdCopyQueryPoolResults;
+    PFN_vkCmdExecuteCommands CmdExecuteCommands;
+    PFN_vkCreateEvent CreateEvent;
+    PFN_vkDestroyEvent DestroyEvent;
+    PFN_vkGetEventStatus GetEventStatus;
+    PFN_vkSetEvent SetEvent;
+    PFN_vkResetEvent ResetEvent;
+    PFN_vkCreateBufferView CreateBufferView;
+    PFN_vkDestroyBufferView DestroyBufferView;
     PFN_vkCreateShaderModule CreateShaderModule;
     PFN_vkDestroyShaderModule DestroyShaderModule;
     PFN_vkCreatePipelineCache CreatePipelineCache;
     PFN_vkDestroyPipelineCache DestroyPipelineCache;
     PFN_vkGetPipelineCacheData GetPipelineCacheData;
     PFN_vkMergePipelineCaches MergePipelineCaches;
-    PFN_vkCreateGraphicsPipelines CreateGraphicsPipelines;
     PFN_vkCreateComputePipelines CreateComputePipelines;
     PFN_vkDestroyPipeline DestroyPipeline;
     PFN_vkCreatePipelineLayout CreatePipelineLayout;
@@ -365,20 +421,21 @@
     PFN_vkAllocateDescriptorSets AllocateDescriptorSets;
     PFN_vkFreeDescriptorSets FreeDescriptorSets;
     PFN_vkUpdateDescriptorSets UpdateDescriptorSets;
+    PFN_vkCmdBindPipeline CmdBindPipeline;
+    PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets;
+    PFN_vkCmdClearColorImage CmdClearColorImage;
+    PFN_vkCmdDispatch CmdDispatch;
+    PFN_vkCmdDispatchIndirect CmdDispatchIndirect;
+    PFN_vkCmdSetEvent CmdSetEvent;
+    PFN_vkCmdResetEvent CmdResetEvent;
+    PFN_vkCmdWaitEvents CmdWaitEvents;
+    PFN_vkCmdPushConstants CmdPushConstants;
+    PFN_vkCreateGraphicsPipelines CreateGraphicsPipelines;
     PFN_vkCreateFramebuffer CreateFramebuffer;
     PFN_vkDestroyFramebuffer DestroyFramebuffer;
     PFN_vkCreateRenderPass CreateRenderPass;
     PFN_vkDestroyRenderPass DestroyRenderPass;
     PFN_vkGetRenderAreaGranularity GetRenderAreaGranularity;
-    PFN_vkCreateCommandPool CreateCommandPool;
-    PFN_vkDestroyCommandPool DestroyCommandPool;
-    PFN_vkResetCommandPool ResetCommandPool;
-    PFN_vkAllocateCommandBuffers AllocateCommandBuffers;
-    PFN_vkFreeCommandBuffers FreeCommandBuffers;
-    PFN_vkBeginCommandBuffer BeginCommandBuffer;
-    PFN_vkEndCommandBuffer EndCommandBuffer;
-    PFN_vkResetCommandBuffer ResetCommandBuffer;
-    PFN_vkCmdBindPipeline CmdBindPipeline;
     PFN_vkCmdSetViewport CmdSetViewport;
     PFN_vkCmdSetScissor CmdSetScissor;
     PFN_vkCmdSetLineWidth CmdSetLineWidth;
@@ -388,66 +445,39 @@
     PFN_vkCmdSetStencilCompareMask CmdSetStencilCompareMask;
     PFN_vkCmdSetStencilWriteMask CmdSetStencilWriteMask;
     PFN_vkCmdSetStencilReference CmdSetStencilReference;
-    PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets;
     PFN_vkCmdBindIndexBuffer CmdBindIndexBuffer;
     PFN_vkCmdBindVertexBuffers CmdBindVertexBuffers;
     PFN_vkCmdDraw CmdDraw;
     PFN_vkCmdDrawIndexed CmdDrawIndexed;
     PFN_vkCmdDrawIndirect CmdDrawIndirect;
     PFN_vkCmdDrawIndexedIndirect CmdDrawIndexedIndirect;
-    PFN_vkCmdDispatch CmdDispatch;
-    PFN_vkCmdDispatchIndirect CmdDispatchIndirect;
-    PFN_vkCmdCopyBuffer CmdCopyBuffer;
-    PFN_vkCmdCopyImage CmdCopyImage;
     PFN_vkCmdBlitImage CmdBlitImage;
-    PFN_vkCmdCopyBufferToImage CmdCopyBufferToImage;
-    PFN_vkCmdCopyImageToBuffer CmdCopyImageToBuffer;
-    PFN_vkCmdUpdateBuffer CmdUpdateBuffer;
-    PFN_vkCmdFillBuffer CmdFillBuffer;
-    PFN_vkCmdClearColorImage CmdClearColorImage;
     PFN_vkCmdClearDepthStencilImage CmdClearDepthStencilImage;
     PFN_vkCmdClearAttachments CmdClearAttachments;
     PFN_vkCmdResolveImage CmdResolveImage;
-    PFN_vkCmdSetEvent CmdSetEvent;
-    PFN_vkCmdResetEvent CmdResetEvent;
-    PFN_vkCmdWaitEvents CmdWaitEvents;
-    PFN_vkCmdPipelineBarrier CmdPipelineBarrier;
-    PFN_vkCmdBeginQuery CmdBeginQuery;
-    PFN_vkCmdEndQuery CmdEndQuery;
-    PFN_vkCmdResetQueryPool CmdResetQueryPool;
-    PFN_vkCmdWriteTimestamp CmdWriteTimestamp;
-    PFN_vkCmdCopyQueryPoolResults CmdCopyQueryPoolResults;
-    PFN_vkCmdPushConstants CmdPushConstants;
     PFN_vkCmdBeginRenderPass CmdBeginRenderPass;
     PFN_vkCmdNextSubpass CmdNextSubpass;
     PFN_vkCmdEndRenderPass CmdEndRenderPass;
-    PFN_vkCmdExecuteCommands CmdExecuteCommands;
 
     // ---- Core Vulkan 1.1 commands
     PFN_vkBindBufferMemory2 BindBufferMemory2;
     PFN_vkBindImageMemory2 BindImageMemory2;
     PFN_vkGetDeviceGroupPeerMemoryFeatures GetDeviceGroupPeerMemoryFeatures;
     PFN_vkCmdSetDeviceMask CmdSetDeviceMask;
-    PFN_vkCmdDispatchBase CmdDispatchBase;
     PFN_vkGetImageMemoryRequirements2 GetImageMemoryRequirements2;
     PFN_vkGetBufferMemoryRequirements2 GetBufferMemoryRequirements2;
     PFN_vkGetImageSparseMemoryRequirements2 GetImageSparseMemoryRequirements2;
     PFN_vkTrimCommandPool TrimCommandPool;
     PFN_vkGetDeviceQueue2 GetDeviceQueue2;
-    PFN_vkCreateSamplerYcbcrConversion CreateSamplerYcbcrConversion;
-    PFN_vkDestroySamplerYcbcrConversion DestroySamplerYcbcrConversion;
+    PFN_vkCmdDispatchBase CmdDispatchBase;
     PFN_vkCreateDescriptorUpdateTemplate CreateDescriptorUpdateTemplate;
     PFN_vkDestroyDescriptorUpdateTemplate DestroyDescriptorUpdateTemplate;
     PFN_vkUpdateDescriptorSetWithTemplate UpdateDescriptorSetWithTemplate;
     PFN_vkGetDescriptorSetLayoutSupport GetDescriptorSetLayoutSupport;
+    PFN_vkCreateSamplerYcbcrConversion CreateSamplerYcbcrConversion;
+    PFN_vkDestroySamplerYcbcrConversion DestroySamplerYcbcrConversion;
 
     // ---- Core Vulkan 1.2 commands
-    PFN_vkCmdDrawIndirectCount CmdDrawIndirectCount;
-    PFN_vkCmdDrawIndexedIndirectCount CmdDrawIndexedIndirectCount;
-    PFN_vkCreateRenderPass2 CreateRenderPass2;
-    PFN_vkCmdBeginRenderPass2 CmdBeginRenderPass2;
-    PFN_vkCmdNextSubpass2 CmdNextSubpass2;
-    PFN_vkCmdEndRenderPass2 CmdEndRenderPass2;
     PFN_vkResetQueryPool ResetQueryPool;
     PFN_vkGetSemaphoreCounterValue GetSemaphoreCounterValue;
     PFN_vkWaitSemaphores WaitSemaphores;
@@ -455,15 +485,18 @@
     PFN_vkGetBufferDeviceAddress GetBufferDeviceAddress;
     PFN_vkGetBufferOpaqueCaptureAddress GetBufferOpaqueCaptureAddress;
     PFN_vkGetDeviceMemoryOpaqueCaptureAddress GetDeviceMemoryOpaqueCaptureAddress;
+    PFN_vkCmdDrawIndirectCount CmdDrawIndirectCount;
+    PFN_vkCmdDrawIndexedIndirectCount CmdDrawIndexedIndirectCount;
+    PFN_vkCreateRenderPass2 CreateRenderPass2;
+    PFN_vkCmdBeginRenderPass2 CmdBeginRenderPass2;
+    PFN_vkCmdNextSubpass2 CmdNextSubpass2;
+    PFN_vkCmdEndRenderPass2 CmdEndRenderPass2;
 
     // ---- Core Vulkan 1.3 commands
     PFN_vkCreatePrivateDataSlot CreatePrivateDataSlot;
     PFN_vkDestroyPrivateDataSlot DestroyPrivateDataSlot;
     PFN_vkSetPrivateData SetPrivateData;
     PFN_vkGetPrivateData GetPrivateData;
-    PFN_vkCmdSetEvent2 CmdSetEvent2;
-    PFN_vkCmdResetEvent2 CmdResetEvent2;
-    PFN_vkCmdWaitEvents2 CmdWaitEvents2;
     PFN_vkCmdPipelineBarrier2 CmdPipelineBarrier2;
     PFN_vkCmdWriteTimestamp2 CmdWriteTimestamp2;
     PFN_vkQueueSubmit2 QueueSubmit2;
@@ -471,6 +504,12 @@
     PFN_vkCmdCopyImage2 CmdCopyImage2;
     PFN_vkCmdCopyBufferToImage2 CmdCopyBufferToImage2;
     PFN_vkCmdCopyImageToBuffer2 CmdCopyImageToBuffer2;
+    PFN_vkGetDeviceBufferMemoryRequirements GetDeviceBufferMemoryRequirements;
+    PFN_vkGetDeviceImageMemoryRequirements GetDeviceImageMemoryRequirements;
+    PFN_vkGetDeviceImageSparseMemoryRequirements GetDeviceImageSparseMemoryRequirements;
+    PFN_vkCmdSetEvent2 CmdSetEvent2;
+    PFN_vkCmdResetEvent2 CmdResetEvent2;
+    PFN_vkCmdWaitEvents2 CmdWaitEvents2;
     PFN_vkCmdBlitImage2 CmdBlitImage2;
     PFN_vkCmdResolveImage2 CmdResolveImage2;
     PFN_vkCmdBeginRendering CmdBeginRendering;
@@ -490,30 +529,27 @@
     PFN_vkCmdSetRasterizerDiscardEnable CmdSetRasterizerDiscardEnable;
     PFN_vkCmdSetDepthBiasEnable CmdSetDepthBiasEnable;
     PFN_vkCmdSetPrimitiveRestartEnable CmdSetPrimitiveRestartEnable;
-    PFN_vkGetDeviceBufferMemoryRequirements GetDeviceBufferMemoryRequirements;
-    PFN_vkGetDeviceImageMemoryRequirements GetDeviceImageMemoryRequirements;
-    PFN_vkGetDeviceImageSparseMemoryRequirements GetDeviceImageSparseMemoryRequirements;
 
     // ---- Core Vulkan 1.4 commands
-    PFN_vkCmdSetLineStipple CmdSetLineStipple;
     PFN_vkMapMemory2 MapMemory2;
     PFN_vkUnmapMemory2 UnmapMemory2;
-    PFN_vkCmdBindIndexBuffer2 CmdBindIndexBuffer2;
-    PFN_vkGetRenderingAreaGranularity GetRenderingAreaGranularity;
     PFN_vkGetDeviceImageSubresourceLayout GetDeviceImageSubresourceLayout;
     PFN_vkGetImageSubresourceLayout2 GetImageSubresourceLayout2;
-    PFN_vkCmdPushDescriptorSet CmdPushDescriptorSet;
-    PFN_vkCmdPushDescriptorSetWithTemplate CmdPushDescriptorSetWithTemplate;
-    PFN_vkCmdSetRenderingAttachmentLocations CmdSetRenderingAttachmentLocations;
-    PFN_vkCmdSetRenderingInputAttachmentIndices CmdSetRenderingInputAttachmentIndices;
-    PFN_vkCmdBindDescriptorSets2 CmdBindDescriptorSets2;
-    PFN_vkCmdPushConstants2 CmdPushConstants2;
-    PFN_vkCmdPushDescriptorSet2 CmdPushDescriptorSet2;
-    PFN_vkCmdPushDescriptorSetWithTemplate2 CmdPushDescriptorSetWithTemplate2;
     PFN_vkCopyMemoryToImage CopyMemoryToImage;
     PFN_vkCopyImageToMemory CopyImageToMemory;
     PFN_vkCopyImageToImage CopyImageToImage;
     PFN_vkTransitionImageLayout TransitionImageLayout;
+    PFN_vkCmdPushDescriptorSet CmdPushDescriptorSet;
+    PFN_vkCmdPushDescriptorSetWithTemplate CmdPushDescriptorSetWithTemplate;
+    PFN_vkCmdBindDescriptorSets2 CmdBindDescriptorSets2;
+    PFN_vkCmdPushConstants2 CmdPushConstants2;
+    PFN_vkCmdPushDescriptorSet2 CmdPushDescriptorSet2;
+    PFN_vkCmdPushDescriptorSetWithTemplate2 CmdPushDescriptorSetWithTemplate2;
+    PFN_vkCmdSetLineStipple CmdSetLineStipple;
+    PFN_vkCmdBindIndexBuffer2 CmdBindIndexBuffer2;
+    PFN_vkGetRenderingAreaGranularity GetRenderingAreaGranularity;
+    PFN_vkCmdSetRenderingAttachmentLocations CmdSetRenderingAttachmentLocations;
+    PFN_vkCmdSetRenderingInputAttachmentIndices CmdSetRenderingInputAttachmentIndices;
 
     // ---- VK_KHR_swapchain extension commands
     PFN_vkCreateSwapchainKHR CreateSwapchainKHR;
@@ -681,6 +717,30 @@
     PFN_vkCmdWriteTimestamp2KHR CmdWriteTimestamp2KHR;
     PFN_vkQueueSubmit2KHR QueueSubmit2KHR;
 
+    // ---- VK_KHR_device_address_commands extension commands
+    PFN_vkCmdBindIndexBuffer3KHR CmdBindIndexBuffer3KHR;
+    PFN_vkCmdBindVertexBuffers3KHR CmdBindVertexBuffers3KHR;
+    PFN_vkCmdDrawIndirect2KHR CmdDrawIndirect2KHR;
+    PFN_vkCmdDrawIndexedIndirect2KHR CmdDrawIndexedIndirect2KHR;
+    PFN_vkCmdDispatchIndirect2KHR CmdDispatchIndirect2KHR;
+    PFN_vkCmdCopyMemoryKHR CmdCopyMemoryKHR;
+    PFN_vkCmdCopyMemoryToImageKHR CmdCopyMemoryToImageKHR;
+    PFN_vkCmdCopyImageToMemoryKHR CmdCopyImageToMemoryKHR;
+    PFN_vkCmdUpdateMemoryKHR CmdUpdateMemoryKHR;
+    PFN_vkCmdFillMemoryKHR CmdFillMemoryKHR;
+    PFN_vkCmdCopyQueryPoolResultsToMemoryKHR CmdCopyQueryPoolResultsToMemoryKHR;
+    PFN_vkCmdDrawIndirectCount2KHR CmdDrawIndirectCount2KHR;
+    PFN_vkCmdDrawIndexedIndirectCount2KHR CmdDrawIndexedIndirectCount2KHR;
+    PFN_vkCmdBeginConditionalRendering2EXT CmdBeginConditionalRendering2EXT;
+    PFN_vkCmdBindTransformFeedbackBuffers2EXT CmdBindTransformFeedbackBuffers2EXT;
+    PFN_vkCmdBeginTransformFeedback2EXT CmdBeginTransformFeedback2EXT;
+    PFN_vkCmdEndTransformFeedback2EXT CmdEndTransformFeedback2EXT;
+    PFN_vkCmdDrawIndirectByteCount2EXT CmdDrawIndirectByteCount2EXT;
+    PFN_vkCmdDrawMeshTasksIndirect2EXT CmdDrawMeshTasksIndirect2EXT;
+    PFN_vkCmdDrawMeshTasksIndirectCount2EXT CmdDrawMeshTasksIndirectCount2EXT;
+    PFN_vkCmdWriteMarkerToMemoryAMD CmdWriteMarkerToMemoryAMD;
+    PFN_vkCreateAccelerationStructure2KHR CreateAccelerationStructure2KHR;
+
     // ---- VK_KHR_copy_commands2 extension commands
     PFN_vkCmdCopyBuffer2KHR CmdCopyBuffer2KHR;
     PFN_vkCmdCopyImage2KHR CmdCopyImage2KHR;
@@ -703,6 +763,9 @@
     PFN_vkGetDeviceImageSubresourceLayoutKHR GetDeviceImageSubresourceLayoutKHR;
     PFN_vkGetImageSubresourceLayout2KHR GetImageSubresourceLayout2KHR;
 
+    // ---- VK_KHR_present_wait2 extension commands
+    PFN_vkWaitForPresent2KHR WaitForPresent2KHR;
+
     // ---- VK_KHR_pipeline_binary extension commands
     PFN_vkCreatePipelineBinariesKHR CreatePipelineBinariesKHR;
     PFN_vkDestroyPipelineBinaryKHR DestroyPipelineBinaryKHR;
@@ -710,6 +773,9 @@
     PFN_vkGetPipelineBinaryDataKHR GetPipelineBinaryDataKHR;
     PFN_vkReleaseCapturedPipelineDataKHR ReleaseCapturedPipelineDataKHR;
 
+    // ---- VK_KHR_swapchain_maintenance1 extension commands
+    PFN_vkReleaseSwapchainImagesKHR ReleaseSwapchainImagesKHR;
+
     // ---- VK_KHR_line_rasterization extension commands
     PFN_vkCmdSetLineStippleKHR CmdSetLineStippleKHR;
 
@@ -724,6 +790,17 @@
     PFN_vkCmdSetDescriptorBufferOffsets2EXT CmdSetDescriptorBufferOffsets2EXT;
     PFN_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT CmdBindDescriptorBufferEmbeddedSamplers2EXT;
 
+    // ---- VK_KHR_copy_memory_indirect extension commands
+    PFN_vkCmdCopyMemoryIndirectKHR CmdCopyMemoryIndirectKHR;
+    PFN_vkCmdCopyMemoryToImageIndirectKHR CmdCopyMemoryToImageIndirectKHR;
+
+    // ---- VK_KHR_device_fault extension commands
+    PFN_vkGetDeviceFaultReportsKHR GetDeviceFaultReportsKHR;
+    PFN_vkGetDeviceFaultDebugInfoKHR GetDeviceFaultDebugInfoKHR;
+
+    // ---- VK_KHR_maintenance10 extension commands
+    PFN_vkCmdEndRendering2KHR CmdEndRendering2KHR;
+
     // ---- VK_EXT_debug_marker extension commands
     PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT;
     PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT;
@@ -750,6 +827,7 @@
     PFN_vkGetImageViewHandleNVX GetImageViewHandleNVX;
     PFN_vkGetImageViewHandle64NVX GetImageViewHandle64NVX;
     PFN_vkGetImageViewAddressNVX GetImageViewAddressNVX;
+    PFN_vkGetDeviceCombinedImageSamplerIndexNVX GetDeviceCombinedImageSamplerIndexNVX;
 
     // ---- VK_AMD_draw_indirect_count extension commands
     PFN_vkCmdDrawIndirectCountAMD CmdDrawIndirectCountAMD;
@@ -829,6 +907,17 @@
     PFN_vkCmdDispatchGraphIndirectCountAMDX CmdDispatchGraphIndirectCountAMDX;
 #endif // VK_ENABLE_BETA_EXTENSIONS
 
+    // ---- VK_EXT_descriptor_heap extension commands
+    PFN_vkWriteSamplerDescriptorsEXT WriteSamplerDescriptorsEXT;
+    PFN_vkWriteResourceDescriptorsEXT WriteResourceDescriptorsEXT;
+    PFN_vkCmdBindSamplerHeapEXT CmdBindSamplerHeapEXT;
+    PFN_vkCmdBindResourceHeapEXT CmdBindResourceHeapEXT;
+    PFN_vkCmdPushDataEXT CmdPushDataEXT;
+    PFN_vkGetImageOpaqueCaptureDataEXT GetImageOpaqueCaptureDataEXT;
+    PFN_vkRegisterCustomBorderColorEXT RegisterCustomBorderColorEXT;
+    PFN_vkUnregisterCustomBorderColorEXT UnregisterCustomBorderColorEXT;
+    PFN_vkGetTensorOpaqueCaptureDataARM GetTensorOpaqueCaptureDataARM;
+
     // ---- VK_EXT_sample_locations extension commands
     PFN_vkCmdSetSampleLocationsEXT CmdSetSampleLocationsEXT;
 
@@ -855,7 +944,11 @@
     PFN_vkCmdCopyAccelerationStructureNV CmdCopyAccelerationStructureNV;
     PFN_vkCmdTraceRaysNV CmdTraceRaysNV;
     PFN_vkCreateRayTracingPipelinesNV CreateRayTracingPipelinesNV;
+
+    // ---- VK_KHR_ray_tracing_pipeline extension commands
     PFN_vkGetRayTracingShaderGroupHandlesKHR GetRayTracingShaderGroupHandlesKHR;
+
+    // ---- VK_NV_ray_tracing extension commands
     PFN_vkGetRayTracingShaderGroupHandlesNV GetRayTracingShaderGroupHandlesNV;
     PFN_vkGetAccelerationStructureHandleNV GetAccelerationStructureHandleNV;
     PFN_vkCmdWriteAccelerationStructuresPropertiesNV CmdWriteAccelerationStructuresPropertiesNV;
@@ -885,6 +978,12 @@
     PFN_vkGetQueueCheckpointDataNV GetQueueCheckpointDataNV;
     PFN_vkGetQueueCheckpointData2NV GetQueueCheckpointData2NV;
 
+    // ---- VK_EXT_present_timing extension commands
+    PFN_vkSetSwapchainPresentTimingQueueSizeEXT SetSwapchainPresentTimingQueueSizeEXT;
+    PFN_vkGetSwapchainTimingPropertiesEXT GetSwapchainTimingPropertiesEXT;
+    PFN_vkGetSwapchainTimeDomainPropertiesEXT GetSwapchainTimeDomainPropertiesEXT;
+    PFN_vkGetPastPresentationTimingEXT GetPastPresentationTimingEXT;
+
     // ---- VK_INTEL_performance_query extension commands
     PFN_vkInitializePerformanceApiINTEL InitializePerformanceApiINTEL;
     PFN_vkUninitializePerformanceApiINTEL UninitializePerformanceApiINTEL;
@@ -960,13 +1059,33 @@
     PFN_vkSetPrivateDataEXT SetPrivateDataEXT;
     PFN_vkGetPrivateDataEXT GetPrivateDataEXT;
 
+    // ---- VK_QCOM_queue_perf_hint extension commands
+    PFN_vkQueueSetPerfHintQCOM QueueSetPerfHintQCOM;
+
     // ---- VK_NV_cuda_kernel_launch extension commands
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     PFN_vkCreateCudaModuleNV CreateCudaModuleNV;
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     PFN_vkGetCudaModuleCacheNV GetCudaModuleCacheNV;
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     PFN_vkCreateCudaFunctionNV CreateCudaFunctionNV;
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     PFN_vkDestroyCudaModuleNV DestroyCudaModuleNV;
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     PFN_vkDestroyCudaFunctionNV DestroyCudaFunctionNV;
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     PFN_vkCmdCudaLaunchKernelNV CmdCudaLaunchKernelNV;
+#endif // VK_ENABLE_BETA_EXTENSIONS
+
+    // ---- VK_QCOM_tile_shading extension commands
+    PFN_vkCmdDispatchTileQCOM CmdDispatchTileQCOM;
+    PFN_vkCmdBeginPerTileExecutionQCOM CmdBeginPerTileExecutionQCOM;
+    PFN_vkCmdEndPerTileExecutionQCOM CmdEndPerTileExecutionQCOM;
 
     // ---- VK_EXT_metal_objects extension commands
 #if defined(VK_USE_PLATFORM_METAL_EXT)
@@ -1078,6 +1197,9 @@
     // ---- VK_EXT_pageable_device_local_memory extension commands
     PFN_vkSetDeviceMemoryPriorityEXT SetDeviceMemoryPriorityEXT;
 
+    // ---- VK_ARM_scheduling_controls extension commands
+    PFN_vkCmdSetDispatchParametersARM CmdSetDispatchParametersARM;
+
     // ---- VK_VALVE_descriptor_set_host_mapping extension commands
     PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE GetDescriptorSetLayoutHostMappingInfoVALVE;
     PFN_vkGetDescriptorSetHostMappingVALVE GetDescriptorSetHostMappingVALVE;
@@ -1095,6 +1217,14 @@
     PFN_vkCmdUpdatePipelineIndirectBufferNV CmdUpdatePipelineIndirectBufferNV;
     PFN_vkGetPipelineIndirectDeviceAddressNV GetPipelineIndirectDeviceAddressNV;
 
+    // ---- VK_OHOS_external_memory extension commands
+#if defined(VK_USE_PLATFORM_OHOS)
+    PFN_vkGetNativeBufferPropertiesOHOS GetNativeBufferPropertiesOHOS;
+#endif // VK_USE_PLATFORM_OHOS
+#if defined(VK_USE_PLATFORM_OHOS)
+    PFN_vkGetMemoryNativeBufferOHOS GetMemoryNativeBufferOHOS;
+#endif // VK_USE_PLATFORM_OHOS
+
     // ---- VK_EXT_extended_dynamic_state3 extension commands
     PFN_vkCmdSetDepthClampEnableEXT CmdSetDepthClampEnableEXT;
     PFN_vkCmdSetPolygonModeEXT CmdSetPolygonModeEXT;
@@ -1128,6 +1258,18 @@
     PFN_vkCmdSetRepresentativeFragmentTestEnableNV CmdSetRepresentativeFragmentTestEnableNV;
     PFN_vkCmdSetCoverageReductionModeNV CmdSetCoverageReductionModeNV;
 
+    // ---- VK_ARM_tensors extension commands
+    PFN_vkCreateTensorARM CreateTensorARM;
+    PFN_vkDestroyTensorARM DestroyTensorARM;
+    PFN_vkCreateTensorViewARM CreateTensorViewARM;
+    PFN_vkDestroyTensorViewARM DestroyTensorViewARM;
+    PFN_vkGetTensorMemoryRequirementsARM GetTensorMemoryRequirementsARM;
+    PFN_vkBindTensorMemoryARM BindTensorMemoryARM;
+    PFN_vkGetDeviceTensorMemoryRequirementsARM GetDeviceTensorMemoryRequirementsARM;
+    PFN_vkCmdCopyTensorARM CmdCopyTensorARM;
+    PFN_vkGetTensorOpaqueCaptureDescriptorDataARM GetTensorOpaqueCaptureDescriptorDataARM;
+    PFN_vkGetTensorViewOpaqueCaptureDescriptorDataARM GetTensorViewOpaqueCaptureDescriptorDataARM;
+
     // ---- VK_EXT_shader_module_identifier extension commands
     PFN_vkGetShaderModuleIdentifierEXT GetShaderModuleIdentifierEXT;
     PFN_vkGetShaderModuleCreateInfoIdentifierEXT GetShaderModuleCreateInfoIdentifierEXT;
@@ -1152,6 +1294,10 @@
     PFN_vkGetFramebufferTilePropertiesQCOM GetFramebufferTilePropertiesQCOM;
     PFN_vkGetDynamicRenderingTilePropertiesQCOM GetDynamicRenderingTilePropertiesQCOM;
 
+    // ---- VK_NV_cooperative_vector extension commands
+    PFN_vkConvertCooperativeVectorMatrixNV ConvertCooperativeVectorMatrixNV;
+    PFN_vkCmdConvertCooperativeVectorMatrixNV CmdConvertCooperativeVectorMatrixNV;
+
     // ---- VK_NV_low_latency2 extension commands
     PFN_vkSetLatencySleepModeNV SetLatencySleepModeNV;
     PFN_vkLatencySleepNV LatencySleepNV;
@@ -1159,6 +1305,17 @@
     PFN_vkGetLatencyTimingsNV GetLatencyTimingsNV;
     PFN_vkQueueNotifyOutOfBandNV QueueNotifyOutOfBandNV;
 
+    // ---- VK_ARM_data_graph extension commands
+    PFN_vkCreateDataGraphPipelinesARM CreateDataGraphPipelinesARM;
+    PFN_vkCreateDataGraphPipelineSessionARM CreateDataGraphPipelineSessionARM;
+    PFN_vkGetDataGraphPipelineSessionBindPointRequirementsARM GetDataGraphPipelineSessionBindPointRequirementsARM;
+    PFN_vkGetDataGraphPipelineSessionMemoryRequirementsARM GetDataGraphPipelineSessionMemoryRequirementsARM;
+    PFN_vkBindDataGraphPipelineSessionMemoryARM BindDataGraphPipelineSessionMemoryARM;
+    PFN_vkDestroyDataGraphPipelineSessionARM DestroyDataGraphPipelineSessionARM;
+    PFN_vkCmdDispatchDataGraphARM CmdDispatchDataGraphARM;
+    PFN_vkGetDataGraphPipelineAvailablePropertiesARM GetDataGraphPipelineAvailablePropertiesARM;
+    PFN_vkGetDataGraphPipelinePropertiesARM GetDataGraphPipelinePropertiesARM;
+
     // ---- VK_EXT_attachment_feedback_loop_dynamic_state extension commands
     PFN_vkCmdSetAttachmentFeedbackLoopEnableEXT CmdSetAttachmentFeedbackLoopEnableEXT;
 
@@ -1167,6 +1324,26 @@
     PFN_vkGetScreenBufferPropertiesQNX GetScreenBufferPropertiesQNX;
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_QCOM_tile_memory_heap extension commands
+    PFN_vkCmdBindTileMemoryQCOM CmdBindTileMemoryQCOM;
+
+    // ---- VK_EXT_memory_decompression extension commands
+    PFN_vkCmdDecompressMemoryEXT CmdDecompressMemoryEXT;
+    PFN_vkCmdDecompressMemoryIndirectCountEXT CmdDecompressMemoryIndirectCountEXT;
+
+    // ---- VK_NV_external_compute_queue extension commands
+    PFN_vkCreateExternalComputeQueueNV CreateExternalComputeQueueNV;
+    PFN_vkDestroyExternalComputeQueueNV DestroyExternalComputeQueueNV;
+    PFN_vkGetExternalComputeQueueDataNV GetExternalComputeQueueDataNV;
+
+    // ---- VK_NV_cluster_acceleration_structure extension commands
+    PFN_vkGetClusterAccelerationStructureBuildSizesNV GetClusterAccelerationStructureBuildSizesNV;
+    PFN_vkCmdBuildClusterAccelerationStructureIndirectNV CmdBuildClusterAccelerationStructureIndirectNV;
+
+    // ---- VK_NV_partitioned_acceleration_structure extension commands
+    PFN_vkGetPartitionedAccelerationStructuresBuildSizesNV GetPartitionedAccelerationStructuresBuildSizesNV;
+    PFN_vkCmdBuildPartitionedAccelerationStructuresNV CmdBuildPartitionedAccelerationStructuresNV;
+
     // ---- VK_EXT_device_generated_commands extension commands
     PFN_vkGetGeneratedCommandsMemoryRequirementsEXT GetGeneratedCommandsMemoryRequirementsEXT;
     PFN_vkCmdPreprocessGeneratedCommandsEXT CmdPreprocessGeneratedCommandsEXT;
@@ -1178,6 +1355,34 @@
     PFN_vkUpdateIndirectExecutionSetPipelineEXT UpdateIndirectExecutionSetPipelineEXT;
     PFN_vkUpdateIndirectExecutionSetShaderEXT UpdateIndirectExecutionSetShaderEXT;
 
+    // ---- VK_EXT_external_memory_metal extension commands
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    PFN_vkGetMemoryMetalHandleEXT GetMemoryMetalHandleEXT;
+#endif // VK_USE_PLATFORM_METAL_EXT
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    PFN_vkGetMemoryMetalHandlePropertiesEXT GetMemoryMetalHandlePropertiesEXT;
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+    // ---- VK_ARM_shader_instrumentation extension commands
+    PFN_vkCreateShaderInstrumentationARM CreateShaderInstrumentationARM;
+    PFN_vkDestroyShaderInstrumentationARM DestroyShaderInstrumentationARM;
+    PFN_vkCmdBeginShaderInstrumentationARM CmdBeginShaderInstrumentationARM;
+    PFN_vkCmdEndShaderInstrumentationARM CmdEndShaderInstrumentationARM;
+    PFN_vkGetShaderInstrumentationValuesARM GetShaderInstrumentationValuesARM;
+    PFN_vkClearShaderInstrumentationMetricsARM ClearShaderInstrumentationMetricsARM;
+
+    // ---- VK_EXT_fragment_density_map_offset extension commands
+    PFN_vkCmdEndRendering2EXT CmdEndRendering2EXT;
+
+    // ---- VK_EXT_custom_resolve extension commands
+    PFN_vkCmdBeginCustomResolveEXT CmdBeginCustomResolveEXT;
+
+    // ---- VK_NV_compute_occupancy_priority extension commands
+    PFN_vkCmdSetComputeOccupancyPriorityNV CmdSetComputeOccupancyPriorityNV;
+
+    // ---- VK_EXT_primitive_restart_index extension commands
+    PFN_vkCmdSetPrimitiveRestartIndexEXT CmdSetPrimitiveRestartIndexEXT;
+
     // ---- VK_KHR_acceleration_structure extension commands
     PFN_vkCreateAccelerationStructureKHR CreateAccelerationStructureKHR;
     PFN_vkDestroyAccelerationStructureKHR DestroyAccelerationStructureKHR;
diff --git a/loader/generated/vk_loader_extensions.c b/loader/generated/vk_loader_extensions.c
index 542beef..18dacd3 100644
--- a/loader/generated/vk_loader_extensions.c
+++ b/loader/generated/vk_loader_extensions.c
@@ -2,9 +2,9 @@
 // See loader_extension_generator.py for modifications
 
 /*
- * Copyright (c) 2015-2022 The Khronos Group Inc.
- * Copyright (c) 2015-2022 Valve Corporation
- * Copyright (c) 2015-2022 LunarG, Inc.
+ * Copyright (c) 2015-2025 The Khronos Group Inc.
+ * Copyright (c) 2015-2025 Valve Corporation
+ * Copyright (c) 2015-2025 LunarG, Inc.
  * Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  * Copyright (c) 2023-2023 RasterGrid Kft.
  *
@@ -22,6 +22,7 @@
  *
  * Author: Mark Lobodzinski <mark@lunarg.com>
  * Author: Mark Young <marky@lunarg.com>
+ * Author: Charles Giessen <charles@lunarg.com>
  */
 
 // clang-format off
@@ -248,6 +249,9 @@
     LOOKUP_GIPA(DestroyDebugUtilsMessengerEXT);
     LOOKUP_GIPA(SubmitDebugUtilsMessageEXT);
 
+    // ---- VK_EXT_descriptor_heap extension commands
+    LOOKUP_GIPA(GetPhysicalDeviceDescriptorSizeEXT);
+
     // ---- VK_EXT_sample_locations extension commands
     LOOKUP_GIPA(GetPhysicalDeviceMultisamplePropertiesEXT);
 
@@ -309,12 +313,47 @@
     LOOKUP_GIPA(GetPhysicalDeviceScreenPresentationSupportQNX);
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_ARM_tensors extension commands
+    LOOKUP_GIPA(GetPhysicalDeviceExternalTensorPropertiesARM);
+
     // ---- VK_NV_optical_flow extension commands
     LOOKUP_GIPA(GetPhysicalDeviceOpticalFlowImageFormatsNV);
 
+    // ---- VK_NV_cooperative_vector extension commands
+    LOOKUP_GIPA(GetPhysicalDeviceCooperativeVectorPropertiesNV);
+
+    // ---- VK_ARM_data_graph extension commands
+    LOOKUP_GIPA(GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM);
+    LOOKUP_GIPA(GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM);
+
+    // ---- VK_ARM_data_graph_instruction_set_tosa extension commands
+    LOOKUP_GIPA(GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM);
+
+    // ---- VK_OHOS_surface extension commands
+#if defined(VK_USE_PLATFORM_OHOS)
+    LOOKUP_GIPA(CreateSurfaceOHOS);
+#endif // VK_USE_PLATFORM_OHOS
+
     // ---- VK_NV_cooperative_matrix2 extension commands
     LOOKUP_GIPA(GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV);
 
+    // ---- VK_ARM_performance_counters_by_region extension commands
+    LOOKUP_GIPA(EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM);
+
+    // ---- VK_ARM_shader_instrumentation extension commands
+    LOOKUP_GIPA(EnumeratePhysicalDeviceShaderInstrumentationMetricsARM);
+
+    // ---- VK_ARM_data_graph_optical_flow extension commands
+    LOOKUP_GIPA(GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM);
+
+    // ---- VK_SEC_ubm_surface extension commands
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    LOOKUP_GIPA(CreateUbmSurfaceSEC);
+#endif // VK_USE_PLATFORM_UBM_SEC
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    LOOKUP_GIPA(GetPhysicalDeviceUbmPresentationSupportSEC);
+#endif // VK_USE_PLATFORM_UBM_SEC
+
 #undef LOOKUP_REQUIRED_GIPA
 #undef LOOKUP_GIPA
 
@@ -355,30 +394,50 @@
     table->WaitForFences = (PFN_vkWaitForFences)gpa(dev, "vkWaitForFences");
     table->CreateSemaphore = (PFN_vkCreateSemaphore)gpa(dev, "vkCreateSemaphore");
     table->DestroySemaphore = (PFN_vkDestroySemaphore)gpa(dev, "vkDestroySemaphore");
-    table->CreateEvent = (PFN_vkCreateEvent)gpa(dev, "vkCreateEvent");
-    table->DestroyEvent = (PFN_vkDestroyEvent)gpa(dev, "vkDestroyEvent");
-    table->GetEventStatus = (PFN_vkGetEventStatus)gpa(dev, "vkGetEventStatus");
-    table->SetEvent = (PFN_vkSetEvent)gpa(dev, "vkSetEvent");
-    table->ResetEvent = (PFN_vkResetEvent)gpa(dev, "vkResetEvent");
     table->CreateQueryPool = (PFN_vkCreateQueryPool)gpa(dev, "vkCreateQueryPool");
     table->DestroyQueryPool = (PFN_vkDestroyQueryPool)gpa(dev, "vkDestroyQueryPool");
     table->GetQueryPoolResults = (PFN_vkGetQueryPoolResults)gpa(dev, "vkGetQueryPoolResults");
     table->CreateBuffer = (PFN_vkCreateBuffer)gpa(dev, "vkCreateBuffer");
     table->DestroyBuffer = (PFN_vkDestroyBuffer)gpa(dev, "vkDestroyBuffer");
-    table->CreateBufferView = (PFN_vkCreateBufferView)gpa(dev, "vkCreateBufferView");
-    table->DestroyBufferView = (PFN_vkDestroyBufferView)gpa(dev, "vkDestroyBufferView");
     table->CreateImage = (PFN_vkCreateImage)gpa(dev, "vkCreateImage");
     table->DestroyImage = (PFN_vkDestroyImage)gpa(dev, "vkDestroyImage");
     table->GetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout)gpa(dev, "vkGetImageSubresourceLayout");
     table->CreateImageView = (PFN_vkCreateImageView)gpa(dev, "vkCreateImageView");
     table->DestroyImageView = (PFN_vkDestroyImageView)gpa(dev, "vkDestroyImageView");
+    table->CreateCommandPool = (PFN_vkCreateCommandPool)gpa(dev, "vkCreateCommandPool");
+    table->DestroyCommandPool = (PFN_vkDestroyCommandPool)gpa(dev, "vkDestroyCommandPool");
+    table->ResetCommandPool = (PFN_vkResetCommandPool)gpa(dev, "vkResetCommandPool");
+    table->AllocateCommandBuffers = (PFN_vkAllocateCommandBuffers)gpa(dev, "vkAllocateCommandBuffers");
+    table->FreeCommandBuffers = (PFN_vkFreeCommandBuffers)gpa(dev, "vkFreeCommandBuffers");
+    table->BeginCommandBuffer = (PFN_vkBeginCommandBuffer)gpa(dev, "vkBeginCommandBuffer");
+    table->EndCommandBuffer = (PFN_vkEndCommandBuffer)gpa(dev, "vkEndCommandBuffer");
+    table->ResetCommandBuffer = (PFN_vkResetCommandBuffer)gpa(dev, "vkResetCommandBuffer");
+    table->CmdCopyBuffer = (PFN_vkCmdCopyBuffer)gpa(dev, "vkCmdCopyBuffer");
+    table->CmdCopyImage = (PFN_vkCmdCopyImage)gpa(dev, "vkCmdCopyImage");
+    table->CmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage)gpa(dev, "vkCmdCopyBufferToImage");
+    table->CmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer)gpa(dev, "vkCmdCopyImageToBuffer");
+    table->CmdUpdateBuffer = (PFN_vkCmdUpdateBuffer)gpa(dev, "vkCmdUpdateBuffer");
+    table->CmdFillBuffer = (PFN_vkCmdFillBuffer)gpa(dev, "vkCmdFillBuffer");
+    table->CmdPipelineBarrier = (PFN_vkCmdPipelineBarrier)gpa(dev, "vkCmdPipelineBarrier");
+    table->CmdBeginQuery = (PFN_vkCmdBeginQuery)gpa(dev, "vkCmdBeginQuery");
+    table->CmdEndQuery = (PFN_vkCmdEndQuery)gpa(dev, "vkCmdEndQuery");
+    table->CmdResetQueryPool = (PFN_vkCmdResetQueryPool)gpa(dev, "vkCmdResetQueryPool");
+    table->CmdWriteTimestamp = (PFN_vkCmdWriteTimestamp)gpa(dev, "vkCmdWriteTimestamp");
+    table->CmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults)gpa(dev, "vkCmdCopyQueryPoolResults");
+    table->CmdExecuteCommands = (PFN_vkCmdExecuteCommands)gpa(dev, "vkCmdExecuteCommands");
+    table->CreateEvent = (PFN_vkCreateEvent)gpa(dev, "vkCreateEvent");
+    table->DestroyEvent = (PFN_vkDestroyEvent)gpa(dev, "vkDestroyEvent");
+    table->GetEventStatus = (PFN_vkGetEventStatus)gpa(dev, "vkGetEventStatus");
+    table->SetEvent = (PFN_vkSetEvent)gpa(dev, "vkSetEvent");
+    table->ResetEvent = (PFN_vkResetEvent)gpa(dev, "vkResetEvent");
+    table->CreateBufferView = (PFN_vkCreateBufferView)gpa(dev, "vkCreateBufferView");
+    table->DestroyBufferView = (PFN_vkDestroyBufferView)gpa(dev, "vkDestroyBufferView");
     table->CreateShaderModule = (PFN_vkCreateShaderModule)gpa(dev, "vkCreateShaderModule");
     table->DestroyShaderModule = (PFN_vkDestroyShaderModule)gpa(dev, "vkDestroyShaderModule");
     table->CreatePipelineCache = (PFN_vkCreatePipelineCache)gpa(dev, "vkCreatePipelineCache");
     table->DestroyPipelineCache = (PFN_vkDestroyPipelineCache)gpa(dev, "vkDestroyPipelineCache");
     table->GetPipelineCacheData = (PFN_vkGetPipelineCacheData)gpa(dev, "vkGetPipelineCacheData");
     table->MergePipelineCaches = (PFN_vkMergePipelineCaches)gpa(dev, "vkMergePipelineCaches");
-    table->CreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines)gpa(dev, "vkCreateGraphicsPipelines");
     table->CreateComputePipelines = (PFN_vkCreateComputePipelines)gpa(dev, "vkCreateComputePipelines");
     table->DestroyPipeline = (PFN_vkDestroyPipeline)gpa(dev, "vkDestroyPipeline");
     table->CreatePipelineLayout = (PFN_vkCreatePipelineLayout)gpa(dev, "vkCreatePipelineLayout");
@@ -393,20 +452,21 @@
     table->AllocateDescriptorSets = (PFN_vkAllocateDescriptorSets)gpa(dev, "vkAllocateDescriptorSets");
     table->FreeDescriptorSets = (PFN_vkFreeDescriptorSets)gpa(dev, "vkFreeDescriptorSets");
     table->UpdateDescriptorSets = (PFN_vkUpdateDescriptorSets)gpa(dev, "vkUpdateDescriptorSets");
+    table->CmdBindPipeline = (PFN_vkCmdBindPipeline)gpa(dev, "vkCmdBindPipeline");
+    table->CmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets)gpa(dev, "vkCmdBindDescriptorSets");
+    table->CmdClearColorImage = (PFN_vkCmdClearColorImage)gpa(dev, "vkCmdClearColorImage");
+    table->CmdDispatch = (PFN_vkCmdDispatch)gpa(dev, "vkCmdDispatch");
+    table->CmdDispatchIndirect = (PFN_vkCmdDispatchIndirect)gpa(dev, "vkCmdDispatchIndirect");
+    table->CmdSetEvent = (PFN_vkCmdSetEvent)gpa(dev, "vkCmdSetEvent");
+    table->CmdResetEvent = (PFN_vkCmdResetEvent)gpa(dev, "vkCmdResetEvent");
+    table->CmdWaitEvents = (PFN_vkCmdWaitEvents)gpa(dev, "vkCmdWaitEvents");
+    table->CmdPushConstants = (PFN_vkCmdPushConstants)gpa(dev, "vkCmdPushConstants");
+    table->CreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines)gpa(dev, "vkCreateGraphicsPipelines");
     table->CreateFramebuffer = (PFN_vkCreateFramebuffer)gpa(dev, "vkCreateFramebuffer");
     table->DestroyFramebuffer = (PFN_vkDestroyFramebuffer)gpa(dev, "vkDestroyFramebuffer");
     table->CreateRenderPass = (PFN_vkCreateRenderPass)gpa(dev, "vkCreateRenderPass");
     table->DestroyRenderPass = (PFN_vkDestroyRenderPass)gpa(dev, "vkDestroyRenderPass");
     table->GetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity)gpa(dev, "vkGetRenderAreaGranularity");
-    table->CreateCommandPool = (PFN_vkCreateCommandPool)gpa(dev, "vkCreateCommandPool");
-    table->DestroyCommandPool = (PFN_vkDestroyCommandPool)gpa(dev, "vkDestroyCommandPool");
-    table->ResetCommandPool = (PFN_vkResetCommandPool)gpa(dev, "vkResetCommandPool");
-    table->AllocateCommandBuffers = (PFN_vkAllocateCommandBuffers)gpa(dev, "vkAllocateCommandBuffers");
-    table->FreeCommandBuffers = (PFN_vkFreeCommandBuffers)gpa(dev, "vkFreeCommandBuffers");
-    table->BeginCommandBuffer = (PFN_vkBeginCommandBuffer)gpa(dev, "vkBeginCommandBuffer");
-    table->EndCommandBuffer = (PFN_vkEndCommandBuffer)gpa(dev, "vkEndCommandBuffer");
-    table->ResetCommandBuffer = (PFN_vkResetCommandBuffer)gpa(dev, "vkResetCommandBuffer");
-    table->CmdBindPipeline = (PFN_vkCmdBindPipeline)gpa(dev, "vkCmdBindPipeline");
     table->CmdSetViewport = (PFN_vkCmdSetViewport)gpa(dev, "vkCmdSetViewport");
     table->CmdSetScissor = (PFN_vkCmdSetScissor)gpa(dev, "vkCmdSetScissor");
     table->CmdSetLineWidth = (PFN_vkCmdSetLineWidth)gpa(dev, "vkCmdSetLineWidth");
@@ -416,66 +476,39 @@
     table->CmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask)gpa(dev, "vkCmdSetStencilCompareMask");
     table->CmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask)gpa(dev, "vkCmdSetStencilWriteMask");
     table->CmdSetStencilReference = (PFN_vkCmdSetStencilReference)gpa(dev, "vkCmdSetStencilReference");
-    table->CmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets)gpa(dev, "vkCmdBindDescriptorSets");
     table->CmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer)gpa(dev, "vkCmdBindIndexBuffer");
     table->CmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers)gpa(dev, "vkCmdBindVertexBuffers");
     table->CmdDraw = (PFN_vkCmdDraw)gpa(dev, "vkCmdDraw");
     table->CmdDrawIndexed = (PFN_vkCmdDrawIndexed)gpa(dev, "vkCmdDrawIndexed");
     table->CmdDrawIndirect = (PFN_vkCmdDrawIndirect)gpa(dev, "vkCmdDrawIndirect");
     table->CmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect)gpa(dev, "vkCmdDrawIndexedIndirect");
-    table->CmdDispatch = (PFN_vkCmdDispatch)gpa(dev, "vkCmdDispatch");
-    table->CmdDispatchIndirect = (PFN_vkCmdDispatchIndirect)gpa(dev, "vkCmdDispatchIndirect");
-    table->CmdCopyBuffer = (PFN_vkCmdCopyBuffer)gpa(dev, "vkCmdCopyBuffer");
-    table->CmdCopyImage = (PFN_vkCmdCopyImage)gpa(dev, "vkCmdCopyImage");
     table->CmdBlitImage = (PFN_vkCmdBlitImage)gpa(dev, "vkCmdBlitImage");
-    table->CmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage)gpa(dev, "vkCmdCopyBufferToImage");
-    table->CmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer)gpa(dev, "vkCmdCopyImageToBuffer");
-    table->CmdUpdateBuffer = (PFN_vkCmdUpdateBuffer)gpa(dev, "vkCmdUpdateBuffer");
-    table->CmdFillBuffer = (PFN_vkCmdFillBuffer)gpa(dev, "vkCmdFillBuffer");
-    table->CmdClearColorImage = (PFN_vkCmdClearColorImage)gpa(dev, "vkCmdClearColorImage");
     table->CmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage)gpa(dev, "vkCmdClearDepthStencilImage");
     table->CmdClearAttachments = (PFN_vkCmdClearAttachments)gpa(dev, "vkCmdClearAttachments");
     table->CmdResolveImage = (PFN_vkCmdResolveImage)gpa(dev, "vkCmdResolveImage");
-    table->CmdSetEvent = (PFN_vkCmdSetEvent)gpa(dev, "vkCmdSetEvent");
-    table->CmdResetEvent = (PFN_vkCmdResetEvent)gpa(dev, "vkCmdResetEvent");
-    table->CmdWaitEvents = (PFN_vkCmdWaitEvents)gpa(dev, "vkCmdWaitEvents");
-    table->CmdPipelineBarrier = (PFN_vkCmdPipelineBarrier)gpa(dev, "vkCmdPipelineBarrier");
-    table->CmdBeginQuery = (PFN_vkCmdBeginQuery)gpa(dev, "vkCmdBeginQuery");
-    table->CmdEndQuery = (PFN_vkCmdEndQuery)gpa(dev, "vkCmdEndQuery");
-    table->CmdResetQueryPool = (PFN_vkCmdResetQueryPool)gpa(dev, "vkCmdResetQueryPool");
-    table->CmdWriteTimestamp = (PFN_vkCmdWriteTimestamp)gpa(dev, "vkCmdWriteTimestamp");
-    table->CmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults)gpa(dev, "vkCmdCopyQueryPoolResults");
-    table->CmdPushConstants = (PFN_vkCmdPushConstants)gpa(dev, "vkCmdPushConstants");
     table->CmdBeginRenderPass = (PFN_vkCmdBeginRenderPass)gpa(dev, "vkCmdBeginRenderPass");
     table->CmdNextSubpass = (PFN_vkCmdNextSubpass)gpa(dev, "vkCmdNextSubpass");
     table->CmdEndRenderPass = (PFN_vkCmdEndRenderPass)gpa(dev, "vkCmdEndRenderPass");
-    table->CmdExecuteCommands = (PFN_vkCmdExecuteCommands)gpa(dev, "vkCmdExecuteCommands");
 
     // ---- Core Vulkan 1.1 commands
     table->BindBufferMemory2 = (PFN_vkBindBufferMemory2)gpa(dev, "vkBindBufferMemory2");
     table->BindImageMemory2 = (PFN_vkBindImageMemory2)gpa(dev, "vkBindImageMemory2");
     table->GetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures)gpa(dev, "vkGetDeviceGroupPeerMemoryFeatures");
     table->CmdSetDeviceMask = (PFN_vkCmdSetDeviceMask)gpa(dev, "vkCmdSetDeviceMask");
-    table->CmdDispatchBase = (PFN_vkCmdDispatchBase)gpa(dev, "vkCmdDispatchBase");
     table->GetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2)gpa(dev, "vkGetImageMemoryRequirements2");
     table->GetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2)gpa(dev, "vkGetBufferMemoryRequirements2");
     table->GetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2)gpa(dev, "vkGetImageSparseMemoryRequirements2");
     table->TrimCommandPool = (PFN_vkTrimCommandPool)gpa(dev, "vkTrimCommandPool");
     table->GetDeviceQueue2 = (PFN_vkGetDeviceQueue2)gpa(dev, "vkGetDeviceQueue2");
-    table->CreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)gpa(dev, "vkCreateSamplerYcbcrConversion");
-    table->DestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion)gpa(dev, "vkDestroySamplerYcbcrConversion");
+    table->CmdDispatchBase = (PFN_vkCmdDispatchBase)gpa(dev, "vkCmdDispatchBase");
     table->CreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate)gpa(dev, "vkCreateDescriptorUpdateTemplate");
     table->DestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate)gpa(dev, "vkDestroyDescriptorUpdateTemplate");
     table->UpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate)gpa(dev, "vkUpdateDescriptorSetWithTemplate");
     table->GetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport)gpa(dev, "vkGetDescriptorSetLayoutSupport");
+    table->CreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)gpa(dev, "vkCreateSamplerYcbcrConversion");
+    table->DestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion)gpa(dev, "vkDestroySamplerYcbcrConversion");
 
     // ---- Core Vulkan 1.2 commands
-    table->CmdDrawIndirectCount = (PFN_vkCmdDrawIndirectCount)gpa(dev, "vkCmdDrawIndirectCount");
-    table->CmdDrawIndexedIndirectCount = (PFN_vkCmdDrawIndexedIndirectCount)gpa(dev, "vkCmdDrawIndexedIndirectCount");
-    table->CreateRenderPass2 = (PFN_vkCreateRenderPass2)gpa(dev, "vkCreateRenderPass2");
-    table->CmdBeginRenderPass2 = (PFN_vkCmdBeginRenderPass2)gpa(dev, "vkCmdBeginRenderPass2");
-    table->CmdNextSubpass2 = (PFN_vkCmdNextSubpass2)gpa(dev, "vkCmdNextSubpass2");
-    table->CmdEndRenderPass2 = (PFN_vkCmdEndRenderPass2)gpa(dev, "vkCmdEndRenderPass2");
     table->ResetQueryPool = (PFN_vkResetQueryPool)gpa(dev, "vkResetQueryPool");
     table->GetSemaphoreCounterValue = (PFN_vkGetSemaphoreCounterValue)gpa(dev, "vkGetSemaphoreCounterValue");
     table->WaitSemaphores = (PFN_vkWaitSemaphores)gpa(dev, "vkWaitSemaphores");
@@ -483,15 +516,18 @@
     table->GetBufferDeviceAddress = (PFN_vkGetBufferDeviceAddress)gpa(dev, "vkGetBufferDeviceAddress");
     table->GetBufferOpaqueCaptureAddress = (PFN_vkGetBufferOpaqueCaptureAddress)gpa(dev, "vkGetBufferOpaqueCaptureAddress");
     table->GetDeviceMemoryOpaqueCaptureAddress = (PFN_vkGetDeviceMemoryOpaqueCaptureAddress)gpa(dev, "vkGetDeviceMemoryOpaqueCaptureAddress");
+    table->CmdDrawIndirectCount = (PFN_vkCmdDrawIndirectCount)gpa(dev, "vkCmdDrawIndirectCount");
+    table->CmdDrawIndexedIndirectCount = (PFN_vkCmdDrawIndexedIndirectCount)gpa(dev, "vkCmdDrawIndexedIndirectCount");
+    table->CreateRenderPass2 = (PFN_vkCreateRenderPass2)gpa(dev, "vkCreateRenderPass2");
+    table->CmdBeginRenderPass2 = (PFN_vkCmdBeginRenderPass2)gpa(dev, "vkCmdBeginRenderPass2");
+    table->CmdNextSubpass2 = (PFN_vkCmdNextSubpass2)gpa(dev, "vkCmdNextSubpass2");
+    table->CmdEndRenderPass2 = (PFN_vkCmdEndRenderPass2)gpa(dev, "vkCmdEndRenderPass2");
 
     // ---- Core Vulkan 1.3 commands
     table->CreatePrivateDataSlot = (PFN_vkCreatePrivateDataSlot)gpa(dev, "vkCreatePrivateDataSlot");
     table->DestroyPrivateDataSlot = (PFN_vkDestroyPrivateDataSlot)gpa(dev, "vkDestroyPrivateDataSlot");
     table->SetPrivateData = (PFN_vkSetPrivateData)gpa(dev, "vkSetPrivateData");
     table->GetPrivateData = (PFN_vkGetPrivateData)gpa(dev, "vkGetPrivateData");
-    table->CmdSetEvent2 = (PFN_vkCmdSetEvent2)gpa(dev, "vkCmdSetEvent2");
-    table->CmdResetEvent2 = (PFN_vkCmdResetEvent2)gpa(dev, "vkCmdResetEvent2");
-    table->CmdWaitEvents2 = (PFN_vkCmdWaitEvents2)gpa(dev, "vkCmdWaitEvents2");
     table->CmdPipelineBarrier2 = (PFN_vkCmdPipelineBarrier2)gpa(dev, "vkCmdPipelineBarrier2");
     table->CmdWriteTimestamp2 = (PFN_vkCmdWriteTimestamp2)gpa(dev, "vkCmdWriteTimestamp2");
     table->QueueSubmit2 = (PFN_vkQueueSubmit2)gpa(dev, "vkQueueSubmit2");
@@ -499,6 +535,12 @@
     table->CmdCopyImage2 = (PFN_vkCmdCopyImage2)gpa(dev, "vkCmdCopyImage2");
     table->CmdCopyBufferToImage2 = (PFN_vkCmdCopyBufferToImage2)gpa(dev, "vkCmdCopyBufferToImage2");
     table->CmdCopyImageToBuffer2 = (PFN_vkCmdCopyImageToBuffer2)gpa(dev, "vkCmdCopyImageToBuffer2");
+    table->GetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements)gpa(dev, "vkGetDeviceBufferMemoryRequirements");
+    table->GetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements)gpa(dev, "vkGetDeviceImageMemoryRequirements");
+    table->GetDeviceImageSparseMemoryRequirements = (PFN_vkGetDeviceImageSparseMemoryRequirements)gpa(dev, "vkGetDeviceImageSparseMemoryRequirements");
+    table->CmdSetEvent2 = (PFN_vkCmdSetEvent2)gpa(dev, "vkCmdSetEvent2");
+    table->CmdResetEvent2 = (PFN_vkCmdResetEvent2)gpa(dev, "vkCmdResetEvent2");
+    table->CmdWaitEvents2 = (PFN_vkCmdWaitEvents2)gpa(dev, "vkCmdWaitEvents2");
     table->CmdBlitImage2 = (PFN_vkCmdBlitImage2)gpa(dev, "vkCmdBlitImage2");
     table->CmdResolveImage2 = (PFN_vkCmdResolveImage2)gpa(dev, "vkCmdResolveImage2");
     table->CmdBeginRendering = (PFN_vkCmdBeginRendering)gpa(dev, "vkCmdBeginRendering");
@@ -518,30 +560,27 @@
     table->CmdSetRasterizerDiscardEnable = (PFN_vkCmdSetRasterizerDiscardEnable)gpa(dev, "vkCmdSetRasterizerDiscardEnable");
     table->CmdSetDepthBiasEnable = (PFN_vkCmdSetDepthBiasEnable)gpa(dev, "vkCmdSetDepthBiasEnable");
     table->CmdSetPrimitiveRestartEnable = (PFN_vkCmdSetPrimitiveRestartEnable)gpa(dev, "vkCmdSetPrimitiveRestartEnable");
-    table->GetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements)gpa(dev, "vkGetDeviceBufferMemoryRequirements");
-    table->GetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements)gpa(dev, "vkGetDeviceImageMemoryRequirements");
-    table->GetDeviceImageSparseMemoryRequirements = (PFN_vkGetDeviceImageSparseMemoryRequirements)gpa(dev, "vkGetDeviceImageSparseMemoryRequirements");
 
     // ---- Core Vulkan 1.4 commands
-    table->CmdSetLineStipple = (PFN_vkCmdSetLineStipple)gpa(dev, "vkCmdSetLineStipple");
     table->MapMemory2 = (PFN_vkMapMemory2)gpa(dev, "vkMapMemory2");
     table->UnmapMemory2 = (PFN_vkUnmapMemory2)gpa(dev, "vkUnmapMemory2");
-    table->CmdBindIndexBuffer2 = (PFN_vkCmdBindIndexBuffer2)gpa(dev, "vkCmdBindIndexBuffer2");
-    table->GetRenderingAreaGranularity = (PFN_vkGetRenderingAreaGranularity)gpa(dev, "vkGetRenderingAreaGranularity");
     table->GetDeviceImageSubresourceLayout = (PFN_vkGetDeviceImageSubresourceLayout)gpa(dev, "vkGetDeviceImageSubresourceLayout");
     table->GetImageSubresourceLayout2 = (PFN_vkGetImageSubresourceLayout2)gpa(dev, "vkGetImageSubresourceLayout2");
-    table->CmdPushDescriptorSet = (PFN_vkCmdPushDescriptorSet)gpa(dev, "vkCmdPushDescriptorSet");
-    table->CmdPushDescriptorSetWithTemplate = (PFN_vkCmdPushDescriptorSetWithTemplate)gpa(dev, "vkCmdPushDescriptorSetWithTemplate");
-    table->CmdSetRenderingAttachmentLocations = (PFN_vkCmdSetRenderingAttachmentLocations)gpa(dev, "vkCmdSetRenderingAttachmentLocations");
-    table->CmdSetRenderingInputAttachmentIndices = (PFN_vkCmdSetRenderingInputAttachmentIndices)gpa(dev, "vkCmdSetRenderingInputAttachmentIndices");
-    table->CmdBindDescriptorSets2 = (PFN_vkCmdBindDescriptorSets2)gpa(dev, "vkCmdBindDescriptorSets2");
-    table->CmdPushConstants2 = (PFN_vkCmdPushConstants2)gpa(dev, "vkCmdPushConstants2");
-    table->CmdPushDescriptorSet2 = (PFN_vkCmdPushDescriptorSet2)gpa(dev, "vkCmdPushDescriptorSet2");
-    table->CmdPushDescriptorSetWithTemplate2 = (PFN_vkCmdPushDescriptorSetWithTemplate2)gpa(dev, "vkCmdPushDescriptorSetWithTemplate2");
     table->CopyMemoryToImage = (PFN_vkCopyMemoryToImage)gpa(dev, "vkCopyMemoryToImage");
     table->CopyImageToMemory = (PFN_vkCopyImageToMemory)gpa(dev, "vkCopyImageToMemory");
     table->CopyImageToImage = (PFN_vkCopyImageToImage)gpa(dev, "vkCopyImageToImage");
     table->TransitionImageLayout = (PFN_vkTransitionImageLayout)gpa(dev, "vkTransitionImageLayout");
+    table->CmdPushDescriptorSet = (PFN_vkCmdPushDescriptorSet)gpa(dev, "vkCmdPushDescriptorSet");
+    table->CmdPushDescriptorSetWithTemplate = (PFN_vkCmdPushDescriptorSetWithTemplate)gpa(dev, "vkCmdPushDescriptorSetWithTemplate");
+    table->CmdBindDescriptorSets2 = (PFN_vkCmdBindDescriptorSets2)gpa(dev, "vkCmdBindDescriptorSets2");
+    table->CmdPushConstants2 = (PFN_vkCmdPushConstants2)gpa(dev, "vkCmdPushConstants2");
+    table->CmdPushDescriptorSet2 = (PFN_vkCmdPushDescriptorSet2)gpa(dev, "vkCmdPushDescriptorSet2");
+    table->CmdPushDescriptorSetWithTemplate2 = (PFN_vkCmdPushDescriptorSetWithTemplate2)gpa(dev, "vkCmdPushDescriptorSetWithTemplate2");
+    table->CmdSetLineStipple = (PFN_vkCmdSetLineStipple)gpa(dev, "vkCmdSetLineStipple");
+    table->CmdBindIndexBuffer2 = (PFN_vkCmdBindIndexBuffer2)gpa(dev, "vkCmdBindIndexBuffer2");
+    table->GetRenderingAreaGranularity = (PFN_vkGetRenderingAreaGranularity)gpa(dev, "vkGetRenderingAreaGranularity");
+    table->CmdSetRenderingAttachmentLocations = (PFN_vkCmdSetRenderingAttachmentLocations)gpa(dev, "vkCmdSetRenderingAttachmentLocations");
+    table->CmdSetRenderingInputAttachmentIndices = (PFN_vkCmdSetRenderingInputAttachmentIndices)gpa(dev, "vkCmdSetRenderingInputAttachmentIndices");
 }
 
 // Init Device function pointer dispatch table with extension commands
@@ -719,6 +758,30 @@
     table->CmdWriteTimestamp2KHR = (PFN_vkCmdWriteTimestamp2KHR)gdpa(dev, "vkCmdWriteTimestamp2KHR");
     table->QueueSubmit2KHR = (PFN_vkQueueSubmit2KHR)gdpa(dev, "vkQueueSubmit2KHR");
 
+    // ---- VK_KHR_device_address_commands extension commands
+    table->CmdBindIndexBuffer3KHR = (PFN_vkCmdBindIndexBuffer3KHR)gdpa(dev, "vkCmdBindIndexBuffer3KHR");
+    table->CmdBindVertexBuffers3KHR = (PFN_vkCmdBindVertexBuffers3KHR)gdpa(dev, "vkCmdBindVertexBuffers3KHR");
+    table->CmdDrawIndirect2KHR = (PFN_vkCmdDrawIndirect2KHR)gdpa(dev, "vkCmdDrawIndirect2KHR");
+    table->CmdDrawIndexedIndirect2KHR = (PFN_vkCmdDrawIndexedIndirect2KHR)gdpa(dev, "vkCmdDrawIndexedIndirect2KHR");
+    table->CmdDispatchIndirect2KHR = (PFN_vkCmdDispatchIndirect2KHR)gdpa(dev, "vkCmdDispatchIndirect2KHR");
+    table->CmdCopyMemoryKHR = (PFN_vkCmdCopyMemoryKHR)gdpa(dev, "vkCmdCopyMemoryKHR");
+    table->CmdCopyMemoryToImageKHR = (PFN_vkCmdCopyMemoryToImageKHR)gdpa(dev, "vkCmdCopyMemoryToImageKHR");
+    table->CmdCopyImageToMemoryKHR = (PFN_vkCmdCopyImageToMemoryKHR)gdpa(dev, "vkCmdCopyImageToMemoryKHR");
+    table->CmdUpdateMemoryKHR = (PFN_vkCmdUpdateMemoryKHR)gdpa(dev, "vkCmdUpdateMemoryKHR");
+    table->CmdFillMemoryKHR = (PFN_vkCmdFillMemoryKHR)gdpa(dev, "vkCmdFillMemoryKHR");
+    table->CmdCopyQueryPoolResultsToMemoryKHR = (PFN_vkCmdCopyQueryPoolResultsToMemoryKHR)gdpa(dev, "vkCmdCopyQueryPoolResultsToMemoryKHR");
+    table->CmdDrawIndirectCount2KHR = (PFN_vkCmdDrawIndirectCount2KHR)gdpa(dev, "vkCmdDrawIndirectCount2KHR");
+    table->CmdDrawIndexedIndirectCount2KHR = (PFN_vkCmdDrawIndexedIndirectCount2KHR)gdpa(dev, "vkCmdDrawIndexedIndirectCount2KHR");
+    table->CmdBeginConditionalRendering2EXT = (PFN_vkCmdBeginConditionalRendering2EXT)gdpa(dev, "vkCmdBeginConditionalRendering2EXT");
+    table->CmdBindTransformFeedbackBuffers2EXT = (PFN_vkCmdBindTransformFeedbackBuffers2EXT)gdpa(dev, "vkCmdBindTransformFeedbackBuffers2EXT");
+    table->CmdBeginTransformFeedback2EXT = (PFN_vkCmdBeginTransformFeedback2EXT)gdpa(dev, "vkCmdBeginTransformFeedback2EXT");
+    table->CmdEndTransformFeedback2EXT = (PFN_vkCmdEndTransformFeedback2EXT)gdpa(dev, "vkCmdEndTransformFeedback2EXT");
+    table->CmdDrawIndirectByteCount2EXT = (PFN_vkCmdDrawIndirectByteCount2EXT)gdpa(dev, "vkCmdDrawIndirectByteCount2EXT");
+    table->CmdDrawMeshTasksIndirect2EXT = (PFN_vkCmdDrawMeshTasksIndirect2EXT)gdpa(dev, "vkCmdDrawMeshTasksIndirect2EXT");
+    table->CmdDrawMeshTasksIndirectCount2EXT = (PFN_vkCmdDrawMeshTasksIndirectCount2EXT)gdpa(dev, "vkCmdDrawMeshTasksIndirectCount2EXT");
+    table->CmdWriteMarkerToMemoryAMD = (PFN_vkCmdWriteMarkerToMemoryAMD)gdpa(dev, "vkCmdWriteMarkerToMemoryAMD");
+    table->CreateAccelerationStructure2KHR = (PFN_vkCreateAccelerationStructure2KHR)gdpa(dev, "vkCreateAccelerationStructure2KHR");
+
     // ---- VK_KHR_copy_commands2 extension commands
     table->CmdCopyBuffer2KHR = (PFN_vkCmdCopyBuffer2KHR)gdpa(dev, "vkCmdCopyBuffer2KHR");
     table->CmdCopyImage2KHR = (PFN_vkCmdCopyImage2KHR)gdpa(dev, "vkCmdCopyImage2KHR");
@@ -741,6 +804,9 @@
     table->GetDeviceImageSubresourceLayoutKHR = (PFN_vkGetDeviceImageSubresourceLayoutKHR)gdpa(dev, "vkGetDeviceImageSubresourceLayoutKHR");
     table->GetImageSubresourceLayout2KHR = (PFN_vkGetImageSubresourceLayout2KHR)gdpa(dev, "vkGetImageSubresourceLayout2KHR");
 
+    // ---- VK_KHR_present_wait2 extension commands
+    table->WaitForPresent2KHR = (PFN_vkWaitForPresent2KHR)gdpa(dev, "vkWaitForPresent2KHR");
+
     // ---- VK_KHR_pipeline_binary extension commands
     table->CreatePipelineBinariesKHR = (PFN_vkCreatePipelineBinariesKHR)gdpa(dev, "vkCreatePipelineBinariesKHR");
     table->DestroyPipelineBinaryKHR = (PFN_vkDestroyPipelineBinaryKHR)gdpa(dev, "vkDestroyPipelineBinaryKHR");
@@ -748,6 +814,9 @@
     table->GetPipelineBinaryDataKHR = (PFN_vkGetPipelineBinaryDataKHR)gdpa(dev, "vkGetPipelineBinaryDataKHR");
     table->ReleaseCapturedPipelineDataKHR = (PFN_vkReleaseCapturedPipelineDataKHR)gdpa(dev, "vkReleaseCapturedPipelineDataKHR");
 
+    // ---- VK_KHR_swapchain_maintenance1 extension commands
+    table->ReleaseSwapchainImagesKHR = (PFN_vkReleaseSwapchainImagesKHR)gdpa(dev, "vkReleaseSwapchainImagesKHR");
+
     // ---- VK_KHR_line_rasterization extension commands
     table->CmdSetLineStippleKHR = (PFN_vkCmdSetLineStippleKHR)gdpa(dev, "vkCmdSetLineStippleKHR");
 
@@ -762,6 +831,17 @@
     table->CmdSetDescriptorBufferOffsets2EXT = (PFN_vkCmdSetDescriptorBufferOffsets2EXT)gdpa(dev, "vkCmdSetDescriptorBufferOffsets2EXT");
     table->CmdBindDescriptorBufferEmbeddedSamplers2EXT = (PFN_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT)gdpa(dev, "vkCmdBindDescriptorBufferEmbeddedSamplers2EXT");
 
+    // ---- VK_KHR_copy_memory_indirect extension commands
+    table->CmdCopyMemoryIndirectKHR = (PFN_vkCmdCopyMemoryIndirectKHR)gdpa(dev, "vkCmdCopyMemoryIndirectKHR");
+    table->CmdCopyMemoryToImageIndirectKHR = (PFN_vkCmdCopyMemoryToImageIndirectKHR)gdpa(dev, "vkCmdCopyMemoryToImageIndirectKHR");
+
+    // ---- VK_KHR_device_fault extension commands
+    table->GetDeviceFaultReportsKHR = (PFN_vkGetDeviceFaultReportsKHR)gdpa(dev, "vkGetDeviceFaultReportsKHR");
+    table->GetDeviceFaultDebugInfoKHR = (PFN_vkGetDeviceFaultDebugInfoKHR)gdpa(dev, "vkGetDeviceFaultDebugInfoKHR");
+
+    // ---- VK_KHR_maintenance10 extension commands
+    table->CmdEndRendering2KHR = (PFN_vkCmdEndRendering2KHR)gdpa(dev, "vkCmdEndRendering2KHR");
+
     // ---- VK_EXT_debug_marker extension commands
     table->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)gdpa(dev, "vkDebugMarkerSetObjectTagEXT");
     table->DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)gdpa(dev, "vkDebugMarkerSetObjectNameEXT");
@@ -788,6 +868,7 @@
     table->GetImageViewHandleNVX = (PFN_vkGetImageViewHandleNVX)gdpa(dev, "vkGetImageViewHandleNVX");
     table->GetImageViewHandle64NVX = (PFN_vkGetImageViewHandle64NVX)gdpa(dev, "vkGetImageViewHandle64NVX");
     table->GetImageViewAddressNVX = (PFN_vkGetImageViewAddressNVX)gdpa(dev, "vkGetImageViewAddressNVX");
+    table->GetDeviceCombinedImageSamplerIndexNVX = (PFN_vkGetDeviceCombinedImageSamplerIndexNVX)gdpa(dev, "vkGetDeviceCombinedImageSamplerIndexNVX");
 
     // ---- VK_AMD_draw_indirect_count extension commands
     table->CmdDrawIndirectCountAMD = (PFN_vkCmdDrawIndirectCountAMD)gdpa(dev, "vkCmdDrawIndirectCountAMD");
@@ -867,6 +948,17 @@
     table->CmdDispatchGraphIndirectCountAMDX = (PFN_vkCmdDispatchGraphIndirectCountAMDX)gdpa(dev, "vkCmdDispatchGraphIndirectCountAMDX");
 #endif // VK_ENABLE_BETA_EXTENSIONS
 
+    // ---- VK_EXT_descriptor_heap extension commands
+    table->WriteSamplerDescriptorsEXT = (PFN_vkWriteSamplerDescriptorsEXT)gdpa(dev, "vkWriteSamplerDescriptorsEXT");
+    table->WriteResourceDescriptorsEXT = (PFN_vkWriteResourceDescriptorsEXT)gdpa(dev, "vkWriteResourceDescriptorsEXT");
+    table->CmdBindSamplerHeapEXT = (PFN_vkCmdBindSamplerHeapEXT)gdpa(dev, "vkCmdBindSamplerHeapEXT");
+    table->CmdBindResourceHeapEXT = (PFN_vkCmdBindResourceHeapEXT)gdpa(dev, "vkCmdBindResourceHeapEXT");
+    table->CmdPushDataEXT = (PFN_vkCmdPushDataEXT)gdpa(dev, "vkCmdPushDataEXT");
+    table->GetImageOpaqueCaptureDataEXT = (PFN_vkGetImageOpaqueCaptureDataEXT)gdpa(dev, "vkGetImageOpaqueCaptureDataEXT");
+    table->RegisterCustomBorderColorEXT = (PFN_vkRegisterCustomBorderColorEXT)gdpa(dev, "vkRegisterCustomBorderColorEXT");
+    table->UnregisterCustomBorderColorEXT = (PFN_vkUnregisterCustomBorderColorEXT)gdpa(dev, "vkUnregisterCustomBorderColorEXT");
+    table->GetTensorOpaqueCaptureDataARM = (PFN_vkGetTensorOpaqueCaptureDataARM)gdpa(dev, "vkGetTensorOpaqueCaptureDataARM");
+
     // ---- VK_EXT_sample_locations extension commands
     table->CmdSetSampleLocationsEXT = (PFN_vkCmdSetSampleLocationsEXT)gdpa(dev, "vkCmdSetSampleLocationsEXT");
 
@@ -893,7 +985,11 @@
     table->CmdCopyAccelerationStructureNV = (PFN_vkCmdCopyAccelerationStructureNV)gdpa(dev, "vkCmdCopyAccelerationStructureNV");
     table->CmdTraceRaysNV = (PFN_vkCmdTraceRaysNV)gdpa(dev, "vkCmdTraceRaysNV");
     table->CreateRayTracingPipelinesNV = (PFN_vkCreateRayTracingPipelinesNV)gdpa(dev, "vkCreateRayTracingPipelinesNV");
+
+    // ---- VK_KHR_ray_tracing_pipeline extension commands
     table->GetRayTracingShaderGroupHandlesKHR = (PFN_vkGetRayTracingShaderGroupHandlesKHR)gdpa(dev, "vkGetRayTracingShaderGroupHandlesKHR");
+
+    // ---- VK_NV_ray_tracing extension commands
     table->GetRayTracingShaderGroupHandlesNV = (PFN_vkGetRayTracingShaderGroupHandlesNV)gdpa(dev, "vkGetRayTracingShaderGroupHandlesNV");
     table->GetAccelerationStructureHandleNV = (PFN_vkGetAccelerationStructureHandleNV)gdpa(dev, "vkGetAccelerationStructureHandleNV");
     table->CmdWriteAccelerationStructuresPropertiesNV = (PFN_vkCmdWriteAccelerationStructuresPropertiesNV)gdpa(dev, "vkCmdWriteAccelerationStructuresPropertiesNV");
@@ -923,6 +1019,12 @@
     table->GetQueueCheckpointDataNV = (PFN_vkGetQueueCheckpointDataNV)gdpa(dev, "vkGetQueueCheckpointDataNV");
     table->GetQueueCheckpointData2NV = (PFN_vkGetQueueCheckpointData2NV)gdpa(dev, "vkGetQueueCheckpointData2NV");
 
+    // ---- VK_EXT_present_timing extension commands
+    table->SetSwapchainPresentTimingQueueSizeEXT = (PFN_vkSetSwapchainPresentTimingQueueSizeEXT)gdpa(dev, "vkSetSwapchainPresentTimingQueueSizeEXT");
+    table->GetSwapchainTimingPropertiesEXT = (PFN_vkGetSwapchainTimingPropertiesEXT)gdpa(dev, "vkGetSwapchainTimingPropertiesEXT");
+    table->GetSwapchainTimeDomainPropertiesEXT = (PFN_vkGetSwapchainTimeDomainPropertiesEXT)gdpa(dev, "vkGetSwapchainTimeDomainPropertiesEXT");
+    table->GetPastPresentationTimingEXT = (PFN_vkGetPastPresentationTimingEXT)gdpa(dev, "vkGetPastPresentationTimingEXT");
+
     // ---- VK_INTEL_performance_query extension commands
     table->InitializePerformanceApiINTEL = (PFN_vkInitializePerformanceApiINTEL)gdpa(dev, "vkInitializePerformanceApiINTEL");
     table->UninitializePerformanceApiINTEL = (PFN_vkUninitializePerformanceApiINTEL)gdpa(dev, "vkUninitializePerformanceApiINTEL");
@@ -998,13 +1100,33 @@
     table->SetPrivateDataEXT = (PFN_vkSetPrivateDataEXT)gdpa(dev, "vkSetPrivateDataEXT");
     table->GetPrivateDataEXT = (PFN_vkGetPrivateDataEXT)gdpa(dev, "vkGetPrivateDataEXT");
 
+    // ---- VK_QCOM_queue_perf_hint extension commands
+    table->QueueSetPerfHintQCOM = (PFN_vkQueueSetPerfHintQCOM)gdpa(dev, "vkQueueSetPerfHintQCOM");
+
     // ---- VK_NV_cuda_kernel_launch extension commands
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     table->CreateCudaModuleNV = (PFN_vkCreateCudaModuleNV)gdpa(dev, "vkCreateCudaModuleNV");
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     table->GetCudaModuleCacheNV = (PFN_vkGetCudaModuleCacheNV)gdpa(dev, "vkGetCudaModuleCacheNV");
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     table->CreateCudaFunctionNV = (PFN_vkCreateCudaFunctionNV)gdpa(dev, "vkCreateCudaFunctionNV");
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     table->DestroyCudaModuleNV = (PFN_vkDestroyCudaModuleNV)gdpa(dev, "vkDestroyCudaModuleNV");
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     table->DestroyCudaFunctionNV = (PFN_vkDestroyCudaFunctionNV)gdpa(dev, "vkDestroyCudaFunctionNV");
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     table->CmdCudaLaunchKernelNV = (PFN_vkCmdCudaLaunchKernelNV)gdpa(dev, "vkCmdCudaLaunchKernelNV");
+#endif // VK_ENABLE_BETA_EXTENSIONS
+
+    // ---- VK_QCOM_tile_shading extension commands
+    table->CmdDispatchTileQCOM = (PFN_vkCmdDispatchTileQCOM)gdpa(dev, "vkCmdDispatchTileQCOM");
+    table->CmdBeginPerTileExecutionQCOM = (PFN_vkCmdBeginPerTileExecutionQCOM)gdpa(dev, "vkCmdBeginPerTileExecutionQCOM");
+    table->CmdEndPerTileExecutionQCOM = (PFN_vkCmdEndPerTileExecutionQCOM)gdpa(dev, "vkCmdEndPerTileExecutionQCOM");
 
     // ---- VK_EXT_metal_objects extension commands
 #if defined(VK_USE_PLATFORM_METAL_EXT)
@@ -1116,6 +1238,9 @@
     // ---- VK_EXT_pageable_device_local_memory extension commands
     table->SetDeviceMemoryPriorityEXT = (PFN_vkSetDeviceMemoryPriorityEXT)gdpa(dev, "vkSetDeviceMemoryPriorityEXT");
 
+    // ---- VK_ARM_scheduling_controls extension commands
+    table->CmdSetDispatchParametersARM = (PFN_vkCmdSetDispatchParametersARM)gdpa(dev, "vkCmdSetDispatchParametersARM");
+
     // ---- VK_VALVE_descriptor_set_host_mapping extension commands
     table->GetDescriptorSetLayoutHostMappingInfoVALVE = (PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE)gdpa(dev, "vkGetDescriptorSetLayoutHostMappingInfoVALVE");
     table->GetDescriptorSetHostMappingVALVE = (PFN_vkGetDescriptorSetHostMappingVALVE)gdpa(dev, "vkGetDescriptorSetHostMappingVALVE");
@@ -1133,6 +1258,14 @@
     table->CmdUpdatePipelineIndirectBufferNV = (PFN_vkCmdUpdatePipelineIndirectBufferNV)gdpa(dev, "vkCmdUpdatePipelineIndirectBufferNV");
     table->GetPipelineIndirectDeviceAddressNV = (PFN_vkGetPipelineIndirectDeviceAddressNV)gdpa(dev, "vkGetPipelineIndirectDeviceAddressNV");
 
+    // ---- VK_OHOS_external_memory extension commands
+#if defined(VK_USE_PLATFORM_OHOS)
+    table->GetNativeBufferPropertiesOHOS = (PFN_vkGetNativeBufferPropertiesOHOS)gdpa(dev, "vkGetNativeBufferPropertiesOHOS");
+#endif // VK_USE_PLATFORM_OHOS
+#if defined(VK_USE_PLATFORM_OHOS)
+    table->GetMemoryNativeBufferOHOS = (PFN_vkGetMemoryNativeBufferOHOS)gdpa(dev, "vkGetMemoryNativeBufferOHOS");
+#endif // VK_USE_PLATFORM_OHOS
+
     // ---- VK_EXT_extended_dynamic_state3 extension commands
     table->CmdSetDepthClampEnableEXT = (PFN_vkCmdSetDepthClampEnableEXT)gdpa(dev, "vkCmdSetDepthClampEnableEXT");
     table->CmdSetPolygonModeEXT = (PFN_vkCmdSetPolygonModeEXT)gdpa(dev, "vkCmdSetPolygonModeEXT");
@@ -1166,6 +1299,18 @@
     table->CmdSetRepresentativeFragmentTestEnableNV = (PFN_vkCmdSetRepresentativeFragmentTestEnableNV)gdpa(dev, "vkCmdSetRepresentativeFragmentTestEnableNV");
     table->CmdSetCoverageReductionModeNV = (PFN_vkCmdSetCoverageReductionModeNV)gdpa(dev, "vkCmdSetCoverageReductionModeNV");
 
+    // ---- VK_ARM_tensors extension commands
+    table->CreateTensorARM = (PFN_vkCreateTensorARM)gdpa(dev, "vkCreateTensorARM");
+    table->DestroyTensorARM = (PFN_vkDestroyTensorARM)gdpa(dev, "vkDestroyTensorARM");
+    table->CreateTensorViewARM = (PFN_vkCreateTensorViewARM)gdpa(dev, "vkCreateTensorViewARM");
+    table->DestroyTensorViewARM = (PFN_vkDestroyTensorViewARM)gdpa(dev, "vkDestroyTensorViewARM");
+    table->GetTensorMemoryRequirementsARM = (PFN_vkGetTensorMemoryRequirementsARM)gdpa(dev, "vkGetTensorMemoryRequirementsARM");
+    table->BindTensorMemoryARM = (PFN_vkBindTensorMemoryARM)gdpa(dev, "vkBindTensorMemoryARM");
+    table->GetDeviceTensorMemoryRequirementsARM = (PFN_vkGetDeviceTensorMemoryRequirementsARM)gdpa(dev, "vkGetDeviceTensorMemoryRequirementsARM");
+    table->CmdCopyTensorARM = (PFN_vkCmdCopyTensorARM)gdpa(dev, "vkCmdCopyTensorARM");
+    table->GetTensorOpaqueCaptureDescriptorDataARM = (PFN_vkGetTensorOpaqueCaptureDescriptorDataARM)gdpa(dev, "vkGetTensorOpaqueCaptureDescriptorDataARM");
+    table->GetTensorViewOpaqueCaptureDescriptorDataARM = (PFN_vkGetTensorViewOpaqueCaptureDescriptorDataARM)gdpa(dev, "vkGetTensorViewOpaqueCaptureDescriptorDataARM");
+
     // ---- VK_EXT_shader_module_identifier extension commands
     table->GetShaderModuleIdentifierEXT = (PFN_vkGetShaderModuleIdentifierEXT)gdpa(dev, "vkGetShaderModuleIdentifierEXT");
     table->GetShaderModuleCreateInfoIdentifierEXT = (PFN_vkGetShaderModuleCreateInfoIdentifierEXT)gdpa(dev, "vkGetShaderModuleCreateInfoIdentifierEXT");
@@ -1190,6 +1335,10 @@
     table->GetFramebufferTilePropertiesQCOM = (PFN_vkGetFramebufferTilePropertiesQCOM)gdpa(dev, "vkGetFramebufferTilePropertiesQCOM");
     table->GetDynamicRenderingTilePropertiesQCOM = (PFN_vkGetDynamicRenderingTilePropertiesQCOM)gdpa(dev, "vkGetDynamicRenderingTilePropertiesQCOM");
 
+    // ---- VK_NV_cooperative_vector extension commands
+    table->ConvertCooperativeVectorMatrixNV = (PFN_vkConvertCooperativeVectorMatrixNV)gdpa(dev, "vkConvertCooperativeVectorMatrixNV");
+    table->CmdConvertCooperativeVectorMatrixNV = (PFN_vkCmdConvertCooperativeVectorMatrixNV)gdpa(dev, "vkCmdConvertCooperativeVectorMatrixNV");
+
     // ---- VK_NV_low_latency2 extension commands
     table->SetLatencySleepModeNV = (PFN_vkSetLatencySleepModeNV)gdpa(dev, "vkSetLatencySleepModeNV");
     table->LatencySleepNV = (PFN_vkLatencySleepNV)gdpa(dev, "vkLatencySleepNV");
@@ -1197,6 +1346,17 @@
     table->GetLatencyTimingsNV = (PFN_vkGetLatencyTimingsNV)gdpa(dev, "vkGetLatencyTimingsNV");
     table->QueueNotifyOutOfBandNV = (PFN_vkQueueNotifyOutOfBandNV)gdpa(dev, "vkQueueNotifyOutOfBandNV");
 
+    // ---- VK_ARM_data_graph extension commands
+    table->CreateDataGraphPipelinesARM = (PFN_vkCreateDataGraphPipelinesARM)gdpa(dev, "vkCreateDataGraphPipelinesARM");
+    table->CreateDataGraphPipelineSessionARM = (PFN_vkCreateDataGraphPipelineSessionARM)gdpa(dev, "vkCreateDataGraphPipelineSessionARM");
+    table->GetDataGraphPipelineSessionBindPointRequirementsARM = (PFN_vkGetDataGraphPipelineSessionBindPointRequirementsARM)gdpa(dev, "vkGetDataGraphPipelineSessionBindPointRequirementsARM");
+    table->GetDataGraphPipelineSessionMemoryRequirementsARM = (PFN_vkGetDataGraphPipelineSessionMemoryRequirementsARM)gdpa(dev, "vkGetDataGraphPipelineSessionMemoryRequirementsARM");
+    table->BindDataGraphPipelineSessionMemoryARM = (PFN_vkBindDataGraphPipelineSessionMemoryARM)gdpa(dev, "vkBindDataGraphPipelineSessionMemoryARM");
+    table->DestroyDataGraphPipelineSessionARM = (PFN_vkDestroyDataGraphPipelineSessionARM)gdpa(dev, "vkDestroyDataGraphPipelineSessionARM");
+    table->CmdDispatchDataGraphARM = (PFN_vkCmdDispatchDataGraphARM)gdpa(dev, "vkCmdDispatchDataGraphARM");
+    table->GetDataGraphPipelineAvailablePropertiesARM = (PFN_vkGetDataGraphPipelineAvailablePropertiesARM)gdpa(dev, "vkGetDataGraphPipelineAvailablePropertiesARM");
+    table->GetDataGraphPipelinePropertiesARM = (PFN_vkGetDataGraphPipelinePropertiesARM)gdpa(dev, "vkGetDataGraphPipelinePropertiesARM");
+
     // ---- VK_EXT_attachment_feedback_loop_dynamic_state extension commands
     table->CmdSetAttachmentFeedbackLoopEnableEXT = (PFN_vkCmdSetAttachmentFeedbackLoopEnableEXT)gdpa(dev, "vkCmdSetAttachmentFeedbackLoopEnableEXT");
 
@@ -1205,6 +1365,26 @@
     table->GetScreenBufferPropertiesQNX = (PFN_vkGetScreenBufferPropertiesQNX)gdpa(dev, "vkGetScreenBufferPropertiesQNX");
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_QCOM_tile_memory_heap extension commands
+    table->CmdBindTileMemoryQCOM = (PFN_vkCmdBindTileMemoryQCOM)gdpa(dev, "vkCmdBindTileMemoryQCOM");
+
+    // ---- VK_EXT_memory_decompression extension commands
+    table->CmdDecompressMemoryEXT = (PFN_vkCmdDecompressMemoryEXT)gdpa(dev, "vkCmdDecompressMemoryEXT");
+    table->CmdDecompressMemoryIndirectCountEXT = (PFN_vkCmdDecompressMemoryIndirectCountEXT)gdpa(dev, "vkCmdDecompressMemoryIndirectCountEXT");
+
+    // ---- VK_NV_external_compute_queue extension commands
+    table->CreateExternalComputeQueueNV = (PFN_vkCreateExternalComputeQueueNV)gdpa(dev, "vkCreateExternalComputeQueueNV");
+    table->DestroyExternalComputeQueueNV = (PFN_vkDestroyExternalComputeQueueNV)gdpa(dev, "vkDestroyExternalComputeQueueNV");
+    table->GetExternalComputeQueueDataNV = (PFN_vkGetExternalComputeQueueDataNV)gdpa(dev, "vkGetExternalComputeQueueDataNV");
+
+    // ---- VK_NV_cluster_acceleration_structure extension commands
+    table->GetClusterAccelerationStructureBuildSizesNV = (PFN_vkGetClusterAccelerationStructureBuildSizesNV)gdpa(dev, "vkGetClusterAccelerationStructureBuildSizesNV");
+    table->CmdBuildClusterAccelerationStructureIndirectNV = (PFN_vkCmdBuildClusterAccelerationStructureIndirectNV)gdpa(dev, "vkCmdBuildClusterAccelerationStructureIndirectNV");
+
+    // ---- VK_NV_partitioned_acceleration_structure extension commands
+    table->GetPartitionedAccelerationStructuresBuildSizesNV = (PFN_vkGetPartitionedAccelerationStructuresBuildSizesNV)gdpa(dev, "vkGetPartitionedAccelerationStructuresBuildSizesNV");
+    table->CmdBuildPartitionedAccelerationStructuresNV = (PFN_vkCmdBuildPartitionedAccelerationStructuresNV)gdpa(dev, "vkCmdBuildPartitionedAccelerationStructuresNV");
+
     // ---- VK_EXT_device_generated_commands extension commands
     table->GetGeneratedCommandsMemoryRequirementsEXT = (PFN_vkGetGeneratedCommandsMemoryRequirementsEXT)gdpa(dev, "vkGetGeneratedCommandsMemoryRequirementsEXT");
     table->CmdPreprocessGeneratedCommandsEXT = (PFN_vkCmdPreprocessGeneratedCommandsEXT)gdpa(dev, "vkCmdPreprocessGeneratedCommandsEXT");
@@ -1216,6 +1396,34 @@
     table->UpdateIndirectExecutionSetPipelineEXT = (PFN_vkUpdateIndirectExecutionSetPipelineEXT)gdpa(dev, "vkUpdateIndirectExecutionSetPipelineEXT");
     table->UpdateIndirectExecutionSetShaderEXT = (PFN_vkUpdateIndirectExecutionSetShaderEXT)gdpa(dev, "vkUpdateIndirectExecutionSetShaderEXT");
 
+    // ---- VK_EXT_external_memory_metal extension commands
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    table->GetMemoryMetalHandleEXT = (PFN_vkGetMemoryMetalHandleEXT)gdpa(dev, "vkGetMemoryMetalHandleEXT");
+#endif // VK_USE_PLATFORM_METAL_EXT
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    table->GetMemoryMetalHandlePropertiesEXT = (PFN_vkGetMemoryMetalHandlePropertiesEXT)gdpa(dev, "vkGetMemoryMetalHandlePropertiesEXT");
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+    // ---- VK_ARM_shader_instrumentation extension commands
+    table->CreateShaderInstrumentationARM = (PFN_vkCreateShaderInstrumentationARM)gdpa(dev, "vkCreateShaderInstrumentationARM");
+    table->DestroyShaderInstrumentationARM = (PFN_vkDestroyShaderInstrumentationARM)gdpa(dev, "vkDestroyShaderInstrumentationARM");
+    table->CmdBeginShaderInstrumentationARM = (PFN_vkCmdBeginShaderInstrumentationARM)gdpa(dev, "vkCmdBeginShaderInstrumentationARM");
+    table->CmdEndShaderInstrumentationARM = (PFN_vkCmdEndShaderInstrumentationARM)gdpa(dev, "vkCmdEndShaderInstrumentationARM");
+    table->GetShaderInstrumentationValuesARM = (PFN_vkGetShaderInstrumentationValuesARM)gdpa(dev, "vkGetShaderInstrumentationValuesARM");
+    table->ClearShaderInstrumentationMetricsARM = (PFN_vkClearShaderInstrumentationMetricsARM)gdpa(dev, "vkClearShaderInstrumentationMetricsARM");
+
+    // ---- VK_EXT_fragment_density_map_offset extension commands
+    table->CmdEndRendering2EXT = (PFN_vkCmdEndRendering2EXT)gdpa(dev, "vkCmdEndRendering2EXT");
+
+    // ---- VK_EXT_custom_resolve extension commands
+    table->CmdBeginCustomResolveEXT = (PFN_vkCmdBeginCustomResolveEXT)gdpa(dev, "vkCmdBeginCustomResolveEXT");
+
+    // ---- VK_NV_compute_occupancy_priority extension commands
+    table->CmdSetComputeOccupancyPriorityNV = (PFN_vkCmdSetComputeOccupancyPriorityNV)gdpa(dev, "vkCmdSetComputeOccupancyPriorityNV");
+
+    // ---- VK_EXT_primitive_restart_index extension commands
+    table->CmdSetPrimitiveRestartIndexEXT = (PFN_vkCmdSetPrimitiveRestartIndexEXT)gdpa(dev, "vkCmdSetPrimitiveRestartIndexEXT");
+
     // ---- VK_KHR_acceleration_structure extension commands
     table->CreateAccelerationStructureKHR = (PFN_vkCreateAccelerationStructureKHR)gdpa(dev, "vkCreateAccelerationStructureKHR");
     table->DestroyAccelerationStructureKHR = (PFN_vkDestroyAccelerationStructureKHR)gdpa(dev, "vkDestroyAccelerationStructureKHR");
@@ -1441,6 +1649,9 @@
     table->DestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT)gpa(inst, "vkDestroyDebugUtilsMessengerEXT");
     table->SubmitDebugUtilsMessageEXT = (PFN_vkSubmitDebugUtilsMessageEXT)gpa(inst, "vkSubmitDebugUtilsMessageEXT");
 
+    // ---- VK_EXT_descriptor_heap extension commands
+    table->GetPhysicalDeviceDescriptorSizeEXT = (PFN_vkGetPhysicalDeviceDescriptorSizeEXT)gpa(inst, "vkGetPhysicalDeviceDescriptorSizeEXT");
+
     // ---- VK_EXT_sample_locations extension commands
     table->GetPhysicalDeviceMultisamplePropertiesEXT = (PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT)gpa(inst, "vkGetPhysicalDeviceMultisamplePropertiesEXT");
 
@@ -1502,11 +1713,46 @@
     table->GetPhysicalDeviceScreenPresentationSupportQNX = (PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX)gpa(inst, "vkGetPhysicalDeviceScreenPresentationSupportQNX");
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_ARM_tensors extension commands
+    table->GetPhysicalDeviceExternalTensorPropertiesARM = (PFN_vkGetPhysicalDeviceExternalTensorPropertiesARM)gpa(inst, "vkGetPhysicalDeviceExternalTensorPropertiesARM");
+
     // ---- VK_NV_optical_flow extension commands
     table->GetPhysicalDeviceOpticalFlowImageFormatsNV = (PFN_vkGetPhysicalDeviceOpticalFlowImageFormatsNV)gpa(inst, "vkGetPhysicalDeviceOpticalFlowImageFormatsNV");
 
+    // ---- VK_NV_cooperative_vector extension commands
+    table->GetPhysicalDeviceCooperativeVectorPropertiesNV = (PFN_vkGetPhysicalDeviceCooperativeVectorPropertiesNV)gpa(inst, "vkGetPhysicalDeviceCooperativeVectorPropertiesNV");
+
+    // ---- VK_ARM_data_graph extension commands
+    table->GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM = (PFN_vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM)gpa(inst, "vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM");
+    table->GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM = (PFN_vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM)gpa(inst, "vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM");
+
+    // ---- VK_ARM_data_graph_instruction_set_tosa extension commands
+    table->GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM = (PFN_vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM)gpa(inst, "vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM");
+
+    // ---- VK_OHOS_surface extension commands
+#if defined(VK_USE_PLATFORM_OHOS)
+    table->CreateSurfaceOHOS = (PFN_vkCreateSurfaceOHOS)gpa(inst, "vkCreateSurfaceOHOS");
+#endif // VK_USE_PLATFORM_OHOS
+
     // ---- VK_NV_cooperative_matrix2 extension commands
     table->GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV = (PFN_vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV)gpa(inst, "vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV");
+
+    // ---- VK_ARM_performance_counters_by_region extension commands
+    table->EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM = (PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM)gpa(inst, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM");
+
+    // ---- VK_ARM_shader_instrumentation extension commands
+    table->EnumeratePhysicalDeviceShaderInstrumentationMetricsARM = (PFN_vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM)gpa(inst, "vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM");
+
+    // ---- VK_ARM_data_graph_optical_flow extension commands
+    table->GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM = (PFN_vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM)gpa(inst, "vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM");
+
+    // ---- VK_SEC_ubm_surface extension commands
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    table->CreateUbmSurfaceSEC = (PFN_vkCreateUbmSurfaceSEC)gpa(inst, "vkCreateUbmSurfaceSEC");
+#endif // VK_USE_PLATFORM_UBM_SEC
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    table->GetPhysicalDeviceUbmPresentationSupportSEC = (PFN_vkGetPhysicalDeviceUbmPresentationSupportSEC)gpa(inst, "vkGetPhysicalDeviceUbmPresentationSupportSEC");
+#endif // VK_USE_PLATFORM_UBM_SEC
 }
 
 // Functions that required a terminator need to have a separate dispatch table which contains their corresponding
@@ -1514,19 +1760,23 @@
 void init_extension_device_proc_terminator_dispatch(struct loader_device *dev) {
     struct loader_device_terminator_dispatch* dispatch = &dev->loader_dispatch.extension_terminator_dispatch;
     PFN_vkGetDeviceProcAddr gpda = (PFN_vkGetDeviceProcAddr)dev->phys_dev_term->this_icd_term->dispatch.GetDeviceProcAddr;
+
     // ---- VK_KHR_swapchain extension commands
     if (dev->driver_extensions.khr_swapchain_enabled)
        dispatch->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpda(dev->icd_device, "vkCreateSwapchainKHR");
-    if (dev->driver_extensions.khr_swapchain_enabled)
+    if (dev->driver_extensions.khr_swapchain_enabled || dev->driver_extensions.khr_device_group_enabled)
        dispatch->GetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR)gpda(dev->icd_device, "vkGetDeviceGroupSurfacePresentModesKHR");
+
     // ---- VK_KHR_display_swapchain extension commands
     if (dev->driver_extensions.khr_display_swapchain_enabled)
        dispatch->CreateSharedSwapchainsKHR = (PFN_vkCreateSharedSwapchainsKHR)gpda(dev->icd_device, "vkCreateSharedSwapchainsKHR");
+
     // ---- VK_EXT_debug_marker extension commands
     if (dev->driver_extensions.ext_debug_marker_enabled)
        dispatch->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)gpda(dev->icd_device, "vkDebugMarkerSetObjectTagEXT");
     if (dev->driver_extensions.ext_debug_marker_enabled)
        dispatch->DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)gpda(dev->icd_device, "vkDebugMarkerSetObjectNameEXT");
+
     // ---- VK_EXT_debug_utils extension commands
     if (dev->driver_extensions.ext_debug_utils_enabled)
        dispatch->SetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)gpda(dev->icd_device, "vkSetDebugUtilsObjectNameEXT");
@@ -1545,14 +1795,16 @@
     if (dev->driver_extensions.ext_debug_utils_enabled)
        dispatch->CmdInsertDebugUtilsLabelEXT = (PFN_vkCmdInsertDebugUtilsLabelEXT)gpda(dev->icd_device, "vkCmdInsertDebugUtilsLabelEXT");
 #if defined(VK_USE_PLATFORM_WIN32_KHR)
+
     // ---- VK_EXT_full_screen_exclusive extension commands
-    if (dev->driver_extensions.ext_full_screen_exclusive_enabled && (dev->driver_extensions.khr_device_group_enabled || dev->driver_extensions.version_1_1_enabled))
+    if (dev->driver_extensions.ext_full_screen_exclusive_enabled)
        dispatch->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)gpda(dev->icd_device, "vkGetDeviceGroupSurfacePresentModes2EXT");
 #endif // VK_USE_PLATFORM_WIN32_KHR
 }
 
 // These are prototypes for functions that need their trampoline called in all circumstances.
 // They are used in loader_lookup_device_dispatch_table but are defined afterwards.
+
     // ---- VK_EXT_debug_marker extension commands
 VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(
     VkDevice                                    device,
@@ -1560,6 +1812,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT(
     VkDevice                                    device,
     const VkDebugMarkerObjectNameInfoEXT*       pNameInfo);
+
     // ---- VK_EXT_debug_utils extension commands
 VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectNameEXT(
     VkDevice                                    device,
@@ -1687,26 +1940,6 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->DestroySemaphore;
     }
-    if (!strcmp(name, "CreateEvent")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CreateEvent;
-    }
-    if (!strcmp(name, "DestroyEvent")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->DestroyEvent;
-    }
-    if (!strcmp(name, "GetEventStatus")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->GetEventStatus;
-    }
-    if (!strcmp(name, "SetEvent")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->SetEvent;
-    }
-    if (!strcmp(name, "ResetEvent")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->ResetEvent;
-    }
     if (!strcmp(name, "CreateQueryPool")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CreateQueryPool;
@@ -1727,14 +1960,6 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->DestroyBuffer;
     }
-    if (!strcmp(name, "CreateBufferView")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CreateBufferView;
-    }
-    if (!strcmp(name, "DestroyBufferView")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->DestroyBufferView;
-    }
     if (!strcmp(name, "CreateImage")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CreateImage;
@@ -1755,6 +1980,118 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->DestroyImageView;
     }
+    if (!strcmp(name, "CreateCommandPool")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CreateCommandPool;
+    }
+    if (!strcmp(name, "DestroyCommandPool")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->DestroyCommandPool;
+    }
+    if (!strcmp(name, "ResetCommandPool")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->ResetCommandPool;
+    }
+    if (!strcmp(name, "AllocateCommandBuffers")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->AllocateCommandBuffers;
+    }
+    if (!strcmp(name, "FreeCommandBuffers")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->FreeCommandBuffers;
+    }
+    if (!strcmp(name, "BeginCommandBuffer")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->BeginCommandBuffer;
+    }
+    if (!strcmp(name, "EndCommandBuffer")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->EndCommandBuffer;
+    }
+    if (!strcmp(name, "ResetCommandBuffer")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->ResetCommandBuffer;
+    }
+    if (!strcmp(name, "CmdCopyBuffer")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdCopyBuffer;
+    }
+    if (!strcmp(name, "CmdCopyImage")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdCopyImage;
+    }
+    if (!strcmp(name, "CmdCopyBufferToImage")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdCopyBufferToImage;
+    }
+    if (!strcmp(name, "CmdCopyImageToBuffer")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdCopyImageToBuffer;
+    }
+    if (!strcmp(name, "CmdUpdateBuffer")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdUpdateBuffer;
+    }
+    if (!strcmp(name, "CmdFillBuffer")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdFillBuffer;
+    }
+    if (!strcmp(name, "CmdPipelineBarrier")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdPipelineBarrier;
+    }
+    if (!strcmp(name, "CmdBeginQuery")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdBeginQuery;
+    }
+    if (!strcmp(name, "CmdEndQuery")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdEndQuery;
+    }
+    if (!strcmp(name, "CmdResetQueryPool")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdResetQueryPool;
+    }
+    if (!strcmp(name, "CmdWriteTimestamp")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdWriteTimestamp;
+    }
+    if (!strcmp(name, "CmdCopyQueryPoolResults")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdCopyQueryPoolResults;
+    }
+    if (!strcmp(name, "CmdExecuteCommands")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdExecuteCommands;
+    }
+    if (!strcmp(name, "CreateEvent")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CreateEvent;
+    }
+    if (!strcmp(name, "DestroyEvent")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->DestroyEvent;
+    }
+    if (!strcmp(name, "GetEventStatus")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->GetEventStatus;
+    }
+    if (!strcmp(name, "SetEvent")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->SetEvent;
+    }
+    if (!strcmp(name, "ResetEvent")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->ResetEvent;
+    }
+    if (!strcmp(name, "CreateBufferView")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CreateBufferView;
+    }
+    if (!strcmp(name, "DestroyBufferView")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->DestroyBufferView;
+    }
     if (!strcmp(name, "CreateShaderModule")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CreateShaderModule;
@@ -1779,10 +2116,6 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->MergePipelineCaches;
     }
-    if (!strcmp(name, "CreateGraphicsPipelines")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CreateGraphicsPipelines;
-    }
     if (!strcmp(name, "CreateComputePipelines")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CreateComputePipelines;
@@ -1839,6 +2172,46 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->UpdateDescriptorSets;
     }
+    if (!strcmp(name, "CmdBindPipeline")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdBindPipeline;
+    }
+    if (!strcmp(name, "CmdBindDescriptorSets")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdBindDescriptorSets;
+    }
+    if (!strcmp(name, "CmdClearColorImage")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdClearColorImage;
+    }
+    if (!strcmp(name, "CmdDispatch")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdDispatch;
+    }
+    if (!strcmp(name, "CmdDispatchIndirect")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdDispatchIndirect;
+    }
+    if (!strcmp(name, "CmdSetEvent")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdSetEvent;
+    }
+    if (!strcmp(name, "CmdResetEvent")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdResetEvent;
+    }
+    if (!strcmp(name, "CmdWaitEvents")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdWaitEvents;
+    }
+    if (!strcmp(name, "CmdPushConstants")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CmdPushConstants;
+    }
+    if (!strcmp(name, "CreateGraphicsPipelines")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
+        return (void *)table->CreateGraphicsPipelines;
+    }
     if (!strcmp(name, "CreateFramebuffer")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CreateFramebuffer;
@@ -1859,42 +2232,6 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->GetRenderAreaGranularity;
     }
-    if (!strcmp(name, "CreateCommandPool")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CreateCommandPool;
-    }
-    if (!strcmp(name, "DestroyCommandPool")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->DestroyCommandPool;
-    }
-    if (!strcmp(name, "ResetCommandPool")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->ResetCommandPool;
-    }
-    if (!strcmp(name, "AllocateCommandBuffers")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->AllocateCommandBuffers;
-    }
-    if (!strcmp(name, "FreeCommandBuffers")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->FreeCommandBuffers;
-    }
-    if (!strcmp(name, "BeginCommandBuffer")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->BeginCommandBuffer;
-    }
-    if (!strcmp(name, "EndCommandBuffer")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->EndCommandBuffer;
-    }
-    if (!strcmp(name, "ResetCommandBuffer")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->ResetCommandBuffer;
-    }
-    if (!strcmp(name, "CmdBindPipeline")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdBindPipeline;
-    }
     if (!strcmp(name, "CmdSetViewport")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CmdSetViewport;
@@ -1931,10 +2268,6 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CmdSetStencilReference;
     }
-    if (!strcmp(name, "CmdBindDescriptorSets")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdBindDescriptorSets;
-    }
     if (!strcmp(name, "CmdBindIndexBuffer")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CmdBindIndexBuffer;
@@ -1959,46 +2292,10 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CmdDrawIndexedIndirect;
     }
-    if (!strcmp(name, "CmdDispatch")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdDispatch;
-    }
-    if (!strcmp(name, "CmdDispatchIndirect")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdDispatchIndirect;
-    }
-    if (!strcmp(name, "CmdCopyBuffer")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdCopyBuffer;
-    }
-    if (!strcmp(name, "CmdCopyImage")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdCopyImage;
-    }
     if (!strcmp(name, "CmdBlitImage")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CmdBlitImage;
     }
-    if (!strcmp(name, "CmdCopyBufferToImage")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdCopyBufferToImage;
-    }
-    if (!strcmp(name, "CmdCopyImageToBuffer")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdCopyImageToBuffer;
-    }
-    if (!strcmp(name, "CmdUpdateBuffer")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdUpdateBuffer;
-    }
-    if (!strcmp(name, "CmdFillBuffer")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdFillBuffer;
-    }
-    if (!strcmp(name, "CmdClearColorImage")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdClearColorImage;
-    }
     if (!strcmp(name, "CmdClearDepthStencilImage")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CmdClearDepthStencilImage;
@@ -2011,46 +2308,6 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CmdResolveImage;
     }
-    if (!strcmp(name, "CmdSetEvent")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdSetEvent;
-    }
-    if (!strcmp(name, "CmdResetEvent")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdResetEvent;
-    }
-    if (!strcmp(name, "CmdWaitEvents")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdWaitEvents;
-    }
-    if (!strcmp(name, "CmdPipelineBarrier")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdPipelineBarrier;
-    }
-    if (!strcmp(name, "CmdBeginQuery")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdBeginQuery;
-    }
-    if (!strcmp(name, "CmdEndQuery")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdEndQuery;
-    }
-    if (!strcmp(name, "CmdResetQueryPool")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdResetQueryPool;
-    }
-    if (!strcmp(name, "CmdWriteTimestamp")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdWriteTimestamp;
-    }
-    if (!strcmp(name, "CmdCopyQueryPoolResults")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdCopyQueryPoolResults;
-    }
-    if (!strcmp(name, "CmdPushConstants")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdPushConstants;
-    }
     if (!strcmp(name, "CmdBeginRenderPass")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CmdBeginRenderPass;
@@ -2063,10 +2320,6 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
         return (void *)table->CmdEndRenderPass;
     }
-    if (!strcmp(name, "CmdExecuteCommands")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL;
-        return (void *)table->CmdExecuteCommands;
-    }
 
     // ---- Core Vulkan 1.1 commands
     if (!strcmp(name, "BindBufferMemory2")) {
@@ -2085,10 +2338,6 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_1) return NULL;
         return (void *)table->CmdSetDeviceMask;
     }
-    if (!strcmp(name, "CmdDispatchBase")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_1) return NULL;
-        return (void *)table->CmdDispatchBase;
-    }
     if (!strcmp(name, "GetImageMemoryRequirements2")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_1) return NULL;
         return (void *)table->GetImageMemoryRequirements2;
@@ -2109,13 +2358,9 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_1) return NULL;
         return (void *)table->GetDeviceQueue2;
     }
-    if (!strcmp(name, "CreateSamplerYcbcrConversion")) {
+    if (!strcmp(name, "CmdDispatchBase")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_1) return NULL;
-        return (void *)table->CreateSamplerYcbcrConversion;
-    }
-    if (!strcmp(name, "DestroySamplerYcbcrConversion")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_1) return NULL;
-        return (void *)table->DestroySamplerYcbcrConversion;
+        return (void *)table->CmdDispatchBase;
     }
     if (!strcmp(name, "CreateDescriptorUpdateTemplate")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_1) return NULL;
@@ -2133,32 +2378,16 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_1) return NULL;
         return (void *)table->GetDescriptorSetLayoutSupport;
     }
+    if (!strcmp(name, "CreateSamplerYcbcrConversion")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_1) return NULL;
+        return (void *)table->CreateSamplerYcbcrConversion;
+    }
+    if (!strcmp(name, "DestroySamplerYcbcrConversion")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_1) return NULL;
+        return (void *)table->DestroySamplerYcbcrConversion;
+    }
 
     // ---- Core Vulkan 1.2 commands
-    if (!strcmp(name, "CmdDrawIndirectCount")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
-        return (void *)table->CmdDrawIndirectCount;
-    }
-    if (!strcmp(name, "CmdDrawIndexedIndirectCount")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
-        return (void *)table->CmdDrawIndexedIndirectCount;
-    }
-    if (!strcmp(name, "CreateRenderPass2")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
-        return (void *)table->CreateRenderPass2;
-    }
-    if (!strcmp(name, "CmdBeginRenderPass2")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
-        return (void *)table->CmdBeginRenderPass2;
-    }
-    if (!strcmp(name, "CmdNextSubpass2")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
-        return (void *)table->CmdNextSubpass2;
-    }
-    if (!strcmp(name, "CmdEndRenderPass2")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
-        return (void *)table->CmdEndRenderPass2;
-    }
     if (!strcmp(name, "ResetQueryPool")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
         return (void *)table->ResetQueryPool;
@@ -2187,6 +2416,30 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
         return (void *)table->GetDeviceMemoryOpaqueCaptureAddress;
     }
+    if (!strcmp(name, "CmdDrawIndirectCount")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
+        return (void *)table->CmdDrawIndirectCount;
+    }
+    if (!strcmp(name, "CmdDrawIndexedIndirectCount")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
+        return (void *)table->CmdDrawIndexedIndirectCount;
+    }
+    if (!strcmp(name, "CreateRenderPass2")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
+        return (void *)table->CreateRenderPass2;
+    }
+    if (!strcmp(name, "CmdBeginRenderPass2")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
+        return (void *)table->CmdBeginRenderPass2;
+    }
+    if (!strcmp(name, "CmdNextSubpass2")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
+        return (void *)table->CmdNextSubpass2;
+    }
+    if (!strcmp(name, "CmdEndRenderPass2")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL;
+        return (void *)table->CmdEndRenderPass2;
+    }
 
     // ---- Core Vulkan 1.3 commands
     if (!strcmp(name, "CreatePrivateDataSlot")) {
@@ -2205,18 +2458,6 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
         return (void *)table->GetPrivateData;
     }
-    if (!strcmp(name, "CmdSetEvent2")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
-        return (void *)table->CmdSetEvent2;
-    }
-    if (!strcmp(name, "CmdResetEvent2")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
-        return (void *)table->CmdResetEvent2;
-    }
-    if (!strcmp(name, "CmdWaitEvents2")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
-        return (void *)table->CmdWaitEvents2;
-    }
     if (!strcmp(name, "CmdPipelineBarrier2")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
         return (void *)table->CmdPipelineBarrier2;
@@ -2245,6 +2486,30 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
         return (void *)table->CmdCopyImageToBuffer2;
     }
+    if (!strcmp(name, "GetDeviceBufferMemoryRequirements")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
+        return (void *)table->GetDeviceBufferMemoryRequirements;
+    }
+    if (!strcmp(name, "GetDeviceImageMemoryRequirements")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
+        return (void *)table->GetDeviceImageMemoryRequirements;
+    }
+    if (!strcmp(name, "GetDeviceImageSparseMemoryRequirements")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
+        return (void *)table->GetDeviceImageSparseMemoryRequirements;
+    }
+    if (!strcmp(name, "CmdSetEvent2")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
+        return (void *)table->CmdSetEvent2;
+    }
+    if (!strcmp(name, "CmdResetEvent2")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
+        return (void *)table->CmdResetEvent2;
+    }
+    if (!strcmp(name, "CmdWaitEvents2")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
+        return (void *)table->CmdWaitEvents2;
+    }
     if (!strcmp(name, "CmdBlitImage2")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
         return (void *)table->CmdBlitImage2;
@@ -2321,24 +2586,8 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
         return (void *)table->CmdSetPrimitiveRestartEnable;
     }
-    if (!strcmp(name, "GetDeviceBufferMemoryRequirements")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
-        return (void *)table->GetDeviceBufferMemoryRequirements;
-    }
-    if (!strcmp(name, "GetDeviceImageMemoryRequirements")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
-        return (void *)table->GetDeviceImageMemoryRequirements;
-    }
-    if (!strcmp(name, "GetDeviceImageSparseMemoryRequirements")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_3) return NULL;
-        return (void *)table->GetDeviceImageSparseMemoryRequirements;
-    }
 
     // ---- Core Vulkan 1.4 commands
-    if (!strcmp(name, "CmdSetLineStipple")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
-        return (void *)table->CmdSetLineStipple;
-    }
     if (!strcmp(name, "MapMemory2")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
         return (void *)table->MapMemory2;
@@ -2347,14 +2596,6 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
         return (void *)table->UnmapMemory2;
     }
-    if (!strcmp(name, "CmdBindIndexBuffer2")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
-        return (void *)table->CmdBindIndexBuffer2;
-    }
-    if (!strcmp(name, "GetRenderingAreaGranularity")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
-        return (void *)table->GetRenderingAreaGranularity;
-    }
     if (!strcmp(name, "GetDeviceImageSubresourceLayout")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
         return (void *)table->GetDeviceImageSubresourceLayout;
@@ -2363,6 +2604,22 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
         return (void *)table->GetImageSubresourceLayout2;
     }
+    if (!strcmp(name, "CopyMemoryToImage")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
+        return (void *)table->CopyMemoryToImage;
+    }
+    if (!strcmp(name, "CopyImageToMemory")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
+        return (void *)table->CopyImageToMemory;
+    }
+    if (!strcmp(name, "CopyImageToImage")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
+        return (void *)table->CopyImageToImage;
+    }
+    if (!strcmp(name, "TransitionImageLayout")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
+        return (void *)table->TransitionImageLayout;
+    }
     if (!strcmp(name, "CmdPushDescriptorSet")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
         return (void *)table->CmdPushDescriptorSet;
@@ -2371,14 +2628,6 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
         return (void *)table->CmdPushDescriptorSetWithTemplate;
     }
-    if (!strcmp(name, "CmdSetRenderingAttachmentLocations")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
-        return (void *)table->CmdSetRenderingAttachmentLocations;
-    }
-    if (!strcmp(name, "CmdSetRenderingInputAttachmentIndices")) {
-        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
-        return (void *)table->CmdSetRenderingInputAttachmentIndices;
-    }
     if (!strcmp(name, "CmdBindDescriptorSets2")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
         return (void *)table->CmdBindDescriptorSets2;
@@ -2395,21 +2644,25 @@
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
         return (void *)table->CmdPushDescriptorSetWithTemplate2;
     }
-    if (!strcmp(name, "CopyMemoryToImage")) {
+    if (!strcmp(name, "CmdSetLineStipple")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
-        return (void *)table->CopyMemoryToImage;
+        return (void *)table->CmdSetLineStipple;
     }
-    if (!strcmp(name, "CopyImageToMemory")) {
+    if (!strcmp(name, "CmdBindIndexBuffer2")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
-        return (void *)table->CopyImageToMemory;
+        return (void *)table->CmdBindIndexBuffer2;
     }
-    if (!strcmp(name, "CopyImageToImage")) {
+    if (!strcmp(name, "GetRenderingAreaGranularity")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
-        return (void *)table->CopyImageToImage;
+        return (void *)table->GetRenderingAreaGranularity;
     }
-    if (!strcmp(name, "TransitionImageLayout")) {
+    if (!strcmp(name, "CmdSetRenderingAttachmentLocations")) {
         if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
-        return (void *)table->TransitionImageLayout;
+        return (void *)table->CmdSetRenderingAttachmentLocations;
+    }
+    if (!strcmp(name, "CmdSetRenderingInputAttachmentIndices")) {
+        if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL;
+        return (void *)table->CmdSetRenderingInputAttachmentIndices;
     }
 
     // ---- VK_KHR_swapchain extension commands
@@ -2578,6 +2831,30 @@
     if (!strcmp(name, "CmdWriteTimestamp2KHR")) return (void *)table->CmdWriteTimestamp2KHR;
     if (!strcmp(name, "QueueSubmit2KHR")) return (void *)table->QueueSubmit2KHR;
 
+    // ---- VK_KHR_device_address_commands extension commands
+    if (!strcmp(name, "CmdBindIndexBuffer3KHR")) return (void *)table->CmdBindIndexBuffer3KHR;
+    if (!strcmp(name, "CmdBindVertexBuffers3KHR")) return (void *)table->CmdBindVertexBuffers3KHR;
+    if (!strcmp(name, "CmdDrawIndirect2KHR")) return (void *)table->CmdDrawIndirect2KHR;
+    if (!strcmp(name, "CmdDrawIndexedIndirect2KHR")) return (void *)table->CmdDrawIndexedIndirect2KHR;
+    if (!strcmp(name, "CmdDispatchIndirect2KHR")) return (void *)table->CmdDispatchIndirect2KHR;
+    if (!strcmp(name, "CmdCopyMemoryKHR")) return (void *)table->CmdCopyMemoryKHR;
+    if (!strcmp(name, "CmdCopyMemoryToImageKHR")) return (void *)table->CmdCopyMemoryToImageKHR;
+    if (!strcmp(name, "CmdCopyImageToMemoryKHR")) return (void *)table->CmdCopyImageToMemoryKHR;
+    if (!strcmp(name, "CmdUpdateMemoryKHR")) return (void *)table->CmdUpdateMemoryKHR;
+    if (!strcmp(name, "CmdFillMemoryKHR")) return (void *)table->CmdFillMemoryKHR;
+    if (!strcmp(name, "CmdCopyQueryPoolResultsToMemoryKHR")) return (void *)table->CmdCopyQueryPoolResultsToMemoryKHR;
+    if (!strcmp(name, "CmdDrawIndirectCount2KHR")) return (void *)table->CmdDrawIndirectCount2KHR;
+    if (!strcmp(name, "CmdDrawIndexedIndirectCount2KHR")) return (void *)table->CmdDrawIndexedIndirectCount2KHR;
+    if (!strcmp(name, "CmdBeginConditionalRendering2EXT")) return (void *)table->CmdBeginConditionalRendering2EXT;
+    if (!strcmp(name, "CmdBindTransformFeedbackBuffers2EXT")) return (void *)table->CmdBindTransformFeedbackBuffers2EXT;
+    if (!strcmp(name, "CmdBeginTransformFeedback2EXT")) return (void *)table->CmdBeginTransformFeedback2EXT;
+    if (!strcmp(name, "CmdEndTransformFeedback2EXT")) return (void *)table->CmdEndTransformFeedback2EXT;
+    if (!strcmp(name, "CmdDrawIndirectByteCount2EXT")) return (void *)table->CmdDrawIndirectByteCount2EXT;
+    if (!strcmp(name, "CmdDrawMeshTasksIndirect2EXT")) return (void *)table->CmdDrawMeshTasksIndirect2EXT;
+    if (!strcmp(name, "CmdDrawMeshTasksIndirectCount2EXT")) return (void *)table->CmdDrawMeshTasksIndirectCount2EXT;
+    if (!strcmp(name, "CmdWriteMarkerToMemoryAMD")) return (void *)table->CmdWriteMarkerToMemoryAMD;
+    if (!strcmp(name, "CreateAccelerationStructure2KHR")) return (void *)table->CreateAccelerationStructure2KHR;
+
     // ---- VK_KHR_copy_commands2 extension commands
     if (!strcmp(name, "CmdCopyBuffer2KHR")) return (void *)table->CmdCopyBuffer2KHR;
     if (!strcmp(name, "CmdCopyImage2KHR")) return (void *)table->CmdCopyImage2KHR;
@@ -2600,6 +2877,9 @@
     if (!strcmp(name, "GetDeviceImageSubresourceLayoutKHR")) return (void *)table->GetDeviceImageSubresourceLayoutKHR;
     if (!strcmp(name, "GetImageSubresourceLayout2KHR")) return (void *)table->GetImageSubresourceLayout2KHR;
 
+    // ---- VK_KHR_present_wait2 extension commands
+    if (!strcmp(name, "WaitForPresent2KHR")) return (void *)table->WaitForPresent2KHR;
+
     // ---- VK_KHR_pipeline_binary extension commands
     if (!strcmp(name, "CreatePipelineBinariesKHR")) return (void *)table->CreatePipelineBinariesKHR;
     if (!strcmp(name, "DestroyPipelineBinaryKHR")) return (void *)table->DestroyPipelineBinaryKHR;
@@ -2607,6 +2887,9 @@
     if (!strcmp(name, "GetPipelineBinaryDataKHR")) return (void *)table->GetPipelineBinaryDataKHR;
     if (!strcmp(name, "ReleaseCapturedPipelineDataKHR")) return (void *)table->ReleaseCapturedPipelineDataKHR;
 
+    // ---- VK_KHR_swapchain_maintenance1 extension commands
+    if (!strcmp(name, "ReleaseSwapchainImagesKHR")) return (void *)table->ReleaseSwapchainImagesKHR;
+
     // ---- VK_KHR_line_rasterization extension commands
     if (!strcmp(name, "CmdSetLineStippleKHR")) return (void *)table->CmdSetLineStippleKHR;
 
@@ -2621,6 +2904,17 @@
     if (!strcmp(name, "CmdSetDescriptorBufferOffsets2EXT")) return (void *)table->CmdSetDescriptorBufferOffsets2EXT;
     if (!strcmp(name, "CmdBindDescriptorBufferEmbeddedSamplers2EXT")) return (void *)table->CmdBindDescriptorBufferEmbeddedSamplers2EXT;
 
+    // ---- VK_KHR_copy_memory_indirect extension commands
+    if (!strcmp(name, "CmdCopyMemoryIndirectKHR")) return (void *)table->CmdCopyMemoryIndirectKHR;
+    if (!strcmp(name, "CmdCopyMemoryToImageIndirectKHR")) return (void *)table->CmdCopyMemoryToImageIndirectKHR;
+
+    // ---- VK_KHR_device_fault extension commands
+    if (!strcmp(name, "GetDeviceFaultReportsKHR")) return (void *)table->GetDeviceFaultReportsKHR;
+    if (!strcmp(name, "GetDeviceFaultDebugInfoKHR")) return (void *)table->GetDeviceFaultDebugInfoKHR;
+
+    // ---- VK_KHR_maintenance10 extension commands
+    if (!strcmp(name, "CmdEndRendering2KHR")) return (void *)table->CmdEndRendering2KHR;
+
     // ---- VK_EXT_debug_marker extension commands
     if (!strcmp(name, "DebugMarkerSetObjectTagEXT")) return dev->layer_extensions.ext_debug_marker_enabled ? (void *)DebugMarkerSetObjectTagEXT : NULL;
     if (!strcmp(name, "DebugMarkerSetObjectNameEXT")) return dev->layer_extensions.ext_debug_marker_enabled ? (void *)DebugMarkerSetObjectNameEXT : NULL;
@@ -2647,6 +2941,7 @@
     if (!strcmp(name, "GetImageViewHandleNVX")) return (void *)table->GetImageViewHandleNVX;
     if (!strcmp(name, "GetImageViewHandle64NVX")) return (void *)table->GetImageViewHandle64NVX;
     if (!strcmp(name, "GetImageViewAddressNVX")) return (void *)table->GetImageViewAddressNVX;
+    if (!strcmp(name, "GetDeviceCombinedImageSamplerIndexNVX")) return (void *)table->GetDeviceCombinedImageSamplerIndexNVX;
 
     // ---- VK_AMD_draw_indirect_count extension commands
     if (!strcmp(name, "CmdDrawIndirectCountAMD")) return (void *)table->CmdDrawIndirectCountAMD;
@@ -2726,6 +3021,17 @@
     if (!strcmp(name, "CmdDispatchGraphIndirectCountAMDX")) return (void *)table->CmdDispatchGraphIndirectCountAMDX;
 #endif // VK_ENABLE_BETA_EXTENSIONS
 
+    // ---- VK_EXT_descriptor_heap extension commands
+    if (!strcmp(name, "WriteSamplerDescriptorsEXT")) return (void *)table->WriteSamplerDescriptorsEXT;
+    if (!strcmp(name, "WriteResourceDescriptorsEXT")) return (void *)table->WriteResourceDescriptorsEXT;
+    if (!strcmp(name, "CmdBindSamplerHeapEXT")) return (void *)table->CmdBindSamplerHeapEXT;
+    if (!strcmp(name, "CmdBindResourceHeapEXT")) return (void *)table->CmdBindResourceHeapEXT;
+    if (!strcmp(name, "CmdPushDataEXT")) return (void *)table->CmdPushDataEXT;
+    if (!strcmp(name, "GetImageOpaqueCaptureDataEXT")) return (void *)table->GetImageOpaqueCaptureDataEXT;
+    if (!strcmp(name, "RegisterCustomBorderColorEXT")) return (void *)table->RegisterCustomBorderColorEXT;
+    if (!strcmp(name, "UnregisterCustomBorderColorEXT")) return (void *)table->UnregisterCustomBorderColorEXT;
+    if (!strcmp(name, "GetTensorOpaqueCaptureDataARM")) return (void *)table->GetTensorOpaqueCaptureDataARM;
+
     // ---- VK_EXT_sample_locations extension commands
     if (!strcmp(name, "CmdSetSampleLocationsEXT")) return (void *)table->CmdSetSampleLocationsEXT;
 
@@ -2752,7 +3058,11 @@
     if (!strcmp(name, "CmdCopyAccelerationStructureNV")) return (void *)table->CmdCopyAccelerationStructureNV;
     if (!strcmp(name, "CmdTraceRaysNV")) return (void *)table->CmdTraceRaysNV;
     if (!strcmp(name, "CreateRayTracingPipelinesNV")) return (void *)table->CreateRayTracingPipelinesNV;
+
+    // ---- VK_KHR_ray_tracing_pipeline extension commands
     if (!strcmp(name, "GetRayTracingShaderGroupHandlesKHR")) return (void *)table->GetRayTracingShaderGroupHandlesKHR;
+
+    // ---- VK_NV_ray_tracing extension commands
     if (!strcmp(name, "GetRayTracingShaderGroupHandlesNV")) return (void *)table->GetRayTracingShaderGroupHandlesNV;
     if (!strcmp(name, "GetAccelerationStructureHandleNV")) return (void *)table->GetAccelerationStructureHandleNV;
     if (!strcmp(name, "CmdWriteAccelerationStructuresPropertiesNV")) return (void *)table->CmdWriteAccelerationStructuresPropertiesNV;
@@ -2782,6 +3092,12 @@
     if (!strcmp(name, "GetQueueCheckpointDataNV")) return (void *)table->GetQueueCheckpointDataNV;
     if (!strcmp(name, "GetQueueCheckpointData2NV")) return (void *)table->GetQueueCheckpointData2NV;
 
+    // ---- VK_EXT_present_timing extension commands
+    if (!strcmp(name, "SetSwapchainPresentTimingQueueSizeEXT")) return (void *)table->SetSwapchainPresentTimingQueueSizeEXT;
+    if (!strcmp(name, "GetSwapchainTimingPropertiesEXT")) return (void *)table->GetSwapchainTimingPropertiesEXT;
+    if (!strcmp(name, "GetSwapchainTimeDomainPropertiesEXT")) return (void *)table->GetSwapchainTimeDomainPropertiesEXT;
+    if (!strcmp(name, "GetPastPresentationTimingEXT")) return (void *)table->GetPastPresentationTimingEXT;
+
     // ---- VK_INTEL_performance_query extension commands
     if (!strcmp(name, "InitializePerformanceApiINTEL")) return (void *)table->InitializePerformanceApiINTEL;
     if (!strcmp(name, "UninitializePerformanceApiINTEL")) return (void *)table->UninitializePerformanceApiINTEL;
@@ -2857,13 +3173,33 @@
     if (!strcmp(name, "SetPrivateDataEXT")) return (void *)table->SetPrivateDataEXT;
     if (!strcmp(name, "GetPrivateDataEXT")) return (void *)table->GetPrivateDataEXT;
 
+    // ---- VK_QCOM_queue_perf_hint extension commands
+    if (!strcmp(name, "QueueSetPerfHintQCOM")) return (void *)table->QueueSetPerfHintQCOM;
+
     // ---- VK_NV_cuda_kernel_launch extension commands
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     if (!strcmp(name, "CreateCudaModuleNV")) return (void *)table->CreateCudaModuleNV;
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     if (!strcmp(name, "GetCudaModuleCacheNV")) return (void *)table->GetCudaModuleCacheNV;
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     if (!strcmp(name, "CreateCudaFunctionNV")) return (void *)table->CreateCudaFunctionNV;
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     if (!strcmp(name, "DestroyCudaModuleNV")) return (void *)table->DestroyCudaModuleNV;
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     if (!strcmp(name, "DestroyCudaFunctionNV")) return (void *)table->DestroyCudaFunctionNV;
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     if (!strcmp(name, "CmdCudaLaunchKernelNV")) return (void *)table->CmdCudaLaunchKernelNV;
+#endif // VK_ENABLE_BETA_EXTENSIONS
+
+    // ---- VK_QCOM_tile_shading extension commands
+    if (!strcmp(name, "CmdDispatchTileQCOM")) return (void *)table->CmdDispatchTileQCOM;
+    if (!strcmp(name, "CmdBeginPerTileExecutionQCOM")) return (void *)table->CmdBeginPerTileExecutionQCOM;
+    if (!strcmp(name, "CmdEndPerTileExecutionQCOM")) return (void *)table->CmdEndPerTileExecutionQCOM;
 
     // ---- VK_EXT_metal_objects extension commands
 #if defined(VK_USE_PLATFORM_METAL_EXT)
@@ -2975,6 +3311,9 @@
     // ---- VK_EXT_pageable_device_local_memory extension commands
     if (!strcmp(name, "SetDeviceMemoryPriorityEXT")) return (void *)table->SetDeviceMemoryPriorityEXT;
 
+    // ---- VK_ARM_scheduling_controls extension commands
+    if (!strcmp(name, "CmdSetDispatchParametersARM")) return (void *)table->CmdSetDispatchParametersARM;
+
     // ---- VK_VALVE_descriptor_set_host_mapping extension commands
     if (!strcmp(name, "GetDescriptorSetLayoutHostMappingInfoVALVE")) return (void *)table->GetDescriptorSetLayoutHostMappingInfoVALVE;
     if (!strcmp(name, "GetDescriptorSetHostMappingVALVE")) return (void *)table->GetDescriptorSetHostMappingVALVE;
@@ -2992,6 +3331,14 @@
     if (!strcmp(name, "CmdUpdatePipelineIndirectBufferNV")) return (void *)table->CmdUpdatePipelineIndirectBufferNV;
     if (!strcmp(name, "GetPipelineIndirectDeviceAddressNV")) return (void *)table->GetPipelineIndirectDeviceAddressNV;
 
+    // ---- VK_OHOS_external_memory extension commands
+#if defined(VK_USE_PLATFORM_OHOS)
+    if (!strcmp(name, "GetNativeBufferPropertiesOHOS")) return (void *)table->GetNativeBufferPropertiesOHOS;
+#endif // VK_USE_PLATFORM_OHOS
+#if defined(VK_USE_PLATFORM_OHOS)
+    if (!strcmp(name, "GetMemoryNativeBufferOHOS")) return (void *)table->GetMemoryNativeBufferOHOS;
+#endif // VK_USE_PLATFORM_OHOS
+
     // ---- VK_EXT_extended_dynamic_state3 extension commands
     if (!strcmp(name, "CmdSetDepthClampEnableEXT")) return (void *)table->CmdSetDepthClampEnableEXT;
     if (!strcmp(name, "CmdSetPolygonModeEXT")) return (void *)table->CmdSetPolygonModeEXT;
@@ -3025,6 +3372,18 @@
     if (!strcmp(name, "CmdSetRepresentativeFragmentTestEnableNV")) return (void *)table->CmdSetRepresentativeFragmentTestEnableNV;
     if (!strcmp(name, "CmdSetCoverageReductionModeNV")) return (void *)table->CmdSetCoverageReductionModeNV;
 
+    // ---- VK_ARM_tensors extension commands
+    if (!strcmp(name, "CreateTensorARM")) return (void *)table->CreateTensorARM;
+    if (!strcmp(name, "DestroyTensorARM")) return (void *)table->DestroyTensorARM;
+    if (!strcmp(name, "CreateTensorViewARM")) return (void *)table->CreateTensorViewARM;
+    if (!strcmp(name, "DestroyTensorViewARM")) return (void *)table->DestroyTensorViewARM;
+    if (!strcmp(name, "GetTensorMemoryRequirementsARM")) return (void *)table->GetTensorMemoryRequirementsARM;
+    if (!strcmp(name, "BindTensorMemoryARM")) return (void *)table->BindTensorMemoryARM;
+    if (!strcmp(name, "GetDeviceTensorMemoryRequirementsARM")) return (void *)table->GetDeviceTensorMemoryRequirementsARM;
+    if (!strcmp(name, "CmdCopyTensorARM")) return (void *)table->CmdCopyTensorARM;
+    if (!strcmp(name, "GetTensorOpaqueCaptureDescriptorDataARM")) return (void *)table->GetTensorOpaqueCaptureDescriptorDataARM;
+    if (!strcmp(name, "GetTensorViewOpaqueCaptureDescriptorDataARM")) return (void *)table->GetTensorViewOpaqueCaptureDescriptorDataARM;
+
     // ---- VK_EXT_shader_module_identifier extension commands
     if (!strcmp(name, "GetShaderModuleIdentifierEXT")) return (void *)table->GetShaderModuleIdentifierEXT;
     if (!strcmp(name, "GetShaderModuleCreateInfoIdentifierEXT")) return (void *)table->GetShaderModuleCreateInfoIdentifierEXT;
@@ -3049,6 +3408,10 @@
     if (!strcmp(name, "GetFramebufferTilePropertiesQCOM")) return (void *)table->GetFramebufferTilePropertiesQCOM;
     if (!strcmp(name, "GetDynamicRenderingTilePropertiesQCOM")) return (void *)table->GetDynamicRenderingTilePropertiesQCOM;
 
+    // ---- VK_NV_cooperative_vector extension commands
+    if (!strcmp(name, "ConvertCooperativeVectorMatrixNV")) return (void *)table->ConvertCooperativeVectorMatrixNV;
+    if (!strcmp(name, "CmdConvertCooperativeVectorMatrixNV")) return (void *)table->CmdConvertCooperativeVectorMatrixNV;
+
     // ---- VK_NV_low_latency2 extension commands
     if (!strcmp(name, "SetLatencySleepModeNV")) return (void *)table->SetLatencySleepModeNV;
     if (!strcmp(name, "LatencySleepNV")) return (void *)table->LatencySleepNV;
@@ -3056,6 +3419,17 @@
     if (!strcmp(name, "GetLatencyTimingsNV")) return (void *)table->GetLatencyTimingsNV;
     if (!strcmp(name, "QueueNotifyOutOfBandNV")) return (void *)table->QueueNotifyOutOfBandNV;
 
+    // ---- VK_ARM_data_graph extension commands
+    if (!strcmp(name, "CreateDataGraphPipelinesARM")) return (void *)table->CreateDataGraphPipelinesARM;
+    if (!strcmp(name, "CreateDataGraphPipelineSessionARM")) return (void *)table->CreateDataGraphPipelineSessionARM;
+    if (!strcmp(name, "GetDataGraphPipelineSessionBindPointRequirementsARM")) return (void *)table->GetDataGraphPipelineSessionBindPointRequirementsARM;
+    if (!strcmp(name, "GetDataGraphPipelineSessionMemoryRequirementsARM")) return (void *)table->GetDataGraphPipelineSessionMemoryRequirementsARM;
+    if (!strcmp(name, "BindDataGraphPipelineSessionMemoryARM")) return (void *)table->BindDataGraphPipelineSessionMemoryARM;
+    if (!strcmp(name, "DestroyDataGraphPipelineSessionARM")) return (void *)table->DestroyDataGraphPipelineSessionARM;
+    if (!strcmp(name, "CmdDispatchDataGraphARM")) return (void *)table->CmdDispatchDataGraphARM;
+    if (!strcmp(name, "GetDataGraphPipelineAvailablePropertiesARM")) return (void *)table->GetDataGraphPipelineAvailablePropertiesARM;
+    if (!strcmp(name, "GetDataGraphPipelinePropertiesARM")) return (void *)table->GetDataGraphPipelinePropertiesARM;
+
     // ---- VK_EXT_attachment_feedback_loop_dynamic_state extension commands
     if (!strcmp(name, "CmdSetAttachmentFeedbackLoopEnableEXT")) return (void *)table->CmdSetAttachmentFeedbackLoopEnableEXT;
 
@@ -3064,6 +3438,26 @@
     if (!strcmp(name, "GetScreenBufferPropertiesQNX")) return (void *)table->GetScreenBufferPropertiesQNX;
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_QCOM_tile_memory_heap extension commands
+    if (!strcmp(name, "CmdBindTileMemoryQCOM")) return (void *)table->CmdBindTileMemoryQCOM;
+
+    // ---- VK_EXT_memory_decompression extension commands
+    if (!strcmp(name, "CmdDecompressMemoryEXT")) return (void *)table->CmdDecompressMemoryEXT;
+    if (!strcmp(name, "CmdDecompressMemoryIndirectCountEXT")) return (void *)table->CmdDecompressMemoryIndirectCountEXT;
+
+    // ---- VK_NV_external_compute_queue extension commands
+    if (!strcmp(name, "CreateExternalComputeQueueNV")) return (void *)table->CreateExternalComputeQueueNV;
+    if (!strcmp(name, "DestroyExternalComputeQueueNV")) return (void *)table->DestroyExternalComputeQueueNV;
+    if (!strcmp(name, "GetExternalComputeQueueDataNV")) return (void *)table->GetExternalComputeQueueDataNV;
+
+    // ---- VK_NV_cluster_acceleration_structure extension commands
+    if (!strcmp(name, "GetClusterAccelerationStructureBuildSizesNV")) return (void *)table->GetClusterAccelerationStructureBuildSizesNV;
+    if (!strcmp(name, "CmdBuildClusterAccelerationStructureIndirectNV")) return (void *)table->CmdBuildClusterAccelerationStructureIndirectNV;
+
+    // ---- VK_NV_partitioned_acceleration_structure extension commands
+    if (!strcmp(name, "GetPartitionedAccelerationStructuresBuildSizesNV")) return (void *)table->GetPartitionedAccelerationStructuresBuildSizesNV;
+    if (!strcmp(name, "CmdBuildPartitionedAccelerationStructuresNV")) return (void *)table->CmdBuildPartitionedAccelerationStructuresNV;
+
     // ---- VK_EXT_device_generated_commands extension commands
     if (!strcmp(name, "GetGeneratedCommandsMemoryRequirementsEXT")) return (void *)table->GetGeneratedCommandsMemoryRequirementsEXT;
     if (!strcmp(name, "CmdPreprocessGeneratedCommandsEXT")) return (void *)table->CmdPreprocessGeneratedCommandsEXT;
@@ -3075,6 +3469,34 @@
     if (!strcmp(name, "UpdateIndirectExecutionSetPipelineEXT")) return (void *)table->UpdateIndirectExecutionSetPipelineEXT;
     if (!strcmp(name, "UpdateIndirectExecutionSetShaderEXT")) return (void *)table->UpdateIndirectExecutionSetShaderEXT;
 
+    // ---- VK_EXT_external_memory_metal extension commands
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    if (!strcmp(name, "GetMemoryMetalHandleEXT")) return (void *)table->GetMemoryMetalHandleEXT;
+#endif // VK_USE_PLATFORM_METAL_EXT
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    if (!strcmp(name, "GetMemoryMetalHandlePropertiesEXT")) return (void *)table->GetMemoryMetalHandlePropertiesEXT;
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+    // ---- VK_ARM_shader_instrumentation extension commands
+    if (!strcmp(name, "CreateShaderInstrumentationARM")) return (void *)table->CreateShaderInstrumentationARM;
+    if (!strcmp(name, "DestroyShaderInstrumentationARM")) return (void *)table->DestroyShaderInstrumentationARM;
+    if (!strcmp(name, "CmdBeginShaderInstrumentationARM")) return (void *)table->CmdBeginShaderInstrumentationARM;
+    if (!strcmp(name, "CmdEndShaderInstrumentationARM")) return (void *)table->CmdEndShaderInstrumentationARM;
+    if (!strcmp(name, "GetShaderInstrumentationValuesARM")) return (void *)table->GetShaderInstrumentationValuesARM;
+    if (!strcmp(name, "ClearShaderInstrumentationMetricsARM")) return (void *)table->ClearShaderInstrumentationMetricsARM;
+
+    // ---- VK_EXT_fragment_density_map_offset extension commands
+    if (!strcmp(name, "CmdEndRendering2EXT")) return (void *)table->CmdEndRendering2EXT;
+
+    // ---- VK_EXT_custom_resolve extension commands
+    if (!strcmp(name, "CmdBeginCustomResolveEXT")) return (void *)table->CmdBeginCustomResolveEXT;
+
+    // ---- VK_NV_compute_occupancy_priority extension commands
+    if (!strcmp(name, "CmdSetComputeOccupancyPriorityNV")) return (void *)table->CmdSetComputeOccupancyPriorityNV;
+
+    // ---- VK_EXT_primitive_restart_index extension commands
+    if (!strcmp(name, "CmdSetPrimitiveRestartIndexEXT")) return (void *)table->CmdSetPrimitiveRestartIndexEXT;
+
     // ---- VK_KHR_acceleration_structure extension commands
     if (!strcmp(name, "CreateAccelerationStructureKHR")) return (void *)table->CreateAccelerationStructureKHR;
     if (!strcmp(name, "DestroyAccelerationStructureKHR")) return (void *)table->DestroyAccelerationStructureKHR;
@@ -3305,6 +3727,9 @@
     if (!strcmp(name, "DestroyDebugUtilsMessengerEXT")) return (void *)table->DestroyDebugUtilsMessengerEXT;
     if (!strcmp(name, "SubmitDebugUtilsMessageEXT")) return (void *)table->SubmitDebugUtilsMessageEXT;
 
+    // ---- VK_EXT_descriptor_heap extension commands
+    if (!strcmp(name, "GetPhysicalDeviceDescriptorSizeEXT")) return (void *)table->GetPhysicalDeviceDescriptorSizeEXT;
+
     // ---- VK_EXT_sample_locations extension commands
     if (!strcmp(name, "GetPhysicalDeviceMultisamplePropertiesEXT")) return (void *)table->GetPhysicalDeviceMultisamplePropertiesEXT;
 
@@ -3366,12 +3791,47 @@
     if (!strcmp(name, "GetPhysicalDeviceScreenPresentationSupportQNX")) return (void *)table->GetPhysicalDeviceScreenPresentationSupportQNX;
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_ARM_tensors extension commands
+    if (!strcmp(name, "GetPhysicalDeviceExternalTensorPropertiesARM")) return (void *)table->GetPhysicalDeviceExternalTensorPropertiesARM;
+
     // ---- VK_NV_optical_flow extension commands
     if (!strcmp(name, "GetPhysicalDeviceOpticalFlowImageFormatsNV")) return (void *)table->GetPhysicalDeviceOpticalFlowImageFormatsNV;
 
+    // ---- VK_NV_cooperative_vector extension commands
+    if (!strcmp(name, "GetPhysicalDeviceCooperativeVectorPropertiesNV")) return (void *)table->GetPhysicalDeviceCooperativeVectorPropertiesNV;
+
+    // ---- VK_ARM_data_graph extension commands
+    if (!strcmp(name, "GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM")) return (void *)table->GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM;
+    if (!strcmp(name, "GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM")) return (void *)table->GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM;
+
+    // ---- VK_ARM_data_graph_instruction_set_tosa extension commands
+    if (!strcmp(name, "GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM")) return (void *)table->GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM;
+
+    // ---- VK_OHOS_surface extension commands
+#if defined(VK_USE_PLATFORM_OHOS)
+    if (!strcmp(name, "CreateSurfaceOHOS")) return (void *)table->CreateSurfaceOHOS;
+#endif // VK_USE_PLATFORM_OHOS
+
     // ---- VK_NV_cooperative_matrix2 extension commands
     if (!strcmp(name, "GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV")) return (void *)table->GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV;
 
+    // ---- VK_ARM_performance_counters_by_region extension commands
+    if (!strcmp(name, "EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM")) return (void *)table->EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM;
+
+    // ---- VK_ARM_shader_instrumentation extension commands
+    if (!strcmp(name, "EnumeratePhysicalDeviceShaderInstrumentationMetricsARM")) return (void *)table->EnumeratePhysicalDeviceShaderInstrumentationMetricsARM;
+
+    // ---- VK_ARM_data_graph_optical_flow extension commands
+    if (!strcmp(name, "GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM")) return (void *)table->GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM;
+
+    // ---- VK_SEC_ubm_surface extension commands
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    if (!strcmp(name, "CreateUbmSurfaceSEC")) return (void *)table->CreateUbmSurfaceSEC;
+#endif // VK_USE_PLATFORM_UBM_SEC
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    if (!strcmp(name, "GetPhysicalDeviceUbmPresentationSupportSEC")) return (void *)table->GetPhysicalDeviceUbmPresentationSupportSEC;
+#endif // VK_USE_PLATFORM_UBM_SEC
+
     *found_name = false;
     return NULL;
 }
@@ -4784,6 +5244,319 @@
 }
 
 
+// ---- VK_KHR_device_address_commands extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdBindIndexBuffer3KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkBindIndexBuffer3InfoKHR*            pInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBindIndexBuffer3KHR: Invalid commandBuffer "
+                   "[VUID-vkCmdBindIndexBuffer3KHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBindIndexBuffer3KHR(commandBuffer, pInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers3KHR(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    firstBinding,
+    uint32_t                                    bindingCount,
+    const VkBindVertexBuffer3InfoKHR*           pBindingInfos) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBindVertexBuffers3KHR: Invalid commandBuffer "
+                   "[VUID-vkCmdBindVertexBuffers3KHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBindVertexBuffers3KHR(commandBuffer, firstBinding, bindingCount, pBindingInfos);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndirect2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkDrawIndirect2InfoKHR*               pInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDrawIndirect2KHR: Invalid commandBuffer "
+                   "[VUID-vkCmdDrawIndirect2KHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDrawIndirect2KHR(commandBuffer, pInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirect2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkDrawIndirect2InfoKHR*               pInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDrawIndexedIndirect2KHR: Invalid commandBuffer "
+                   "[VUID-vkCmdDrawIndexedIndirect2KHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDrawIndexedIndirect2KHR(commandBuffer, pInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDispatchIndirect2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkDispatchIndirect2InfoKHR*           pInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDispatchIndirect2KHR: Invalid commandBuffer "
+                   "[VUID-vkCmdDispatchIndirect2KHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDispatchIndirect2KHR(commandBuffer, pInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyMemoryKHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkCopyDeviceMemoryInfoKHR*            pCopyMemoryInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdCopyMemoryKHR: Invalid commandBuffer "
+                   "[VUID-vkCmdCopyMemoryKHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdCopyMemoryKHR(commandBuffer, pCopyMemoryInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyMemoryToImageKHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkCopyDeviceMemoryImageInfoKHR*       pCopyMemoryInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdCopyMemoryToImageKHR: Invalid commandBuffer "
+                   "[VUID-vkCmdCopyMemoryToImageKHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdCopyMemoryToImageKHR(commandBuffer, pCopyMemoryInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyImageToMemoryKHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkCopyDeviceMemoryImageInfoKHR*       pCopyMemoryInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdCopyImageToMemoryKHR: Invalid commandBuffer "
+                   "[VUID-vkCmdCopyImageToMemoryKHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdCopyImageToMemoryKHR(commandBuffer, pCopyMemoryInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdUpdateMemoryKHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkDeviceAddressRangeKHR*              pDstRange,
+    VkAddressCommandFlagsKHR                    dstFlags,
+    VkDeviceSize                                dataSize,
+    const void*                                 pData) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdUpdateMemoryKHR: Invalid commandBuffer "
+                   "[VUID-vkCmdUpdateMemoryKHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdUpdateMemoryKHR(commandBuffer, pDstRange, dstFlags, dataSize, pData);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdFillMemoryKHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkDeviceAddressRangeKHR*              pDstRange,
+    VkAddressCommandFlagsKHR                    dstFlags,
+    uint32_t                                    data) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdFillMemoryKHR: Invalid commandBuffer "
+                   "[VUID-vkCmdFillMemoryKHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdFillMemoryKHR(commandBuffer, pDstRange, dstFlags, data);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyQueryPoolResultsToMemoryKHR(
+    VkCommandBuffer                             commandBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    firstQuery,
+    uint32_t                                    queryCount,
+    const VkStridedDeviceAddressRangeKHR*       pDstRange,
+    VkAddressCommandFlagsKHR                    dstFlags,
+    VkQueryResultFlags                          queryResultFlags) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdCopyQueryPoolResultsToMemoryKHR: Invalid commandBuffer "
+                   "[VUID-vkCmdCopyQueryPoolResultsToMemoryKHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdCopyQueryPoolResultsToMemoryKHR(commandBuffer, queryPool, firstQuery, queryCount, pDstRange, dstFlags, queryResultFlags);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndirectCount2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkDrawIndirectCount2InfoKHR*          pInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDrawIndirectCount2KHR: Invalid commandBuffer "
+                   "[VUID-vkCmdDrawIndirectCount2KHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDrawIndirectCount2KHR(commandBuffer, pInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirectCount2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkDrawIndirectCount2InfoKHR*          pInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDrawIndexedIndirectCount2KHR: Invalid commandBuffer "
+                   "[VUID-vkCmdDrawIndexedIndirectCount2KHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDrawIndexedIndirectCount2KHR(commandBuffer, pInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginConditionalRendering2EXT(
+    VkCommandBuffer                             commandBuffer,
+    const VkConditionalRenderingBeginInfo2EXT*  pConditionalRenderingBegin) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBeginConditionalRendering2EXT: Invalid commandBuffer "
+                   "[VUID-vkCmdBeginConditionalRendering2EXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBeginConditionalRendering2EXT(commandBuffer, pConditionalRenderingBegin);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBindTransformFeedbackBuffers2EXT(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    firstBinding,
+    uint32_t                                    bindingCount,
+    const VkBindTransformFeedbackBuffer2InfoEXT* pBindingInfos) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBindTransformFeedbackBuffers2EXT: Invalid commandBuffer "
+                   "[VUID-vkCmdBindTransformFeedbackBuffers2EXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBindTransformFeedbackBuffers2EXT(commandBuffer, firstBinding, bindingCount, pBindingInfos);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginTransformFeedback2EXT(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    firstCounterRange,
+    uint32_t                                    counterRangeCount,
+    const VkBindTransformFeedbackBuffer2InfoEXT* pCounterInfos) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBeginTransformFeedback2EXT: Invalid commandBuffer "
+                   "[VUID-vkCmdBeginTransformFeedback2EXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBeginTransformFeedback2EXT(commandBuffer, firstCounterRange, counterRangeCount, pCounterInfos);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndTransformFeedback2EXT(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    firstCounterRange,
+    uint32_t                                    counterRangeCount,
+    const VkBindTransformFeedbackBuffer2InfoEXT* pCounterInfos) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdEndTransformFeedback2EXT: Invalid commandBuffer "
+                   "[VUID-vkCmdEndTransformFeedback2EXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdEndTransformFeedback2EXT(commandBuffer, firstCounterRange, counterRangeCount, pCounterInfos);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndirectByteCount2EXT(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    instanceCount,
+    uint32_t                                    firstInstance,
+    const VkBindTransformFeedbackBuffer2InfoEXT* pCounterInfo,
+    uint32_t                                    counterOffset,
+    uint32_t                                    vertexStride) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDrawIndirectByteCount2EXT: Invalid commandBuffer "
+                   "[VUID-vkCmdDrawIndirectByteCount2EXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDrawIndirectByteCount2EXT(commandBuffer, instanceCount, firstInstance, pCounterInfo, counterOffset, vertexStride);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksIndirect2EXT(
+    VkCommandBuffer                             commandBuffer,
+    const VkDrawIndirect2InfoKHR*               pInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDrawMeshTasksIndirect2EXT: Invalid commandBuffer "
+                   "[VUID-vkCmdDrawMeshTasksIndirect2EXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDrawMeshTasksIndirect2EXT(commandBuffer, pInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksIndirectCount2EXT(
+    VkCommandBuffer                             commandBuffer,
+    const VkDrawIndirectCount2InfoKHR*          pInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDrawMeshTasksIndirectCount2EXT: Invalid commandBuffer "
+                   "[VUID-vkCmdDrawMeshTasksIndirectCount2EXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDrawMeshTasksIndirectCount2EXT(commandBuffer, pInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdWriteMarkerToMemoryAMD(
+    VkCommandBuffer                             commandBuffer,
+    const VkMemoryMarkerInfoAMD*                pInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdWriteMarkerToMemoryAMD: Invalid commandBuffer "
+                   "[VUID-vkCmdWriteMarkerToMemoryAMD-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdWriteMarkerToMemoryAMD(commandBuffer, pInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateAccelerationStructure2KHR(
+    VkDevice                                    device,
+    const VkAccelerationStructureCreateInfo2KHR* pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkAccelerationStructureKHR*                 pAccelerationStructure) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCreateAccelerationStructure2KHR: Invalid device "
+                   "[VUID-vkCreateAccelerationStructure2KHR-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->CreateAccelerationStructure2KHR(device, pCreateInfo, pAllocator, pAccelerationStructure);
+}
+
+
 // ---- VK_KHR_copy_commands2 extension trampoline/terminators
 
 VKAPI_ATTR void VKAPI_CALL CmdCopyBuffer2KHR(
@@ -4989,6 +5762,23 @@
 }
 
 
+// ---- VK_KHR_present_wait2 extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL WaitForPresent2KHR(
+    VkDevice                                    device,
+    VkSwapchainKHR                              swapchain,
+    const VkPresentWait2InfoKHR*                pPresentWait2Info) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkWaitForPresent2KHR: Invalid device "
+                   "[VUID-vkWaitForPresent2KHR-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->WaitForPresent2KHR(device, swapchain, pPresentWait2Info);
+}
+
+
 // ---- VK_KHR_pipeline_binary extension trampoline/terminators
 
 VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineBinariesKHR(
@@ -5065,6 +5855,22 @@
 }
 
 
+// ---- VK_KHR_swapchain_maintenance1 extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL ReleaseSwapchainImagesKHR(
+    VkDevice                                    device,
+    const VkReleaseSwapchainImagesInfoKHR*      pReleaseInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkReleaseSwapchainImagesKHR: Invalid device "
+                   "[VUID-vkReleaseSwapchainImagesKHR-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->ReleaseSwapchainImagesKHR(device, pReleaseInfo);
+}
+
+
 // ---- VK_KHR_cooperative_matrix extension trampoline/terminators
 
 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCooperativeMatrixPropertiesKHR(
@@ -5245,6 +6051,82 @@
 }
 
 
+// ---- VK_KHR_copy_memory_indirect extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyMemoryIndirectKHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkCopyMemoryIndirectInfoKHR*          pCopyMemoryIndirectInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdCopyMemoryIndirectKHR: Invalid commandBuffer "
+                   "[VUID-vkCmdCopyMemoryIndirectKHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdCopyMemoryIndirectKHR(commandBuffer, pCopyMemoryIndirectInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyMemoryToImageIndirectKHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkCopyMemoryToImageIndirectInfoKHR*   pCopyMemoryToImageIndirectInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdCopyMemoryToImageIndirectKHR: Invalid commandBuffer "
+                   "[VUID-vkCmdCopyMemoryToImageIndirectKHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdCopyMemoryToImageIndirectKHR(commandBuffer, pCopyMemoryToImageIndirectInfo);
+}
+
+
+// ---- VK_KHR_device_fault extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetDeviceFaultReportsKHR(
+    VkDevice                                    device,
+    uint64_t                                    timeout,
+    uint32_t*                                   pFaultCounts,
+    VkDeviceFaultInfoKHR*                       pFaultInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetDeviceFaultReportsKHR: Invalid device "
+                   "[VUID-vkGetDeviceFaultReportsKHR-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetDeviceFaultReportsKHR(device, timeout, pFaultCounts, pFaultInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetDeviceFaultDebugInfoKHR(
+    VkDevice                                    device,
+    VkDeviceFaultDebugInfoKHR*                  pDebugInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetDeviceFaultDebugInfoKHR: Invalid device "
+                   "[VUID-vkGetDeviceFaultDebugInfoKHR-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetDeviceFaultDebugInfoKHR(device, pDebugInfo);
+}
+
+
+// ---- VK_KHR_maintenance10 extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdEndRendering2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkRenderingEndInfoKHR*                pRenderingEndInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdEndRendering2KHR: Invalid commandBuffer "
+                   "[VUID-vkCmdEndRendering2KHR-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdEndRendering2KHR(commandBuffer, pRenderingEndInfo);
+}
+
+
 // ---- VK_EXT_debug_marker extension trampoline/terminators
 
 VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(
@@ -5289,10 +6171,9 @@
     // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.
     } else if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
         if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) {
-            VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pTagInfo->object;
-            if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR)
-                && icd_term->surface_list.list[icd_surface->surface_index]) {
-                local_tag_info.object = (uint64_t)icd_term->surface_list.list[icd_surface->surface_index];
+            VkSurfaceKHR surface = (VkSurfaceKHR)(uintptr_t)pTagInfo->object;
+            if (wsi_unwrap_icd_surface(icd_term, &surface) == VK_SUCCESS) {
+                local_tag_info.object = (uint64_t)surface;
             }
         }
     // If this is an instance we have to replace it with the proper one for the next call.
@@ -5348,10 +6229,9 @@
     // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.
     } else if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
         if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) {
-            VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pNameInfo->object;
-            if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR)
-                && icd_term->surface_list.list[icd_surface->surface_index]) {
-                local_name_info.object = (uint64_t)icd_term->surface_list.list[icd_surface->surface_index];
+            VkSurfaceKHR surface = (VkSurfaceKHR)(uintptr_t)pNameInfo->object;
+            if (wsi_unwrap_icd_surface(icd_term, &surface) == VK_SUCCESS) {
+                local_name_info.object = (uint64_t)surface;
             }
         }
     // If this is an instance we have to replace it with the proper one for the next call.
@@ -5621,6 +6501,20 @@
     return disp->GetImageViewAddressNVX(device, imageView, pProperties);
 }
 
+VKAPI_ATTR uint64_t VKAPI_CALL GetDeviceCombinedImageSamplerIndexNVX(
+    VkDevice                                    device,
+    uint64_t                                    imageViewIndex,
+    uint64_t                                    samplerIndex) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetDeviceCombinedImageSamplerIndexNVX: Invalid device "
+                   "[VUID-vkGetDeviceCombinedImageSamplerIndexNVX-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetDeviceCombinedImageSamplerIndexNVX(device, imageViewIndex, samplerIndex);
+}
+
 
 // ---- VK_AMD_draw_indirect_count extension trampoline/terminators
 
@@ -5952,10 +6846,9 @@
     // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.
     } else if (pNameInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
         if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) {
-            VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pNameInfo->objectHandle;
-            if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR)
-                && icd_term->surface_list.list[icd_surface->surface_index]) {
-                local_name_info.objectHandle = (uint64_t)icd_term->surface_list.list[icd_surface->surface_index];
+            VkSurfaceKHR surface = (VkSurfaceKHR)(uintptr_t)pNameInfo->objectHandle;
+            if (wsi_unwrap_icd_surface(icd_term, &surface) == VK_SUCCESS) {
+                local_name_info.objectHandle = (uint64_t)surface;
             }
         }
     // If this is an instance we have to replace it with the proper one for the next call.
@@ -6015,10 +6908,9 @@
     // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.
     } else if (pTagInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
         if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) {
-            VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pTagInfo->objectHandle;
-            if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR)
-                && icd_term->surface_list.list[icd_surface->surface_index]) {
-                local_tag_info.objectHandle = (uint64_t)icd_term->surface_list.list[icd_surface->surface_index];
+            VkSurfaceKHR surface = (VkSurfaceKHR)(uintptr_t)pTagInfo->objectHandle;
+            if (wsi_unwrap_icd_surface(icd_term, &surface) == VK_SUCCESS) {
+                local_tag_info.objectHandle = (uint64_t)surface;
             }
         }
     // If this is an instance we have to replace it with the proper one for the next call.
@@ -6355,6 +7247,164 @@
 
 #endif // VK_ENABLE_BETA_EXTENSIONS
 
+// ---- VK_EXT_descriptor_heap extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL WriteSamplerDescriptorsEXT(
+    VkDevice                                    device,
+    uint32_t                                    samplerCount,
+    const VkSamplerCreateInfo*                  pSamplers,
+    const VkHostAddressRangeEXT*                pDescriptors) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkWriteSamplerDescriptorsEXT: Invalid device "
+                   "[VUID-vkWriteSamplerDescriptorsEXT-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->WriteSamplerDescriptorsEXT(device, samplerCount, pSamplers, pDescriptors);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL WriteResourceDescriptorsEXT(
+    VkDevice                                    device,
+    uint32_t                                    resourceCount,
+    const VkResourceDescriptorInfoEXT*          pResources,
+    const VkHostAddressRangeEXT*                pDescriptors) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkWriteResourceDescriptorsEXT: Invalid device "
+                   "[VUID-vkWriteResourceDescriptorsEXT-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->WriteResourceDescriptorsEXT(device, resourceCount, pResources, pDescriptors);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBindSamplerHeapEXT(
+    VkCommandBuffer                             commandBuffer,
+    const VkBindHeapInfoEXT*                    pBindInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBindSamplerHeapEXT: Invalid commandBuffer "
+                   "[VUID-vkCmdBindSamplerHeapEXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBindSamplerHeapEXT(commandBuffer, pBindInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBindResourceHeapEXT(
+    VkCommandBuffer                             commandBuffer,
+    const VkBindHeapInfoEXT*                    pBindInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBindResourceHeapEXT: Invalid commandBuffer "
+                   "[VUID-vkCmdBindResourceHeapEXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBindResourceHeapEXT(commandBuffer, pBindInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdPushDataEXT(
+    VkCommandBuffer                             commandBuffer,
+    const VkPushDataInfoEXT*                    pPushDataInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdPushDataEXT: Invalid commandBuffer "
+                   "[VUID-vkCmdPushDataEXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdPushDataEXT(commandBuffer, pPushDataInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetImageOpaqueCaptureDataEXT(
+    VkDevice                                    device,
+    uint32_t                                    imageCount,
+    const VkImage*                              pImages,
+    VkHostAddressRangeEXT*                      pDatas) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetImageOpaqueCaptureDataEXT: Invalid device "
+                   "[VUID-vkGetImageOpaqueCaptureDataEXT-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetImageOpaqueCaptureDataEXT(device, imageCount, pImages, pDatas);
+}
+
+VKAPI_ATTR VkDeviceSize VKAPI_CALL GetPhysicalDeviceDescriptorSizeEXT(
+    VkPhysicalDevice                            physicalDevice,
+    VkDescriptorType                            descriptorType) {
+    const VkLayerInstanceDispatchTable *disp;
+    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetPhysicalDeviceDescriptorSizeEXT: Invalid physicalDevice "
+                   "[VUID-vkGetPhysicalDeviceDescriptorSizeEXT-physicalDevice-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp = loader_get_instance_layer_dispatch(physicalDevice);
+    return disp->GetPhysicalDeviceDescriptorSizeEXT(unwrapped_phys_dev, descriptorType);
+}
+
+VKAPI_ATTR VkDeviceSize VKAPI_CALL terminator_GetPhysicalDeviceDescriptorSizeEXT(
+    VkPhysicalDevice                            physicalDevice,
+    VkDescriptorType                            descriptorType) {
+    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+    if (NULL == icd_term->dispatch.GetPhysicalDeviceDescriptorSizeEXT) {
+        loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
+                   "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceDescriptorSizeEXT");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return icd_term->dispatch.GetPhysicalDeviceDescriptorSizeEXT(phys_dev_term->phys_dev, descriptorType);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL RegisterCustomBorderColorEXT(
+    VkDevice                                    device,
+    const VkSamplerCustomBorderColorCreateInfoEXT* pBorderColor,
+    VkBool32                                    requestIndex,
+    uint32_t*                                   pIndex) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkRegisterCustomBorderColorEXT: Invalid device "
+                   "[VUID-vkRegisterCustomBorderColorEXT-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->RegisterCustomBorderColorEXT(device, pBorderColor, requestIndex, pIndex);
+}
+
+VKAPI_ATTR void VKAPI_CALL UnregisterCustomBorderColorEXT(
+    VkDevice                                    device,
+    uint32_t                                    index) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkUnregisterCustomBorderColorEXT: Invalid device "
+                   "[VUID-vkUnregisterCustomBorderColorEXT-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->UnregisterCustomBorderColorEXT(device, index);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetTensorOpaqueCaptureDataARM(
+    VkDevice                                    device,
+    uint32_t                                    tensorCount,
+    const VkTensorARM*                          pTensors,
+    VkHostAddressRangeEXT*                      pDatas) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetTensorOpaqueCaptureDataARM: Invalid device "
+                   "[VUID-vkGetTensorOpaqueCaptureDataARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetTensorOpaqueCaptureDataARM(device, tensorCount, pTensors, pDatas);
+}
+
+
 // ---- VK_EXT_sample_locations extension trampoline/terminators
 
 VKAPI_ATTR void VKAPI_CALL CmdSetSampleLocationsEXT(
@@ -6561,7 +7611,7 @@
 VKAPI_ATTR void VKAPI_CALL GetAccelerationStructureMemoryRequirementsNV(
     VkDevice                                    device,
     const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo,
-    VkMemoryRequirements2KHR*                   pMemoryRequirements) {
+    VkMemoryRequirements2*                      pMemoryRequirements) {
     const VkLayerDispatchTable *disp = loader_get_dispatch(device);
     if (NULL == disp) {
         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
@@ -6664,6 +7714,9 @@
     return disp->CreateRayTracingPipelinesNV(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
 }
 
+
+// ---- VK_KHR_ray_tracing_pipeline extension trampoline/terminators
+
 VKAPI_ATTR VkResult VKAPI_CALL GetRayTracingShaderGroupHandlesKHR(
     VkDevice                                    device,
     VkPipeline                                  pipeline,
@@ -6681,6 +7734,9 @@
     return disp->GetRayTracingShaderGroupHandlesKHR(device, pipeline, firstGroup, groupCount, dataSize, pData);
 }
 
+
+// ---- VK_NV_ray_tracing extension trampoline/terminators
+
 VKAPI_ATTR VkResult VKAPI_CALL GetRayTracingShaderGroupHandlesNV(
     VkDevice                                    device,
     VkPipeline                                  pipeline,
@@ -6975,6 +8031,67 @@
 }
 
 
+// ---- VK_EXT_present_timing extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL SetSwapchainPresentTimingQueueSizeEXT(
+    VkDevice                                    device,
+    VkSwapchainKHR                              swapchain,
+    uint32_t                                    size) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkSetSwapchainPresentTimingQueueSizeEXT: Invalid device "
+                   "[VUID-vkSetSwapchainPresentTimingQueueSizeEXT-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->SetSwapchainPresentTimingQueueSizeEXT(device, swapchain, size);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainTimingPropertiesEXT(
+    VkDevice                                    device,
+    VkSwapchainKHR                              swapchain,
+    VkSwapchainTimingPropertiesEXT*             pSwapchainTimingProperties,
+    uint64_t*                                   pSwapchainTimingPropertiesCounter) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetSwapchainTimingPropertiesEXT: Invalid device "
+                   "[VUID-vkGetSwapchainTimingPropertiesEXT-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetSwapchainTimingPropertiesEXT(device, swapchain, pSwapchainTimingProperties, pSwapchainTimingPropertiesCounter);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainTimeDomainPropertiesEXT(
+    VkDevice                                    device,
+    VkSwapchainKHR                              swapchain,
+    VkSwapchainTimeDomainPropertiesEXT*         pSwapchainTimeDomainProperties,
+    uint64_t*                                   pTimeDomainsCounter) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetSwapchainTimeDomainPropertiesEXT: Invalid device "
+                   "[VUID-vkGetSwapchainTimeDomainPropertiesEXT-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetSwapchainTimeDomainPropertiesEXT(device, swapchain, pSwapchainTimeDomainProperties, pTimeDomainsCounter);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPastPresentationTimingEXT(
+    VkDevice                                    device,
+    const VkPastPresentationTimingInfoEXT*      pPastPresentationTimingInfo,
+    VkPastPresentationTimingPropertiesEXT*      pPastPresentationTimingProperties) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetPastPresentationTimingEXT: Invalid device "
+                   "[VUID-vkGetPastPresentationTimingEXT-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetPastPresentationTimingEXT(device, pPastPresentationTimingInfo, pPastPresentationTimingProperties);
+}
+
+
 // ---- VK_INTEL_performance_query extension trampoline/terminators
 
 VKAPI_ATTR VkResult VKAPI_CALL InitializePerformanceApiINTEL(
@@ -7508,7 +8625,7 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL ReleaseSwapchainImagesEXT(
     VkDevice                                    device,
-    const VkReleaseSwapchainImagesInfoEXT*      pReleaseInfo) {
+    const VkReleaseSwapchainImagesInfoKHR*      pReleaseInfo) {
     const VkLayerDispatchTable *disp = loader_get_dispatch(device);
     if (NULL == disp) {
         loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
@@ -7753,8 +8870,25 @@
 }
 
 
+// ---- VK_QCOM_queue_perf_hint extension trampoline/terminators
+
+VKAPI_ATTR VkResult                   VKAPI_CALL QueueSetPerfHintQCOM(
+    VkQueue                                     queue,
+    const VkPerfHintInfoQCOM*                   pPerfHintInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(queue);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkQueueSetPerfHintQCOM: Invalid queue "
+                   "[VUID-vkQueueSetPerfHintQCOM-queue-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->QueueSetPerfHintQCOM(queue, pPerfHintInfo);
+}
+
+
 // ---- VK_NV_cuda_kernel_launch extension trampoline/terminators
 
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
 VKAPI_ATTR VkResult VKAPI_CALL CreateCudaModuleNV(
     VkDevice                                    device,
     const VkCudaModuleCreateInfoNV*             pCreateInfo,
@@ -7770,6 +8904,8 @@
     return disp->CreateCudaModuleNV(device, pCreateInfo, pAllocator, pModule);
 }
 
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
 VKAPI_ATTR VkResult VKAPI_CALL GetCudaModuleCacheNV(
     VkDevice                                    device,
     VkCudaModuleNV                              module,
@@ -7785,6 +8921,8 @@
     return disp->GetCudaModuleCacheNV(device, module, pCacheSize, pCacheData);
 }
 
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
 VKAPI_ATTR VkResult VKAPI_CALL CreateCudaFunctionNV(
     VkDevice                                    device,
     const VkCudaFunctionCreateInfoNV*           pCreateInfo,
@@ -7800,6 +8938,8 @@
     return disp->CreateCudaFunctionNV(device, pCreateInfo, pAllocator, pFunction);
 }
 
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
 VKAPI_ATTR void VKAPI_CALL DestroyCudaModuleNV(
     VkDevice                                    device,
     VkCudaModuleNV                              module,
@@ -7814,6 +8954,8 @@
     disp->DestroyCudaModuleNV(device, module, pAllocator);
 }
 
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
 VKAPI_ATTR void VKAPI_CALL DestroyCudaFunctionNV(
     VkDevice                                    device,
     VkCudaFunctionNV                            function,
@@ -7828,6 +8970,8 @@
     disp->DestroyCudaFunctionNV(device, function, pAllocator);
 }
 
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
 VKAPI_ATTR void VKAPI_CALL CmdCudaLaunchKernelNV(
     VkCommandBuffer                             commandBuffer,
     const VkCudaLaunchInfoNV*                   pLaunchInfo) {
@@ -7841,6 +8985,49 @@
     disp->CmdCudaLaunchKernelNV(commandBuffer, pLaunchInfo);
 }
 
+#endif // VK_ENABLE_BETA_EXTENSIONS
+
+// ---- VK_QCOM_tile_shading extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdDispatchTileQCOM(
+    VkCommandBuffer                             commandBuffer,
+    const VkDispatchTileInfoQCOM*               pDispatchTileInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDispatchTileQCOM: Invalid commandBuffer "
+                   "[VUID-vkCmdDispatchTileQCOM-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDispatchTileQCOM(commandBuffer, pDispatchTileInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginPerTileExecutionQCOM(
+    VkCommandBuffer                             commandBuffer,
+    const VkPerTileBeginInfoQCOM*               pPerTileBeginInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBeginPerTileExecutionQCOM: Invalid commandBuffer "
+                   "[VUID-vkCmdBeginPerTileExecutionQCOM-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBeginPerTileExecutionQCOM(commandBuffer, pPerTileBeginInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndPerTileExecutionQCOM(
+    VkCommandBuffer                             commandBuffer,
+    const VkPerTileEndInfoQCOM*                 pPerTileEndInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdEndPerTileExecutionQCOM: Invalid commandBuffer "
+                   "[VUID-vkCmdEndPerTileExecutionQCOM-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdEndPerTileExecutionQCOM(commandBuffer, pPerTileEndInfo);
+}
+
 
 // ---- VK_EXT_metal_objects extension trampoline/terminators
 
@@ -8363,7 +9550,7 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL GetPipelinePropertiesEXT(
     VkDevice                                    device,
-    const VkPipelineInfoEXT*                    pPipelineInfo,
+    const VkPipelineInfoKHR*                    pPipelineInfo,
     VkBaseOutStructure*                         pPipelineProperties) {
     const VkLayerDispatchTable *disp = loader_get_dispatch(device);
     if (NULL == disp) {
@@ -8446,7 +9633,7 @@
 
 // ---- VK_EXT_color_write_enable extension trampoline/terminators
 
-VKAPI_ATTR void                                    VKAPI_CALL CmdSetColorWriteEnableEXT(
+VKAPI_ATTR void VKAPI_CALL CmdSetColorWriteEnableEXT(
     VkCommandBuffer                             commandBuffer,
     uint32_t                                    attachmentCount,
     const VkBool32*                             pColorWriteEnables) {
@@ -8754,6 +9941,22 @@
 }
 
 
+// ---- VK_ARM_scheduling_controls extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdSetDispatchParametersARM(
+    VkCommandBuffer                             commandBuffer,
+    const VkDispatchParametersARM*              pDispatchParameters) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdSetDispatchParametersARM: Invalid commandBuffer "
+                   "[VUID-vkCmdSetDispatchParametersARM-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdSetDispatchParametersARM(commandBuffer, pDispatchParameters);
+}
+
+
 // ---- VK_VALVE_descriptor_set_host_mapping extension trampoline/terminators
 
 VKAPI_ATTR void VKAPI_CALL GetDescriptorSetLayoutHostMappingInfoVALVE(
@@ -8897,6 +10100,41 @@
 }
 
 
+// ---- VK_OHOS_external_memory extension trampoline/terminators
+
+#if defined(VK_USE_PLATFORM_OHOS)
+VKAPI_ATTR VkResult VKAPI_CALL GetNativeBufferPropertiesOHOS(
+    VkDevice                                    device,
+    const struct OH_NativeBuffer*               buffer,
+    VkNativeBufferPropertiesOHOS*               pProperties) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetNativeBufferPropertiesOHOS: Invalid device "
+                   "[VUID-vkGetNativeBufferPropertiesOHOS-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetNativeBufferPropertiesOHOS(device, buffer, pProperties);
+}
+
+#endif // VK_USE_PLATFORM_OHOS
+#if defined(VK_USE_PLATFORM_OHOS)
+VKAPI_ATTR VkResult VKAPI_CALL GetMemoryNativeBufferOHOS(
+    VkDevice                                    device,
+    const VkMemoryGetNativeBufferInfoOHOS*      pInfo,
+    struct OH_NativeBuffer**                    pBuffer) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetMemoryNativeBufferOHOS: Invalid device "
+                   "[VUID-vkGetMemoryNativeBufferOHOS-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetMemoryNativeBufferOHOS(device, pInfo, pBuffer);
+}
+
+#endif // VK_USE_PLATFORM_OHOS
+
 // ---- VK_EXT_extended_dynamic_state3 extension trampoline/terminators
 
 VKAPI_ATTR void VKAPI_CALL CmdSetDepthClampEnableEXT(
@@ -9315,6 +10553,180 @@
 }
 
 
+// ---- VK_ARM_tensors extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateTensorARM(
+    VkDevice                                    device,
+    const VkTensorCreateInfoARM*                pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkTensorARM*                                pTensor) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCreateTensorARM: Invalid device "
+                   "[VUID-vkCreateTensorARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->CreateTensorARM(device, pCreateInfo, pAllocator, pTensor);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyTensorARM(
+    VkDevice                                    device,
+    VkTensorARM                                 tensor,
+    const VkAllocationCallbacks*                pAllocator) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkDestroyTensorARM: Invalid device "
+                   "[VUID-vkDestroyTensorARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->DestroyTensorARM(device, tensor, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateTensorViewARM(
+    VkDevice                                    device,
+    const VkTensorViewCreateInfoARM*            pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkTensorViewARM*                            pView) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCreateTensorViewARM: Invalid device "
+                   "[VUID-vkCreateTensorViewARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->CreateTensorViewARM(device, pCreateInfo, pAllocator, pView);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyTensorViewARM(
+    VkDevice                                    device,
+    VkTensorViewARM                             tensorView,
+    const VkAllocationCallbacks*                pAllocator) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkDestroyTensorViewARM: Invalid device "
+                   "[VUID-vkDestroyTensorViewARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->DestroyTensorViewARM(device, tensorView, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetTensorMemoryRequirementsARM(
+    VkDevice                                    device,
+    const VkTensorMemoryRequirementsInfoARM*    pInfo,
+    VkMemoryRequirements2*                      pMemoryRequirements) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetTensorMemoryRequirementsARM: Invalid device "
+                   "[VUID-vkGetTensorMemoryRequirementsARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->GetTensorMemoryRequirementsARM(device, pInfo, pMemoryRequirements);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL BindTensorMemoryARM(
+    VkDevice                                    device,
+    uint32_t                                    bindInfoCount,
+    const VkBindTensorMemoryInfoARM*            pBindInfos) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkBindTensorMemoryARM: Invalid device "
+                   "[VUID-vkBindTensorMemoryARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->BindTensorMemoryARM(device, bindInfoCount, pBindInfos);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetDeviceTensorMemoryRequirementsARM(
+    VkDevice                                    device,
+    const VkDeviceTensorMemoryRequirementsARM*  pInfo,
+    VkMemoryRequirements2*                      pMemoryRequirements) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetDeviceTensorMemoryRequirementsARM: Invalid device "
+                   "[VUID-vkGetDeviceTensorMemoryRequirementsARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->GetDeviceTensorMemoryRequirementsARM(device, pInfo, pMemoryRequirements);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyTensorARM(
+    VkCommandBuffer                             commandBuffer,
+    const VkCopyTensorInfoARM*                  pCopyTensorInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdCopyTensorARM: Invalid commandBuffer "
+                   "[VUID-vkCmdCopyTensorARM-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdCopyTensorARM(commandBuffer, pCopyTensorInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalTensorPropertiesARM(
+    VkPhysicalDevice                            physicalDevice,
+    const VkPhysicalDeviceExternalTensorInfoARM* pExternalTensorInfo,
+    VkExternalTensorPropertiesARM*              pExternalTensorProperties) {
+    const VkLayerInstanceDispatchTable *disp;
+    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetPhysicalDeviceExternalTensorPropertiesARM: Invalid physicalDevice "
+                   "[VUID-vkGetPhysicalDeviceExternalTensorPropertiesARM-physicalDevice-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp = loader_get_instance_layer_dispatch(physicalDevice);
+    disp->GetPhysicalDeviceExternalTensorPropertiesARM(unwrapped_phys_dev, pExternalTensorInfo, pExternalTensorProperties);
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalTensorPropertiesARM(
+    VkPhysicalDevice                            physicalDevice,
+    const VkPhysicalDeviceExternalTensorInfoARM* pExternalTensorInfo,
+    VkExternalTensorPropertiesARM*              pExternalTensorProperties) {
+    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+    if (NULL == icd_term->dispatch.GetPhysicalDeviceExternalTensorPropertiesARM) {
+        loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
+                   "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceExternalTensorPropertiesARM");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    icd_term->dispatch.GetPhysicalDeviceExternalTensorPropertiesARM(phys_dev_term->phys_dev, pExternalTensorInfo, pExternalTensorProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetTensorOpaqueCaptureDescriptorDataARM(
+    VkDevice                                    device,
+    const VkTensorCaptureDescriptorDataInfoARM* pInfo,
+    void*                                       pData) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetTensorOpaqueCaptureDescriptorDataARM: Invalid device "
+                   "[VUID-vkGetTensorOpaqueCaptureDescriptorDataARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetTensorOpaqueCaptureDescriptorDataARM(device, pInfo, pData);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetTensorViewOpaqueCaptureDescriptorDataARM(
+    VkDevice                                    device,
+    const VkTensorViewCaptureDescriptorDataInfoARM* pInfo,
+    void*                                       pData) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetTensorViewOpaqueCaptureDescriptorDataARM: Invalid device "
+                   "[VUID-vkGetTensorViewOpaqueCaptureDescriptorDataARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetTensorViewOpaqueCaptureDescriptorDataARM(device, pInfo, pData);
+}
+
+
 // ---- VK_EXT_shader_module_identifier extension trampoline/terminators
 
 VKAPI_ATTR void VKAPI_CALL GetShaderModuleIdentifierEXT(
@@ -9565,6 +10977,66 @@
 }
 
 
+// ---- VK_NV_cooperative_vector extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCooperativeVectorPropertiesNV(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pPropertyCount,
+    VkCooperativeVectorPropertiesNV*            pProperties) {
+    const VkLayerInstanceDispatchTable *disp;
+    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetPhysicalDeviceCooperativeVectorPropertiesNV: Invalid physicalDevice "
+                   "[VUID-vkGetPhysicalDeviceCooperativeVectorPropertiesNV-physicalDevice-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp = loader_get_instance_layer_dispatch(physicalDevice);
+    return disp->GetPhysicalDeviceCooperativeVectorPropertiesNV(unwrapped_phys_dev, pPropertyCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceCooperativeVectorPropertiesNV(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pPropertyCount,
+    VkCooperativeVectorPropertiesNV*            pProperties) {
+    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+    if (NULL == icd_term->dispatch.GetPhysicalDeviceCooperativeVectorPropertiesNV) {
+        loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
+                   "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceCooperativeVectorPropertiesNV");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return icd_term->dispatch.GetPhysicalDeviceCooperativeVectorPropertiesNV(phys_dev_term->phys_dev, pPropertyCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL ConvertCooperativeVectorMatrixNV(
+    VkDevice                                    device,
+    const VkConvertCooperativeVectorMatrixInfoNV* pInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkConvertCooperativeVectorMatrixNV: Invalid device "
+                   "[VUID-vkConvertCooperativeVectorMatrixNV-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->ConvertCooperativeVectorMatrixNV(device, pInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdConvertCooperativeVectorMatrixNV(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    infoCount,
+    const VkConvertCooperativeVectorMatrixInfoNV* pInfos) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdConvertCooperativeVectorMatrixNV: Invalid commandBuffer "
+                   "[VUID-vkCmdConvertCooperativeVectorMatrixNV-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdConvertCooperativeVectorMatrixNV(commandBuffer, infoCount, pInfos);
+}
+
+
 // ---- VK_NV_low_latency2 extension trampoline/terminators
 
 VKAPI_ATTR VkResult VKAPI_CALL SetLatencySleepModeNV(
@@ -9637,6 +11109,240 @@
 }
 
 
+// ---- VK_ARM_data_graph extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateDataGraphPipelinesARM(
+    VkDevice                                    device,
+    VkDeferredOperationKHR                      deferredOperation,
+    VkPipelineCache                             pipelineCache,
+    uint32_t                                    createInfoCount,
+    const VkDataGraphPipelineCreateInfoARM*     pCreateInfos,
+    const VkAllocationCallbacks*                pAllocator,
+    VkPipeline*                                 pPipelines) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCreateDataGraphPipelinesARM: Invalid device "
+                   "[VUID-vkCreateDataGraphPipelinesARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->CreateDataGraphPipelinesARM(device, deferredOperation, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateDataGraphPipelineSessionARM(
+    VkDevice                                    device,
+    const VkDataGraphPipelineSessionCreateInfoARM* pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkDataGraphPipelineSessionARM*              pSession) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCreateDataGraphPipelineSessionARM: Invalid device "
+                   "[VUID-vkCreateDataGraphPipelineSessionARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->CreateDataGraphPipelineSessionARM(device, pCreateInfo, pAllocator, pSession);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetDataGraphPipelineSessionBindPointRequirementsARM(
+    VkDevice                                    device,
+    const VkDataGraphPipelineSessionBindPointRequirementsInfoARM* pInfo,
+    uint32_t*                                   pBindPointRequirementCount,
+    VkDataGraphPipelineSessionBindPointRequirementARM* pBindPointRequirements) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetDataGraphPipelineSessionBindPointRequirementsARM: Invalid device "
+                   "[VUID-vkGetDataGraphPipelineSessionBindPointRequirementsARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetDataGraphPipelineSessionBindPointRequirementsARM(device, pInfo, pBindPointRequirementCount, pBindPointRequirements);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetDataGraphPipelineSessionMemoryRequirementsARM(
+    VkDevice                                    device,
+    const VkDataGraphPipelineSessionMemoryRequirementsInfoARM* pInfo,
+    VkMemoryRequirements2*                      pMemoryRequirements) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetDataGraphPipelineSessionMemoryRequirementsARM: Invalid device "
+                   "[VUID-vkGetDataGraphPipelineSessionMemoryRequirementsARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->GetDataGraphPipelineSessionMemoryRequirementsARM(device, pInfo, pMemoryRequirements);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL BindDataGraphPipelineSessionMemoryARM(
+    VkDevice                                    device,
+    uint32_t                                    bindInfoCount,
+    const VkBindDataGraphPipelineSessionMemoryInfoARM* pBindInfos) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkBindDataGraphPipelineSessionMemoryARM: Invalid device "
+                   "[VUID-vkBindDataGraphPipelineSessionMemoryARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->BindDataGraphPipelineSessionMemoryARM(device, bindInfoCount, pBindInfos);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDataGraphPipelineSessionARM(
+    VkDevice                                    device,
+    VkDataGraphPipelineSessionARM               session,
+    const VkAllocationCallbacks*                pAllocator) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkDestroyDataGraphPipelineSessionARM: Invalid device "
+                   "[VUID-vkDestroyDataGraphPipelineSessionARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->DestroyDataGraphPipelineSessionARM(device, session, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDispatchDataGraphARM(
+    VkCommandBuffer                             commandBuffer,
+    VkDataGraphPipelineSessionARM               session,
+    const VkDataGraphPipelineDispatchInfoARM*   pInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDispatchDataGraphARM: Invalid commandBuffer "
+                   "[VUID-vkCmdDispatchDataGraphARM-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDispatchDataGraphARM(commandBuffer, session, pInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetDataGraphPipelineAvailablePropertiesARM(
+    VkDevice                                    device,
+    const VkDataGraphPipelineInfoARM*           pPipelineInfo,
+    uint32_t*                                   pPropertiesCount,
+    VkDataGraphPipelinePropertyARM*             pProperties) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetDataGraphPipelineAvailablePropertiesARM: Invalid device "
+                   "[VUID-vkGetDataGraphPipelineAvailablePropertiesARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetDataGraphPipelineAvailablePropertiesARM(device, pPipelineInfo, pPropertiesCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetDataGraphPipelinePropertiesARM(
+    VkDevice                                    device,
+    const VkDataGraphPipelineInfoARM*           pPipelineInfo,
+    uint32_t                                    propertiesCount,
+    VkDataGraphPipelinePropertyQueryResultARM*  pProperties) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetDataGraphPipelinePropertiesARM: Invalid device "
+                   "[VUID-vkGetDataGraphPipelinePropertiesARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetDataGraphPipelinePropertiesARM(device, pPipelineInfo, propertiesCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t                                    queueFamilyIndex,
+    uint32_t*                                   pQueueFamilyDataGraphPropertyCount,
+    VkQueueFamilyDataGraphPropertiesARM*        pQueueFamilyDataGraphProperties) {
+    const VkLayerInstanceDispatchTable *disp;
+    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM: Invalid physicalDevice "
+                   "[VUID-vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM-physicalDevice-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp = loader_get_instance_layer_dispatch(physicalDevice);
+    return disp->GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(unwrapped_phys_dev, queueFamilyIndex, pQueueFamilyDataGraphPropertyCount, pQueueFamilyDataGraphProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t                                    queueFamilyIndex,
+    uint32_t*                                   pQueueFamilyDataGraphPropertyCount,
+    VkQueueFamilyDataGraphPropertiesARM*        pQueueFamilyDataGraphProperties) {
+    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+    if (NULL == icd_term->dispatch.GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM) {
+        loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
+                   "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return icd_term->dispatch.GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(phys_dev_term->phys_dev, queueFamilyIndex, pQueueFamilyDataGraphPropertyCount, pQueueFamilyDataGraphProperties);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM(
+    VkPhysicalDevice                            physicalDevice,
+    const VkPhysicalDeviceQueueFamilyDataGraphProcessingEngineInfoARM* pQueueFamilyDataGraphProcessingEngineInfo,
+    VkQueueFamilyDataGraphProcessingEnginePropertiesARM* pQueueFamilyDataGraphProcessingEngineProperties) {
+    const VkLayerInstanceDispatchTable *disp;
+    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM: Invalid physicalDevice "
+                   "[VUID-vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM-physicalDevice-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp = loader_get_instance_layer_dispatch(physicalDevice);
+    disp->GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM(unwrapped_phys_dev, pQueueFamilyDataGraphProcessingEngineInfo, pQueueFamilyDataGraphProcessingEngineProperties);
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM(
+    VkPhysicalDevice                            physicalDevice,
+    const VkPhysicalDeviceQueueFamilyDataGraphProcessingEngineInfoARM* pQueueFamilyDataGraphProcessingEngineInfo,
+    VkQueueFamilyDataGraphProcessingEnginePropertiesARM* pQueueFamilyDataGraphProcessingEngineProperties) {
+    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+    if (NULL == icd_term->dispatch.GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM) {
+        loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
+                   "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    icd_term->dispatch.GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM(phys_dev_term->phys_dev, pQueueFamilyDataGraphProcessingEngineInfo, pQueueFamilyDataGraphProcessingEngineProperties);
+}
+
+
+// ---- VK_ARM_data_graph_instruction_set_tosa extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t                                    queueFamilyIndex,
+    const VkQueueFamilyDataGraphPropertiesARM*  pQueueFamilyDataGraphProperties,
+    VkBaseOutStructure*                         pProperties) {
+    const VkLayerInstanceDispatchTable *disp;
+    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM: Invalid physicalDevice "
+                   "[VUID-vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM-physicalDevice-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp = loader_get_instance_layer_dispatch(physicalDevice);
+    return disp->GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM(unwrapped_phys_dev, queueFamilyIndex, pQueueFamilyDataGraphProperties, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t                                    queueFamilyIndex,
+    const VkQueueFamilyDataGraphPropertiesARM*  pQueueFamilyDataGraphProperties,
+    VkBaseOutStructure*                         pProperties) {
+    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+    if (NULL == icd_term->dispatch.GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM) {
+        loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
+                   "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return icd_term->dispatch.GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM(phys_dev_term->phys_dev, queueFamilyIndex, pQueueFamilyDataGraphProperties, pProperties);
+}
+
+
 // ---- VK_EXT_attachment_feedback_loop_dynamic_state extension trampoline/terminators
 
 VKAPI_ATTR void VKAPI_CALL CmdSetAttachmentFeedbackLoopEnableEXT(
@@ -9672,6 +11378,161 @@
 
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+// ---- VK_QCOM_tile_memory_heap extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdBindTileMemoryQCOM(
+    VkCommandBuffer                             commandBuffer,
+    const VkTileMemoryBindInfoQCOM*             pTileMemoryBindInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBindTileMemoryQCOM: Invalid commandBuffer "
+                   "[VUID-vkCmdBindTileMemoryQCOM-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBindTileMemoryQCOM(commandBuffer, pTileMemoryBindInfo);
+}
+
+
+// ---- VK_EXT_memory_decompression extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdDecompressMemoryEXT(
+    VkCommandBuffer                             commandBuffer,
+    const VkDecompressMemoryInfoEXT*            pDecompressMemoryInfoEXT) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDecompressMemoryEXT: Invalid commandBuffer "
+                   "[VUID-vkCmdDecompressMemoryEXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDecompressMemoryEXT(commandBuffer, pDecompressMemoryInfoEXT);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDecompressMemoryIndirectCountEXT(
+    VkCommandBuffer                             commandBuffer,
+    VkMemoryDecompressionMethodFlagsEXT         decompressionMethod,
+    VkDeviceAddress                             indirectCommandsAddress,
+    VkDeviceAddress                             indirectCommandsCountAddress,
+    uint32_t                                    maxDecompressionCount,
+    uint32_t                                    stride) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdDecompressMemoryIndirectCountEXT: Invalid commandBuffer "
+                   "[VUID-vkCmdDecompressMemoryIndirectCountEXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdDecompressMemoryIndirectCountEXT(commandBuffer, decompressionMethod, indirectCommandsAddress, indirectCommandsCountAddress, maxDecompressionCount, stride);
+}
+
+
+// ---- VK_NV_external_compute_queue extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateExternalComputeQueueNV(
+    VkDevice                                    device,
+    const VkExternalComputeQueueCreateInfoNV*   pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkExternalComputeQueueNV*                   pExternalQueue) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCreateExternalComputeQueueNV: Invalid device "
+                   "[VUID-vkCreateExternalComputeQueueNV-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->CreateExternalComputeQueueNV(device, pCreateInfo, pAllocator, pExternalQueue);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyExternalComputeQueueNV(
+    VkDevice                                    device,
+    VkExternalComputeQueueNV                    externalQueue,
+    const VkAllocationCallbacks*                pAllocator) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkDestroyExternalComputeQueueNV: Invalid device "
+                   "[VUID-vkDestroyExternalComputeQueueNV-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->DestroyExternalComputeQueueNV(device, externalQueue, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetExternalComputeQueueDataNV(
+    VkExternalComputeQueueNV                    externalQueue,
+    VkExternalComputeQueueDataParamsNV*         params,
+    void*                                       pData) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(externalQueue);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetExternalComputeQueueDataNV: Invalid externalQueue "
+                   "[VUID-vkGetExternalComputeQueueDataNV-externalQueue-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->GetExternalComputeQueueDataNV(externalQueue, params, pData);
+}
+
+
+// ---- VK_NV_cluster_acceleration_structure extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL GetClusterAccelerationStructureBuildSizesNV(
+    VkDevice                                    device,
+    const VkClusterAccelerationStructureInputInfoNV* pInfo,
+    VkAccelerationStructureBuildSizesInfoKHR*   pSizeInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetClusterAccelerationStructureBuildSizesNV: Invalid device "
+                   "[VUID-vkGetClusterAccelerationStructureBuildSizesNV-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->GetClusterAccelerationStructureBuildSizesNV(device, pInfo, pSizeInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBuildClusterAccelerationStructureIndirectNV(
+    VkCommandBuffer                             commandBuffer,
+    const VkClusterAccelerationStructureCommandsInfoNV* pCommandInfos) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBuildClusterAccelerationStructureIndirectNV: Invalid commandBuffer "
+                   "[VUID-vkCmdBuildClusterAccelerationStructureIndirectNV-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBuildClusterAccelerationStructureIndirectNV(commandBuffer, pCommandInfos);
+}
+
+
+// ---- VK_NV_partitioned_acceleration_structure extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL GetPartitionedAccelerationStructuresBuildSizesNV(
+    VkDevice                                    device,
+    const VkPartitionedAccelerationStructureInstancesInputNV* pInfo,
+    VkAccelerationStructureBuildSizesInfoKHR*   pSizeInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetPartitionedAccelerationStructuresBuildSizesNV: Invalid device "
+                   "[VUID-vkGetPartitionedAccelerationStructuresBuildSizesNV-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->GetPartitionedAccelerationStructuresBuildSizesNV(device, pInfo, pSizeInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBuildPartitionedAccelerationStructuresNV(
+    VkCommandBuffer                             commandBuffer,
+    const VkBuildPartitionedAccelerationStructureInfoNV* pBuildInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBuildPartitionedAccelerationStructuresNV: Invalid commandBuffer "
+                   "[VUID-vkCmdBuildPartitionedAccelerationStructuresNV-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBuildPartitionedAccelerationStructuresNV(commandBuffer, pBuildInfo);
+}
+
+
 // ---- VK_EXT_device_generated_commands extension trampoline/terminators
 
 VKAPI_ATTR void VKAPI_CALL GetGeneratedCommandsMemoryRequirementsEXT(
@@ -9805,6 +11666,42 @@
 }
 
 
+// ---- VK_OHOS_surface extension trampoline/terminators
+
+#if defined(VK_USE_PLATFORM_OHOS)
+VKAPI_ATTR VkResult VKAPI_CALL CreateSurfaceOHOS(
+    VkInstance                                  instance,
+    const VkSurfaceCreateInfoOHOS*              pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkSurfaceKHR*                               pSurface) {
+    struct loader_instance *inst = loader_get_instance(instance);
+    if (NULL == inst) {
+        loader_log(
+            NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+            "vkCreateSurfaceOHOS: Invalid instance [VUID-vkCreateSurfaceOHOS-instance-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+#error("Not implemented. Likely needs to be manually generated!");
+    return inst->disp->CreateSurfaceOHOS(instance, pCreateInfo, pAllocator, pSurface);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSurfaceOHOS(
+    VkInstance                                  instance,
+    const VkSurfaceCreateInfoOHOS*              pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkSurfaceKHR*                               pSurface) {
+    struct loader_instance *inst = loader_get_instance(instance);
+    if (NULL == inst) {
+        loader_log(
+            NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+            "vkCreateSurfaceOHOS: Invalid instance [VUID-vkCreateSurfaceOHOS-instance-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+#error("Not implemented. Likely needs to be manually generated!");
+}
+
+#endif // VK_USE_PLATFORM_OHOS
+
 // ---- VK_NV_cooperative_matrix2 extension trampoline/terminators
 
 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV(
@@ -9838,6 +11735,366 @@
 }
 
 
+// ---- VK_EXT_external_memory_metal extension trampoline/terminators
+
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+VKAPI_ATTR VkResult VKAPI_CALL GetMemoryMetalHandleEXT(
+    VkDevice                                    device,
+    const VkMemoryGetMetalHandleInfoEXT*        pGetMetalHandleInfo,
+    void**                                      pHandle) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetMemoryMetalHandleEXT: Invalid device "
+                   "[VUID-vkGetMemoryMetalHandleEXT-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetMemoryMetalHandleEXT(device, pGetMetalHandleInfo, pHandle);
+}
+
+#endif // VK_USE_PLATFORM_METAL_EXT
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+VKAPI_ATTR VkResult VKAPI_CALL GetMemoryMetalHandlePropertiesEXT(
+    VkDevice                                    device,
+    VkExternalMemoryHandleTypeFlagBits          handleType,
+    const void*                                 pHandle,
+    VkMemoryMetalHandlePropertiesEXT*           pMemoryMetalHandleProperties) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetMemoryMetalHandlePropertiesEXT: Invalid device "
+                   "[VUID-vkGetMemoryMetalHandlePropertiesEXT-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetMemoryMetalHandlePropertiesEXT(device, handleType, pHandle, pMemoryMetalHandleProperties);
+}
+
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+// ---- VK_ARM_performance_counters_by_region extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t                                    queueFamilyIndex,
+    uint32_t*                                   pCounterCount,
+    VkPerformanceCounterARM*                    pCounters,
+    VkPerformanceCounterDescriptionARM*         pCounterDescriptions) {
+    const VkLayerInstanceDispatchTable *disp;
+    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM: Invalid physicalDevice "
+                   "[VUID-vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM-physicalDevice-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp = loader_get_instance_layer_dispatch(physicalDevice);
+    return disp->EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM(unwrapped_phys_dev, queueFamilyIndex, pCounterCount, pCounters, pCounterDescriptions);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t                                    queueFamilyIndex,
+    uint32_t*                                   pCounterCount,
+    VkPerformanceCounterARM*                    pCounters,
+    VkPerformanceCounterDescriptionARM*         pCounterDescriptions) {
+    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+    if (NULL == icd_term->dispatch.EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM) {
+        loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
+                   "ICD associated with VkPhysicalDevice does not support EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return icd_term->dispatch.EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM(phys_dev_term->phys_dev, queueFamilyIndex, pCounterCount, pCounters, pCounterDescriptions);
+}
+
+
+// ---- VK_ARM_shader_instrumentation extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceShaderInstrumentationMetricsARM(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pDescriptionCount,
+    VkShaderInstrumentationMetricDescriptionARM* pDescriptions) {
+    const VkLayerInstanceDispatchTable *disp;
+    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM: Invalid physicalDevice "
+                   "[VUID-vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM-physicalDevice-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp = loader_get_instance_layer_dispatch(physicalDevice);
+    return disp->EnumeratePhysicalDeviceShaderInstrumentationMetricsARM(unwrapped_phys_dev, pDescriptionCount, pDescriptions);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceShaderInstrumentationMetricsARM(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pDescriptionCount,
+    VkShaderInstrumentationMetricDescriptionARM* pDescriptions) {
+    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+    if (NULL == icd_term->dispatch.EnumeratePhysicalDeviceShaderInstrumentationMetricsARM) {
+        loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
+                   "ICD associated with VkPhysicalDevice does not support EnumeratePhysicalDeviceShaderInstrumentationMetricsARM");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return icd_term->dispatch.EnumeratePhysicalDeviceShaderInstrumentationMetricsARM(phys_dev_term->phys_dev, pDescriptionCount, pDescriptions);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateShaderInstrumentationARM(
+    VkDevice                                    device,
+    const VkShaderInstrumentationCreateInfoARM* pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkShaderInstrumentationARM*                 pInstrumentation) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCreateShaderInstrumentationARM: Invalid device "
+                   "[VUID-vkCreateShaderInstrumentationARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->CreateShaderInstrumentationARM(device, pCreateInfo, pAllocator, pInstrumentation);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyShaderInstrumentationARM(
+    VkDevice                                    device,
+    VkShaderInstrumentationARM                  instrumentation,
+    const VkAllocationCallbacks*                pAllocator) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkDestroyShaderInstrumentationARM: Invalid device "
+                   "[VUID-vkDestroyShaderInstrumentationARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->DestroyShaderInstrumentationARM(device, instrumentation, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginShaderInstrumentationARM(
+    VkCommandBuffer                             commandBuffer,
+    VkShaderInstrumentationARM                  instrumentation) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBeginShaderInstrumentationARM: Invalid commandBuffer "
+                   "[VUID-vkCmdBeginShaderInstrumentationARM-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBeginShaderInstrumentationARM(commandBuffer, instrumentation);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndShaderInstrumentationARM(
+    VkCommandBuffer                             commandBuffer) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdEndShaderInstrumentationARM: Invalid commandBuffer "
+                   "[VUID-vkCmdEndShaderInstrumentationARM-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdEndShaderInstrumentationARM(commandBuffer);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetShaderInstrumentationValuesARM(
+    VkDevice                                    device,
+    VkShaderInstrumentationARM                  instrumentation,
+    uint32_t*                                   pMetricBlockCount,
+    void*                                       pMetricValues,
+    VkShaderInstrumentationValuesFlagsARM       flags) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetShaderInstrumentationValuesARM: Invalid device "
+                   "[VUID-vkGetShaderInstrumentationValuesARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return disp->GetShaderInstrumentationValuesARM(device, instrumentation, pMetricBlockCount, pMetricValues, flags);
+}
+
+VKAPI_ATTR void VKAPI_CALL ClearShaderInstrumentationMetricsARM(
+    VkDevice                                    device,
+    VkShaderInstrumentationARM                  instrumentation) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkClearShaderInstrumentationMetricsARM: Invalid device "
+                   "[VUID-vkClearShaderInstrumentationMetricsARM-device-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->ClearShaderInstrumentationMetricsARM(device, instrumentation);
+}
+
+
+// ---- VK_EXT_fragment_density_map_offset extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdEndRendering2EXT(
+    VkCommandBuffer                             commandBuffer,
+    const VkRenderingEndInfoKHR*                pRenderingEndInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdEndRendering2EXT: Invalid commandBuffer "
+                   "[VUID-vkCmdEndRendering2EXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdEndRendering2EXT(commandBuffer, pRenderingEndInfo);
+}
+
+
+// ---- VK_EXT_custom_resolve extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginCustomResolveEXT(
+    VkCommandBuffer                             commandBuffer,
+    const VkBeginCustomResolveInfoEXT*          pBeginCustomResolveInfo) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdBeginCustomResolveEXT: Invalid commandBuffer "
+                   "[VUID-vkCmdBeginCustomResolveEXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdBeginCustomResolveEXT(commandBuffer, pBeginCustomResolveInfo);
+}
+
+
+// ---- VK_ARM_data_graph_optical_flow extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t                                    queueFamilyIndex,
+    const VkQueueFamilyDataGraphPropertiesARM*  pQueueFamilyDataGraphProperties,
+    const VkDataGraphOpticalFlowImageFormatInfoARM* pOpticalFlowImageFormatInfo,
+    uint32_t*                                   pFormatCount,
+    VkDataGraphOpticalFlowImageFormatPropertiesARM* pImageFormatProperties) {
+    const VkLayerInstanceDispatchTable *disp;
+    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM: Invalid physicalDevice "
+                   "[VUID-vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM-physicalDevice-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp = loader_get_instance_layer_dispatch(physicalDevice);
+    return disp->GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM(unwrapped_phys_dev, queueFamilyIndex, pQueueFamilyDataGraphProperties, pOpticalFlowImageFormatInfo, pFormatCount, pImageFormatProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t                                    queueFamilyIndex,
+    const VkQueueFamilyDataGraphPropertiesARM*  pQueueFamilyDataGraphProperties,
+    const VkDataGraphOpticalFlowImageFormatInfoARM* pOpticalFlowImageFormatInfo,
+    uint32_t*                                   pFormatCount,
+    VkDataGraphOpticalFlowImageFormatPropertiesARM* pImageFormatProperties) {
+    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+    if (NULL == icd_term->dispatch.GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM) {
+        loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
+                   "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    return icd_term->dispatch.GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM(phys_dev_term->phys_dev, queueFamilyIndex, pQueueFamilyDataGraphProperties, pOpticalFlowImageFormatInfo, pFormatCount, pImageFormatProperties);
+}
+
+
+// ---- VK_NV_compute_occupancy_priority extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdSetComputeOccupancyPriorityNV(
+    VkCommandBuffer                             commandBuffer,
+    const VkComputeOccupancyPriorityParametersNV* pParameters) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdSetComputeOccupancyPriorityNV: Invalid commandBuffer "
+                   "[VUID-vkCmdSetComputeOccupancyPriorityNV-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdSetComputeOccupancyPriorityNV(commandBuffer, pParameters);
+}
+
+
+// ---- VK_SEC_ubm_surface extension trampoline/terminators
+
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+VKAPI_ATTR VkResult VKAPI_CALL CreateUbmSurfaceSEC(
+    VkInstance                                  instance,
+    const VkUbmSurfaceCreateInfoSEC*            pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkSurfaceKHR*                               pSurface) {
+    struct loader_instance *inst = loader_get_instance(instance);
+    if (NULL == inst) {
+        loader_log(
+            NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+            "vkCreateUbmSurfaceSEC: Invalid instance [VUID-vkCreateUbmSurfaceSEC-instance-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+#error("Not implemented. Likely needs to be manually generated!");
+    return inst->disp->CreateUbmSurfaceSEC(instance, pCreateInfo, pAllocator, pSurface);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateUbmSurfaceSEC(
+    VkInstance                                  instance,
+    const VkUbmSurfaceCreateInfoSEC*            pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkSurfaceKHR*                               pSurface) {
+    struct loader_instance *inst = loader_get_instance(instance);
+    if (NULL == inst) {
+        loader_log(
+            NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+            "vkCreateUbmSurfaceSEC: Invalid instance [VUID-vkCreateUbmSurfaceSEC-instance-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+#error("Not implemented. Likely needs to be manually generated!");
+}
+
+#endif // VK_USE_PLATFORM_UBM_SEC
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceUbmPresentationSupportSEC(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t                                    queueFamilyIndex,
+    struct ubm_device*                          device) {
+    const VkLayerInstanceDispatchTable *disp;
+    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+    if (VK_NULL_HANDLE == unwrapped_phys_dev) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkGetPhysicalDeviceUbmPresentationSupportSEC: Invalid physicalDevice "
+                   "[VUID-vkGetPhysicalDeviceUbmPresentationSupportSEC-physicalDevice-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp = loader_get_instance_layer_dispatch(physicalDevice);
+    return disp->GetPhysicalDeviceUbmPresentationSupportSEC(unwrapped_phys_dev, queueFamilyIndex, device);
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceUbmPresentationSupportSEC(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t                                    queueFamilyIndex,
+    struct ubm_device*                          device) {
+    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+    if (NULL == icd_term->dispatch.GetPhysicalDeviceUbmPresentationSupportSEC) {
+        loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
+                   "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceUbmPresentationSupportSEC");
+        return VK_ERROR_EXTENSION_NOT_PRESENT;
+    }
+    return icd_term->dispatch.GetPhysicalDeviceUbmPresentationSupportSEC(phys_dev_term->phys_dev, queueFamilyIndex, device);
+}
+
+#endif // VK_USE_PLATFORM_UBM_SEC
+
+// ---- VK_EXT_primitive_restart_index extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdSetPrimitiveRestartIndexEXT(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    primitiveRestartIndex) {
+    const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+    if (NULL == disp) {
+        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+                   "vkCmdSetPrimitiveRestartIndexEXT: Invalid commandBuffer "
+                   "[VUID-vkCmdSetPrimitiveRestartIndexEXT-commandBuffer-parameter]");
+        abort(); /* Intentionally fail so user can correct issue. */
+    }
+    disp->CmdSetPrimitiveRestartIndexEXT(commandBuffer, primitiveRestartIndex);
+}
+
+
 // ---- VK_KHR_acceleration_structure extension trampoline/terminators
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateAccelerationStructureKHR(
@@ -10303,43 +12560,43 @@
 
     // ---- VK_KHR_get_physical_device_properties2 extension commands
     if (!strcmp("vkGetPhysicalDeviceFeatures2KHR", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+        *addr = (ptr_instance->enabled_extensions.khr_get_physical_device_properties2 == 1)
                      ? (void *)vkGetPhysicalDeviceFeatures2
                      : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceProperties2KHR", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+        *addr = (ptr_instance->enabled_extensions.khr_get_physical_device_properties2 == 1)
                      ? (void *)vkGetPhysicalDeviceProperties2
                      : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceFormatProperties2KHR", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+        *addr = (ptr_instance->enabled_extensions.khr_get_physical_device_properties2 == 1)
                      ? (void *)vkGetPhysicalDeviceFormatProperties2
                      : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceImageFormatProperties2KHR", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+        *addr = (ptr_instance->enabled_extensions.khr_get_physical_device_properties2 == 1)
                      ? (void *)vkGetPhysicalDeviceImageFormatProperties2
                      : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceQueueFamilyProperties2KHR", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+        *addr = (ptr_instance->enabled_extensions.khr_get_physical_device_properties2 == 1)
                      ? (void *)vkGetPhysicalDeviceQueueFamilyProperties2
                      : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceMemoryProperties2KHR", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+        *addr = (ptr_instance->enabled_extensions.khr_get_physical_device_properties2 == 1)
                      ? (void *)vkGetPhysicalDeviceMemoryProperties2
                      : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceSparseImageFormatProperties2KHR", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+        *addr = (ptr_instance->enabled_extensions.khr_get_physical_device_properties2 == 1)
                      ? (void *)vkGetPhysicalDeviceSparseImageFormatProperties2
                      : NULL;
         return true;
@@ -10367,7 +12624,7 @@
 
     // ---- VK_KHR_device_group_creation extension commands
     if (!strcmp("vkEnumeratePhysicalDeviceGroupsKHR", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.khr_device_group_creation == 1)
+        *addr = (ptr_instance->enabled_extensions.khr_device_group_creation == 1)
                      ? (void *)vkEnumeratePhysicalDeviceGroups
                      : NULL;
         return true;
@@ -10375,7 +12632,7 @@
 
     // ---- VK_KHR_external_memory_capabilities extension commands
     if (!strcmp("vkGetPhysicalDeviceExternalBufferPropertiesKHR", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.khr_external_memory_capabilities == 1)
+        *addr = (ptr_instance->enabled_extensions.khr_external_memory_capabilities == 1)
                      ? (void *)vkGetPhysicalDeviceExternalBufferProperties
                      : NULL;
         return true;
@@ -10407,7 +12664,7 @@
 
     // ---- VK_KHR_external_semaphore_capabilities extension commands
     if (!strcmp("vkGetPhysicalDeviceExternalSemaphorePropertiesKHR", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.khr_external_semaphore_capabilities == 1)
+        *addr = (ptr_instance->enabled_extensions.khr_external_semaphore_capabilities == 1)
                      ? (void *)vkGetPhysicalDeviceExternalSemaphoreProperties
                      : NULL;
         return true;
@@ -10487,7 +12744,7 @@
 
     // ---- VK_KHR_external_fence_capabilities extension commands
     if (!strcmp("vkGetPhysicalDeviceExternalFencePropertiesKHR", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.khr_external_fence_capabilities == 1)
+        *addr = (ptr_instance->enabled_extensions.khr_external_fence_capabilities == 1)
                      ? (void *)vkGetPhysicalDeviceExternalFenceProperties
                      : NULL;
         return true;
@@ -10725,6 +12982,96 @@
         return true;
     }
 
+    // ---- VK_KHR_device_address_commands extension commands
+    if (!strcmp("vkCmdBindIndexBuffer3KHR", name)) {
+        *addr = (void *)CmdBindIndexBuffer3KHR;
+        return true;
+    }
+    if (!strcmp("vkCmdBindVertexBuffers3KHR", name)) {
+        *addr = (void *)CmdBindVertexBuffers3KHR;
+        return true;
+    }
+    if (!strcmp("vkCmdDrawIndirect2KHR", name)) {
+        *addr = (void *)CmdDrawIndirect2KHR;
+        return true;
+    }
+    if (!strcmp("vkCmdDrawIndexedIndirect2KHR", name)) {
+        *addr = (void *)CmdDrawIndexedIndirect2KHR;
+        return true;
+    }
+    if (!strcmp("vkCmdDispatchIndirect2KHR", name)) {
+        *addr = (void *)CmdDispatchIndirect2KHR;
+        return true;
+    }
+    if (!strcmp("vkCmdCopyMemoryKHR", name)) {
+        *addr = (void *)CmdCopyMemoryKHR;
+        return true;
+    }
+    if (!strcmp("vkCmdCopyMemoryToImageKHR", name)) {
+        *addr = (void *)CmdCopyMemoryToImageKHR;
+        return true;
+    }
+    if (!strcmp("vkCmdCopyImageToMemoryKHR", name)) {
+        *addr = (void *)CmdCopyImageToMemoryKHR;
+        return true;
+    }
+    if (!strcmp("vkCmdUpdateMemoryKHR", name)) {
+        *addr = (void *)CmdUpdateMemoryKHR;
+        return true;
+    }
+    if (!strcmp("vkCmdFillMemoryKHR", name)) {
+        *addr = (void *)CmdFillMemoryKHR;
+        return true;
+    }
+    if (!strcmp("vkCmdCopyQueryPoolResultsToMemoryKHR", name)) {
+        *addr = (void *)CmdCopyQueryPoolResultsToMemoryKHR;
+        return true;
+    }
+    if (!strcmp("vkCmdDrawIndirectCount2KHR", name)) {
+        *addr = (void *)CmdDrawIndirectCount2KHR;
+        return true;
+    }
+    if (!strcmp("vkCmdDrawIndexedIndirectCount2KHR", name)) {
+        *addr = (void *)CmdDrawIndexedIndirectCount2KHR;
+        return true;
+    }
+    if (!strcmp("vkCmdBeginConditionalRendering2EXT", name)) {
+        *addr = (void *)CmdBeginConditionalRendering2EXT;
+        return true;
+    }
+    if (!strcmp("vkCmdBindTransformFeedbackBuffers2EXT", name)) {
+        *addr = (void *)CmdBindTransformFeedbackBuffers2EXT;
+        return true;
+    }
+    if (!strcmp("vkCmdBeginTransformFeedback2EXT", name)) {
+        *addr = (void *)CmdBeginTransformFeedback2EXT;
+        return true;
+    }
+    if (!strcmp("vkCmdEndTransformFeedback2EXT", name)) {
+        *addr = (void *)CmdEndTransformFeedback2EXT;
+        return true;
+    }
+    if (!strcmp("vkCmdDrawIndirectByteCount2EXT", name)) {
+        *addr = (void *)CmdDrawIndirectByteCount2EXT;
+        return true;
+    }
+    if (!strcmp("vkCmdDrawMeshTasksIndirect2EXT", name)) {
+        *addr = (void *)CmdDrawMeshTasksIndirect2EXT;
+        return true;
+    }
+    if (!strcmp("vkCmdDrawMeshTasksIndirectCount2EXT", name)) {
+        *addr = (void *)CmdDrawMeshTasksIndirectCount2EXT;
+        return true;
+    }
+    if (!strcmp("vkCmdWriteMarkerToMemoryAMD", name)) {
+        *addr = (void *)CmdWriteMarkerToMemoryAMD;
+        return true;
+    }
+    if (!strcmp("vkCreateAccelerationStructure2KHR", name)) {
+        *addr = (void *)CreateAccelerationStructure2KHR;
+        return true;
+    }
+
     // ---- VK_KHR_copy_commands2 extension commands
     if (!strcmp("vkCmdCopyBuffer2KHR", name)) {
         *addr = (void *)CmdCopyBuffer2KHR;
@@ -10789,6 +13136,12 @@
         return true;
     }
 
+    // ---- VK_KHR_present_wait2 extension commands
+    if (!strcmp("vkWaitForPresent2KHR", name)) {
+        *addr = (void *)WaitForPresent2KHR;
+        return true;
+    }
+
     // ---- VK_KHR_pipeline_binary extension commands
     if (!strcmp("vkCreatePipelineBinariesKHR", name)) {
         *addr = (void *)CreatePipelineBinariesKHR;
@@ -10811,6 +13164,12 @@
         return true;
     }
 
+    // ---- VK_KHR_swapchain_maintenance1 extension commands
+    if (!strcmp("vkReleaseSwapchainImagesKHR", name)) {
+        *addr = (void *)ReleaseSwapchainImagesKHR;
+        return true;
+    }
+
     // ---- VK_KHR_cooperative_matrix extension commands
     if (!strcmp("vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR", name)) {
         *addr = (void *)GetPhysicalDeviceCooperativeMatrixPropertiesKHR;
@@ -10859,6 +13218,32 @@
         return true;
     }
 
+    // ---- VK_KHR_copy_memory_indirect extension commands
+    if (!strcmp("vkCmdCopyMemoryIndirectKHR", name)) {
+        *addr = (void *)CmdCopyMemoryIndirectKHR;
+        return true;
+    }
+    if (!strcmp("vkCmdCopyMemoryToImageIndirectKHR", name)) {
+        *addr = (void *)CmdCopyMemoryToImageIndirectKHR;
+        return true;
+    }
+
+    // ---- VK_KHR_device_fault extension commands
+    if (!strcmp("vkGetDeviceFaultReportsKHR", name)) {
+        *addr = (void *)GetDeviceFaultReportsKHR;
+        return true;
+    }
+    if (!strcmp("vkGetDeviceFaultDebugInfoKHR", name)) {
+        *addr = (void *)GetDeviceFaultDebugInfoKHR;
+        return true;
+    }
+
+    // ---- VK_KHR_maintenance10 extension commands
+    if (!strcmp("vkCmdEndRendering2KHR", name)) {
+        *addr = (void *)CmdEndRendering2KHR;
+        return true;
+    }
+
     // ---- VK_EXT_debug_marker extension commands
     if (!strcmp("vkDebugMarkerSetObjectTagEXT", name)) {
         *addr = (void *)DebugMarkerSetObjectTagEXT;
@@ -10942,6 +13327,10 @@
         *addr = (void *)GetImageViewAddressNVX;
         return true;
     }
+    if (!strcmp("vkGetDeviceCombinedImageSamplerIndexNVX", name)) {
+        *addr = (void *)GetDeviceCombinedImageSamplerIndexNVX;
+        return true;
+    }
 
     // ---- VK_AMD_draw_indirect_count extension commands
     if (!strcmp("vkCmdDrawIndirectCountAMD", name)) {
@@ -10961,7 +13350,7 @@
 
     // ---- VK_NV_external_memory_capabilities extension commands
     if (!strcmp("vkGetPhysicalDeviceExternalImageFormatPropertiesNV", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.nv_external_memory_capabilities == 1)
+        *addr = (ptr_instance->enabled_extensions.nv_external_memory_capabilities == 1)
                      ? (void *)GetPhysicalDeviceExternalImageFormatPropertiesNV
                      : NULL;
         return true;
@@ -10993,7 +13382,7 @@
 
     // ---- VK_EXT_direct_mode_display extension commands
     if (!strcmp("vkReleaseDisplayEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_direct_mode_display == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_direct_mode_display == 1)
                      ? (void *)ReleaseDisplayEXT
                      : NULL;
         return true;
@@ -11002,7 +13391,7 @@
     // ---- VK_EXT_acquire_xlib_display extension commands
 #if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
     if (!strcmp("vkAcquireXlibDisplayEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_acquire_xlib_display == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_acquire_xlib_display == 1)
                      ? (void *)AcquireXlibDisplayEXT
                      : NULL;
         return true;
@@ -11010,7 +13399,7 @@
 #endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
 #if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
     if (!strcmp("vkGetRandROutputDisplayEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_acquire_xlib_display == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_acquire_xlib_display == 1)
                      ? (void *)GetRandROutputDisplayEXT
                      : NULL;
         return true;
@@ -11019,7 +13408,7 @@
 
     // ---- VK_EXT_display_surface_counter extension commands
     if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilities2EXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_display_surface_counter == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_display_surface_counter == 1)
                      ? (void *)GetPhysicalDeviceSurfaceCapabilities2EXT
                      : NULL;
         return true;
@@ -11075,49 +13464,49 @@
 
     // ---- VK_EXT_debug_utils extension commands
     if (!strcmp("vkSetDebugUtilsObjectNameEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_debug_utils == 1)
                      ? (void *)SetDebugUtilsObjectNameEXT
                      : NULL;
         return true;
     }
     if (!strcmp("vkSetDebugUtilsObjectTagEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_debug_utils == 1)
                      ? (void *)SetDebugUtilsObjectTagEXT
                      : NULL;
         return true;
     }
     if (!strcmp("vkQueueBeginDebugUtilsLabelEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_debug_utils == 1)
                      ? (void *)QueueBeginDebugUtilsLabelEXT
                      : NULL;
         return true;
     }
     if (!strcmp("vkQueueEndDebugUtilsLabelEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_debug_utils == 1)
                      ? (void *)QueueEndDebugUtilsLabelEXT
                      : NULL;
         return true;
     }
     if (!strcmp("vkQueueInsertDebugUtilsLabelEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_debug_utils == 1)
                      ? (void *)QueueInsertDebugUtilsLabelEXT
                      : NULL;
         return true;
     }
     if (!strcmp("vkCmdBeginDebugUtilsLabelEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_debug_utils == 1)
                      ? (void *)CmdBeginDebugUtilsLabelEXT
                      : NULL;
         return true;
     }
     if (!strcmp("vkCmdEndDebugUtilsLabelEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_debug_utils == 1)
                      ? (void *)CmdEndDebugUtilsLabelEXT
                      : NULL;
         return true;
     }
     if (!strcmp("vkCmdInsertDebugUtilsLabelEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_debug_utils == 1)
                      ? (void *)CmdInsertDebugUtilsLabelEXT
                      : NULL;
         return true;
@@ -11181,6 +13570,48 @@
     }
 #endif // VK_ENABLE_BETA_EXTENSIONS
 
+    // ---- VK_EXT_descriptor_heap extension commands
+    if (!strcmp("vkWriteSamplerDescriptorsEXT", name)) {
+        *addr = (void *)WriteSamplerDescriptorsEXT;
+        return true;
+    }
+    if (!strcmp("vkWriteResourceDescriptorsEXT", name)) {
+        *addr = (void *)WriteResourceDescriptorsEXT;
+        return true;
+    }
+    if (!strcmp("vkCmdBindSamplerHeapEXT", name)) {
+        *addr = (void *)CmdBindSamplerHeapEXT;
+        return true;
+    }
+    if (!strcmp("vkCmdBindResourceHeapEXT", name)) {
+        *addr = (void *)CmdBindResourceHeapEXT;
+        return true;
+    }
+    if (!strcmp("vkCmdPushDataEXT", name)) {
+        *addr = (void *)CmdPushDataEXT;
+        return true;
+    }
+    if (!strcmp("vkGetImageOpaqueCaptureDataEXT", name)) {
+        *addr = (void *)GetImageOpaqueCaptureDataEXT;
+        return true;
+    }
+    if (!strcmp("vkGetPhysicalDeviceDescriptorSizeEXT", name)) {
+        *addr = (void *)GetPhysicalDeviceDescriptorSizeEXT;
+        return true;
+    }
+    if (!strcmp("vkRegisterCustomBorderColorEXT", name)) {
+        *addr = (void *)RegisterCustomBorderColorEXT;
+        return true;
+    }
+    if (!strcmp("vkUnregisterCustomBorderColorEXT", name)) {
+        *addr = (void *)UnregisterCustomBorderColorEXT;
+        return true;
+    }
+    if (!strcmp("vkGetTensorOpaqueCaptureDataARM", name)) {
+        *addr = (void *)GetTensorOpaqueCaptureDataARM;
+        return true;
+    }
+
     // ---- VK_EXT_sample_locations extension commands
     if (!strcmp("vkCmdSetSampleLocationsEXT", name)) {
         *addr = (void *)CmdSetSampleLocationsEXT;
@@ -11262,10 +13693,14 @@
         *addr = (void *)CreateRayTracingPipelinesNV;
         return true;
     }
+
+    // ---- VK_KHR_ray_tracing_pipeline extension commands
     if (!strcmp("vkGetRayTracingShaderGroupHandlesKHR", name)) {
         *addr = (void *)GetRayTracingShaderGroupHandlesKHR;
         return true;
     }
+
+    // ---- VK_NV_ray_tracing extension commands
     if (!strcmp("vkGetRayTracingShaderGroupHandlesNV", name)) {
         *addr = (void *)GetRayTracingShaderGroupHandlesNV;
         return true;
@@ -11347,6 +13782,24 @@
         return true;
     }
 
+    // ---- VK_EXT_present_timing extension commands
+    if (!strcmp("vkSetSwapchainPresentTimingQueueSizeEXT", name)) {
+        *addr = (void *)SetSwapchainPresentTimingQueueSizeEXT;
+        return true;
+    }
+    if (!strcmp("vkGetSwapchainTimingPropertiesEXT", name)) {
+        *addr = (void *)GetSwapchainTimingPropertiesEXT;
+        return true;
+    }
+    if (!strcmp("vkGetSwapchainTimeDomainPropertiesEXT", name)) {
+        *addr = (void *)GetSwapchainTimeDomainPropertiesEXT;
+        return true;
+    }
+    if (!strcmp("vkGetPastPresentationTimingEXT", name)) {
+        *addr = (void *)GetPastPresentationTimingEXT;
+        return true;
+    }
+
     // ---- VK_INTEL_performance_query extension commands
     if (!strcmp("vkInitializePerformanceApiINTEL", name)) {
         *addr = (void *)InitializePerformanceApiINTEL;
@@ -11565,13 +14018,13 @@
 
     // ---- VK_EXT_acquire_drm_display extension commands
     if (!strcmp("vkAcquireDrmDisplayEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_acquire_drm_display == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_acquire_drm_display == 1)
                      ? (void *)AcquireDrmDisplayEXT
                      : NULL;
         return true;
     }
     if (!strcmp("vkGetDrmDisplayEXT", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.ext_acquire_drm_display == 1)
+        *addr = (ptr_instance->enabled_extensions.ext_acquire_drm_display == 1)
                      ? (void *)GetDrmDisplayEXT
                      : NULL;
         return true;
@@ -11595,31 +14048,63 @@
         return true;
     }
 
+    // ---- VK_QCOM_queue_perf_hint extension commands
+    if (!strcmp("vkQueueSetPerfHintQCOM", name)) {
+        *addr = (void *)QueueSetPerfHintQCOM;
+        return true;
+    }
+
     // ---- VK_NV_cuda_kernel_launch extension commands
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     if (!strcmp("vkCreateCudaModuleNV", name)) {
         *addr = (void *)CreateCudaModuleNV;
         return true;
     }
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     if (!strcmp("vkGetCudaModuleCacheNV", name)) {
         *addr = (void *)GetCudaModuleCacheNV;
         return true;
     }
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     if (!strcmp("vkCreateCudaFunctionNV", name)) {
         *addr = (void *)CreateCudaFunctionNV;
         return true;
     }
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     if (!strcmp("vkDestroyCudaModuleNV", name)) {
         *addr = (void *)DestroyCudaModuleNV;
         return true;
     }
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     if (!strcmp("vkDestroyCudaFunctionNV", name)) {
         *addr = (void *)DestroyCudaFunctionNV;
         return true;
     }
+#endif // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
     if (!strcmp("vkCmdCudaLaunchKernelNV", name)) {
         *addr = (void *)CmdCudaLaunchKernelNV;
         return true;
     }
+#endif // VK_ENABLE_BETA_EXTENSIONS
+
+    // ---- VK_QCOM_tile_shading extension commands
+    if (!strcmp("vkCmdDispatchTileQCOM", name)) {
+        *addr = (void *)CmdDispatchTileQCOM;
+        return true;
+    }
+    if (!strcmp("vkCmdBeginPerTileExecutionQCOM", name)) {
+        *addr = (void *)CmdBeginPerTileExecutionQCOM;
+        return true;
+    }
+    if (!strcmp("vkCmdEndPerTileExecutionQCOM", name)) {
+        *addr = (void *)CmdEndPerTileExecutionQCOM;
+        return true;
+    }
 
     // ---- VK_EXT_metal_objects extension commands
 #if defined(VK_USE_PLATFORM_METAL_EXT)
@@ -11907,6 +14392,12 @@
         return true;
     }
 
+    // ---- VK_ARM_scheduling_controls extension commands
+    if (!strcmp("vkCmdSetDispatchParametersARM", name)) {
+        *addr = (void *)CmdSetDispatchParametersARM;
+        return true;
+    }
+
     // ---- VK_VALVE_descriptor_set_host_mapping extension commands
     if (!strcmp("vkGetDescriptorSetLayoutHostMappingInfoVALVE", name)) {
         *addr = (void *)GetDescriptorSetLayoutHostMappingInfoVALVE;
@@ -11951,6 +14442,20 @@
         return true;
     }
 
+    // ---- VK_OHOS_external_memory extension commands
+#if defined(VK_USE_PLATFORM_OHOS)
+    if (!strcmp("vkGetNativeBufferPropertiesOHOS", name)) {
+        *addr = (void *)GetNativeBufferPropertiesOHOS;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_OHOS
+#if defined(VK_USE_PLATFORM_OHOS)
+    if (!strcmp("vkGetMemoryNativeBufferOHOS", name)) {
+        *addr = (void *)GetMemoryNativeBufferOHOS;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_OHOS
+
     // ---- VK_EXT_extended_dynamic_state3 extension commands
     if (!strcmp("vkCmdSetDepthClampEnableEXT", name)) {
         *addr = (void *)CmdSetDepthClampEnableEXT;
@@ -12077,6 +14582,52 @@
         return true;
     }
 
+    // ---- VK_ARM_tensors extension commands
+    if (!strcmp("vkCreateTensorARM", name)) {
+        *addr = (void *)CreateTensorARM;
+        return true;
+    }
+    if (!strcmp("vkDestroyTensorARM", name)) {
+        *addr = (void *)DestroyTensorARM;
+        return true;
+    }
+    if (!strcmp("vkCreateTensorViewARM", name)) {
+        *addr = (void *)CreateTensorViewARM;
+        return true;
+    }
+    if (!strcmp("vkDestroyTensorViewARM", name)) {
+        *addr = (void *)DestroyTensorViewARM;
+        return true;
+    }
+    if (!strcmp("vkGetTensorMemoryRequirementsARM", name)) {
+        *addr = (void *)GetTensorMemoryRequirementsARM;
+        return true;
+    }
+    if (!strcmp("vkBindTensorMemoryARM", name)) {
+        *addr = (void *)BindTensorMemoryARM;
+        return true;
+    }
+    if (!strcmp("vkGetDeviceTensorMemoryRequirementsARM", name)) {
+        *addr = (void *)GetDeviceTensorMemoryRequirementsARM;
+        return true;
+    }
+    if (!strcmp("vkCmdCopyTensorARM", name)) {
+        *addr = (void *)CmdCopyTensorARM;
+        return true;
+    }
+    if (!strcmp("vkGetPhysicalDeviceExternalTensorPropertiesARM", name)) {
+        *addr = (void *)GetPhysicalDeviceExternalTensorPropertiesARM;
+        return true;
+    }
+    if (!strcmp("vkGetTensorOpaqueCaptureDescriptorDataARM", name)) {
+        *addr = (void *)GetTensorOpaqueCaptureDescriptorDataARM;
+        return true;
+    }
+    if (!strcmp("vkGetTensorViewOpaqueCaptureDescriptorDataARM", name)) {
+        *addr = (void *)GetTensorViewOpaqueCaptureDescriptorDataARM;
+        return true;
+    }
+
     // ---- VK_EXT_shader_module_identifier extension commands
     if (!strcmp("vkGetShaderModuleIdentifierEXT", name)) {
         *addr = (void *)GetShaderModuleIdentifierEXT;
@@ -12147,6 +14698,20 @@
         return true;
     }
 
+    // ---- VK_NV_cooperative_vector extension commands
+    if (!strcmp("vkGetPhysicalDeviceCooperativeVectorPropertiesNV", name)) {
+        *addr = (void *)GetPhysicalDeviceCooperativeVectorPropertiesNV;
+        return true;
+    }
+    if (!strcmp("vkConvertCooperativeVectorMatrixNV", name)) {
+        *addr = (void *)ConvertCooperativeVectorMatrixNV;
+        return true;
+    }
+    if (!strcmp("vkCmdConvertCooperativeVectorMatrixNV", name)) {
+        *addr = (void *)CmdConvertCooperativeVectorMatrixNV;
+        return true;
+    }
+
     // ---- VK_NV_low_latency2 extension commands
     if (!strcmp("vkSetLatencySleepModeNV", name)) {
         *addr = (void *)SetLatencySleepModeNV;
@@ -12169,6 +14734,58 @@
         return true;
     }
 
+    // ---- VK_ARM_data_graph extension commands
+    if (!strcmp("vkCreateDataGraphPipelinesARM", name)) {
+        *addr = (void *)CreateDataGraphPipelinesARM;
+        return true;
+    }
+    if (!strcmp("vkCreateDataGraphPipelineSessionARM", name)) {
+        *addr = (void *)CreateDataGraphPipelineSessionARM;
+        return true;
+    }
+    if (!strcmp("vkGetDataGraphPipelineSessionBindPointRequirementsARM", name)) {
+        *addr = (void *)GetDataGraphPipelineSessionBindPointRequirementsARM;
+        return true;
+    }
+    if (!strcmp("vkGetDataGraphPipelineSessionMemoryRequirementsARM", name)) {
+        *addr = (void *)GetDataGraphPipelineSessionMemoryRequirementsARM;
+        return true;
+    }
+    if (!strcmp("vkBindDataGraphPipelineSessionMemoryARM", name)) {
+        *addr = (void *)BindDataGraphPipelineSessionMemoryARM;
+        return true;
+    }
+    if (!strcmp("vkDestroyDataGraphPipelineSessionARM", name)) {
+        *addr = (void *)DestroyDataGraphPipelineSessionARM;
+        return true;
+    }
+    if (!strcmp("vkCmdDispatchDataGraphARM", name)) {
+        *addr = (void *)CmdDispatchDataGraphARM;
+        return true;
+    }
+    if (!strcmp("vkGetDataGraphPipelineAvailablePropertiesARM", name)) {
+        *addr = (void *)GetDataGraphPipelineAvailablePropertiesARM;
+        return true;
+    }
+    if (!strcmp("vkGetDataGraphPipelinePropertiesARM", name)) {
+        *addr = (void *)GetDataGraphPipelinePropertiesARM;
+        return true;
+    }
+    if (!strcmp("vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM", name)) {
+        *addr = (void *)GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM;
+        return true;
+    }
+    if (!strcmp("vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM", name)) {
+        *addr = (void *)GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM;
+        return true;
+    }
+
+    // ---- VK_ARM_data_graph_instruction_set_tosa extension commands
+    if (!strcmp("vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM", name)) {
+        *addr = (void *)GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM;
+        return true;
+    }
+
     // ---- VK_EXT_attachment_feedback_loop_dynamic_state extension commands
     if (!strcmp("vkCmdSetAttachmentFeedbackLoopEnableEXT", name)) {
         *addr = (void *)CmdSetAttachmentFeedbackLoopEnableEXT;
@@ -12183,6 +14800,56 @@
     }
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_QCOM_tile_memory_heap extension commands
+    if (!strcmp("vkCmdBindTileMemoryQCOM", name)) {
+        *addr = (void *)CmdBindTileMemoryQCOM;
+        return true;
+    }
+
+    // ---- VK_EXT_memory_decompression extension commands
+    if (!strcmp("vkCmdDecompressMemoryEXT", name)) {
+        *addr = (void *)CmdDecompressMemoryEXT;
+        return true;
+    }
+    if (!strcmp("vkCmdDecompressMemoryIndirectCountEXT", name)) {
+        *addr = (void *)CmdDecompressMemoryIndirectCountEXT;
+        return true;
+    }
+
+    // ---- VK_NV_external_compute_queue extension commands
+    if (!strcmp("vkCreateExternalComputeQueueNV", name)) {
+        *addr = (void *)CreateExternalComputeQueueNV;
+        return true;
+    }
+    if (!strcmp("vkDestroyExternalComputeQueueNV", name)) {
+        *addr = (void *)DestroyExternalComputeQueueNV;
+        return true;
+    }
+    if (!strcmp("vkGetExternalComputeQueueDataNV", name)) {
+        *addr = (void *)GetExternalComputeQueueDataNV;
+        return true;
+    }
+
+    // ---- VK_NV_cluster_acceleration_structure extension commands
+    if (!strcmp("vkGetClusterAccelerationStructureBuildSizesNV", name)) {
+        *addr = (void *)GetClusterAccelerationStructureBuildSizesNV;
+        return true;
+    }
+    if (!strcmp("vkCmdBuildClusterAccelerationStructureIndirectNV", name)) {
+        *addr = (void *)CmdBuildClusterAccelerationStructureIndirectNV;
+        return true;
+    }
+
+    // ---- VK_NV_partitioned_acceleration_structure extension commands
+    if (!strcmp("vkGetPartitionedAccelerationStructuresBuildSizesNV", name)) {
+        *addr = (void *)GetPartitionedAccelerationStructuresBuildSizesNV;
+        return true;
+    }
+    if (!strcmp("vkCmdBuildPartitionedAccelerationStructuresNV", name)) {
+        *addr = (void *)CmdBuildPartitionedAccelerationStructuresNV;
+        return true;
+    }
+
     // ---- VK_EXT_device_generated_commands extension commands
     if (!strcmp("vkGetGeneratedCommandsMemoryRequirementsEXT", name)) {
         *addr = (void *)GetGeneratedCommandsMemoryRequirementsEXT;
@@ -12221,12 +14888,120 @@
         return true;
     }
 
+    // ---- VK_OHOS_surface extension commands
+#if defined(VK_USE_PLATFORM_OHOS)
+    if (!strcmp("vkCreateSurfaceOHOS", name)) {
+        *addr = (ptr_instance->enabled_extensions.ohos_surface == 1)
+                     ? (void *)CreateSurfaceOHOS
+                     : NULL;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_OHOS
+
     // ---- VK_NV_cooperative_matrix2 extension commands
     if (!strcmp("vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV", name)) {
         *addr = (void *)GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV;
         return true;
     }
 
+    // ---- VK_EXT_external_memory_metal extension commands
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    if (!strcmp("vkGetMemoryMetalHandleEXT", name)) {
+        *addr = (void *)GetMemoryMetalHandleEXT;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_METAL_EXT
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    if (!strcmp("vkGetMemoryMetalHandlePropertiesEXT", name)) {
+        *addr = (void *)GetMemoryMetalHandlePropertiesEXT;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+    // ---- VK_ARM_performance_counters_by_region extension commands
+    if (!strcmp("vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM", name)) {
+        *addr = (void *)EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM;
+        return true;
+    }
+
+    // ---- VK_ARM_shader_instrumentation extension commands
+    if (!strcmp("vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM", name)) {
+        *addr = (void *)EnumeratePhysicalDeviceShaderInstrumentationMetricsARM;
+        return true;
+    }
+    if (!strcmp("vkCreateShaderInstrumentationARM", name)) {
+        *addr = (void *)CreateShaderInstrumentationARM;
+        return true;
+    }
+    if (!strcmp("vkDestroyShaderInstrumentationARM", name)) {
+        *addr = (void *)DestroyShaderInstrumentationARM;
+        return true;
+    }
+    if (!strcmp("vkCmdBeginShaderInstrumentationARM", name)) {
+        *addr = (void *)CmdBeginShaderInstrumentationARM;
+        return true;
+    }
+    if (!strcmp("vkCmdEndShaderInstrumentationARM", name)) {
+        *addr = (void *)CmdEndShaderInstrumentationARM;
+        return true;
+    }
+    if (!strcmp("vkGetShaderInstrumentationValuesARM", name)) {
+        *addr = (void *)GetShaderInstrumentationValuesARM;
+        return true;
+    }
+    if (!strcmp("vkClearShaderInstrumentationMetricsARM", name)) {
+        *addr = (void *)ClearShaderInstrumentationMetricsARM;
+        return true;
+    }
+
+    // ---- VK_EXT_fragment_density_map_offset extension commands
+    if (!strcmp("vkCmdEndRendering2EXT", name)) {
+        *addr = (void *)CmdEndRendering2EXT;
+        return true;
+    }
+
+    // ---- VK_EXT_custom_resolve extension commands
+    if (!strcmp("vkCmdBeginCustomResolveEXT", name)) {
+        *addr = (void *)CmdBeginCustomResolveEXT;
+        return true;
+    }
+
+    // ---- VK_ARM_data_graph_optical_flow extension commands
+    if (!strcmp("vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM", name)) {
+        *addr = (void *)GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM;
+        return true;
+    }
+
+    // ---- VK_NV_compute_occupancy_priority extension commands
+    if (!strcmp("vkCmdSetComputeOccupancyPriorityNV", name)) {
+        *addr = (void *)CmdSetComputeOccupancyPriorityNV;
+        return true;
+    }
+
+    // ---- VK_SEC_ubm_surface extension commands
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    if (!strcmp("vkCreateUbmSurfaceSEC", name)) {
+        *addr = (ptr_instance->enabled_extensions.sec_ubm_surface == 1)
+                     ? (void *)CreateUbmSurfaceSEC
+                     : NULL;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_UBM_SEC
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    if (!strcmp("vkGetPhysicalDeviceUbmPresentationSupportSEC", name)) {
+        *addr = (ptr_instance->enabled_extensions.sec_ubm_surface == 1)
+                     ? (void *)GetPhysicalDeviceUbmPresentationSupportSEC
+                     : NULL;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_UBM_SEC
+
+    // ---- VK_EXT_primitive_restart_index extension commands
+    if (!strcmp("vkCmdSetPrimitiveRestartIndexEXT", name)) {
+        *addr = (void *)CmdSetPrimitiveRestartIndexEXT;
+        return true;
+    }
+
     // ---- VK_KHR_acceleration_structure extension commands
     if (!strcmp("vkCreateAccelerationStructureKHR", name)) {
         *addr = (void *)CreateAccelerationStructureKHR;
@@ -12335,56 +15110,170 @@
     return false;
 }
 
-// A function that can be used to query enabled extensions during a vkCreateInstance call
-void extensions_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) {
-    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+// Used to keep track of all enabled instance extensions
+void fill_out_enabled_instance_extensions(uint32_t extension_count, const char *const * extension_list, struct loader_instance_extension_enable_list* enables) {
+    for (uint32_t i = 0; i < extension_count; i++) {
+
+    // ---- VK_KHR_surface extension commands
+        if (0 == strcmp(extension_list[i], VK_KHR_SURFACE_EXTENSION_NAME)) { enables->khr_surface = 1; }
+
+    // ---- VK_KHR_display extension commands
+        else if (0 == strcmp(extension_list[i], VK_KHR_DISPLAY_EXTENSION_NAME)) { enables->khr_display = 1; }
+
+    // ---- VK_KHR_xlib_surface extension commands
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+        else if (0 == strcmp(extension_list[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME)) { enables->khr_xlib_surface = 1; }
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+    // ---- VK_KHR_xcb_surface extension commands
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+        else if (0 == strcmp(extension_list[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME)) { enables->khr_xcb_surface = 1; }
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+    // ---- VK_KHR_wayland_surface extension commands
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+        else if (0 == strcmp(extension_list[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME)) { enables->khr_wayland_surface = 1; }
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+    // ---- VK_KHR_android_surface extension commands
+#if defined(VK_USE_PLATFORM_ANDROID_KHR)
+        else if (0 == strcmp(extension_list[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME)) { enables->khr_android_surface = 1; }
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+    // ---- VK_KHR_win32_surface extension commands
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+        else if (0 == strcmp(extension_list[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME)) { enables->khr_win32_surface = 1; }
+#endif // VK_USE_PLATFORM_WIN32_KHR
 
     // ---- VK_KHR_get_physical_device_properties2 extension commands
-        if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 = 1;
+        else if (0 == strcmp(extension_list[i], VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { enables->khr_get_physical_device_properties2 = 1; }
 
     // ---- VK_KHR_device_group_creation extension commands
-        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.khr_device_group_creation = 1;
+        else if (0 == strcmp(extension_list[i], VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) { enables->khr_device_group_creation = 1; }
 
     // ---- VK_KHR_external_memory_capabilities extension commands
-        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.khr_external_memory_capabilities = 1;
+        else if (0 == strcmp(extension_list[i], VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) { enables->khr_external_memory_capabilities = 1; }
 
     // ---- VK_KHR_external_semaphore_capabilities extension commands
-        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.khr_external_semaphore_capabilities = 1;
+        else if (0 == strcmp(extension_list[i], VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) { enables->khr_external_semaphore_capabilities = 1; }
 
     // ---- VK_KHR_external_fence_capabilities extension commands
-        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.khr_external_fence_capabilities = 1;
+        else if (0 == strcmp(extension_list[i], VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) { enables->khr_external_fence_capabilities = 1; }
+
+    // ---- VK_KHR_get_surface_capabilities2 extension commands
+        else if (0 == strcmp(extension_list[i], VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) { enables->khr_get_surface_capabilities2 = 1; }
+
+    // ---- VK_KHR_get_display_properties2 extension commands
+        else if (0 == strcmp(extension_list[i], VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME)) { enables->khr_get_display_properties2 = 1; }
+
+    // ---- VK_KHR_surface_protected_capabilities extension commands
+        else if (0 == strcmp(extension_list[i], VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME)) { enables->khr_surface_protected_capabilities = 1; }
+
+    // ---- VK_KHR_portability_enumeration extension commands
+        else if (0 == strcmp(extension_list[i], VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)) { enables->khr_portability_enumeration = 1; }
+
+    // ---- VK_KHR_surface_maintenance1 extension commands
+        else if (0 == strcmp(extension_list[i], VK_KHR_SURFACE_MAINTENANCE_1_EXTENSION_NAME)) { enables->khr_surface_maintenance1 = 1; }
+
+    // ---- VK_EXT_debug_report extension commands
+        else if (0 == strcmp(extension_list[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) { enables->ext_debug_report = 1; }
+
+    // ---- VK_GGP_stream_descriptor_surface extension commands
+#if defined(VK_USE_PLATFORM_GGP)
+        else if (0 == strcmp(extension_list[i], VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME)) { enables->ggp_stream_descriptor_surface = 1; }
+#endif // VK_USE_PLATFORM_GGP
 
     // ---- VK_NV_external_memory_capabilities extension commands
-        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.nv_external_memory_capabilities = 1;
+        else if (0 == strcmp(extension_list[i], VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) { enables->nv_external_memory_capabilities = 1; }
+
+    // ---- VK_EXT_validation_flags extension commands
+        else if (0 == strcmp(extension_list[i], VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME)) { enables->ext_validation_flags = 1; }
+
+    // ---- VK_NN_vi_surface extension commands
+#if defined(VK_USE_PLATFORM_VI_NN)
+        else if (0 == strcmp(extension_list[i], VK_NN_VI_SURFACE_EXTENSION_NAME)) { enables->nn_vi_surface = 1; }
+#endif // VK_USE_PLATFORM_VI_NN
 
     // ---- VK_EXT_direct_mode_display extension commands
-        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.ext_direct_mode_display = 1;
+        else if (0 == strcmp(extension_list[i], VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)) { enables->ext_direct_mode_display = 1; }
 
     // ---- VK_EXT_acquire_xlib_display extension commands
 #if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
-        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.ext_acquire_xlib_display = 1;
+        else if (0 == strcmp(extension_list[i], VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME)) { enables->ext_acquire_xlib_display = 1; }
 #endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
 
     // ---- VK_EXT_display_surface_counter extension commands
-        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.ext_display_surface_counter = 1;
+        else if (0 == strcmp(extension_list[i], VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) { enables->ext_display_surface_counter = 1; }
+
+    // ---- VK_EXT_swapchain_colorspace extension commands
+        else if (0 == strcmp(extension_list[i], VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME)) { enables->ext_swapchain_colorspace = 1; }
+
+    // ---- VK_MVK_ios_surface extension commands
+#if defined(VK_USE_PLATFORM_IOS_MVK)
+        else if (0 == strcmp(extension_list[i], VK_MVK_IOS_SURFACE_EXTENSION_NAME)) { enables->mvk_ios_surface = 1; }
+#endif // VK_USE_PLATFORM_IOS_MVK
+
+    // ---- VK_MVK_macos_surface extension commands
+#if defined(VK_USE_PLATFORM_MACOS_MVK)
+        else if (0 == strcmp(extension_list[i], VK_MVK_MACOS_SURFACE_EXTENSION_NAME)) { enables->mvk_macos_surface = 1; }
+#endif // VK_USE_PLATFORM_MACOS_MVK
 
     // ---- VK_EXT_debug_utils extension commands
-        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.ext_debug_utils = 1;
+        else if (0 == strcmp(extension_list[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) { enables->ext_debug_utils = 1; }
+
+    // ---- VK_FUCHSIA_imagepipe_surface extension commands
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+        else if (0 == strcmp(extension_list[i], VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME)) { enables->fuchsia_imagepipe_surface = 1; }
+#endif // VK_USE_PLATFORM_FUCHSIA
+
+    // ---- VK_EXT_metal_surface extension commands
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+        else if (0 == strcmp(extension_list[i], VK_EXT_METAL_SURFACE_EXTENSION_NAME)) { enables->ext_metal_surface = 1; }
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+    // ---- VK_EXT_validation_features extension commands
+        else if (0 == strcmp(extension_list[i], VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME)) { enables->ext_validation_features = 1; }
+
+    // ---- VK_EXT_headless_surface extension commands
+        else if (0 == strcmp(extension_list[i], VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME)) { enables->ext_headless_surface = 1; }
+
+    // ---- VK_EXT_surface_maintenance1 extension commands
+        else if (0 == strcmp(extension_list[i], VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME)) { enables->ext_surface_maintenance1 = 1; }
 
     // ---- VK_EXT_acquire_drm_display extension commands
-        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.ext_acquire_drm_display = 1;
-        }
+        else if (0 == strcmp(extension_list[i], VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME)) { enables->ext_acquire_drm_display = 1; }
+
+    // ---- VK_EXT_directfb_surface extension commands
+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+        else if (0 == strcmp(extension_list[i], VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME)) { enables->ext_directfb_surface = 1; }
+#endif // VK_USE_PLATFORM_DIRECTFB_EXT
+
+    // ---- VK_QNX_screen_surface extension commands
+#if defined(VK_USE_PLATFORM_SCREEN_QNX)
+        else if (0 == strcmp(extension_list[i], VK_QNX_SCREEN_SURFACE_EXTENSION_NAME)) { enables->qnx_screen_surface = 1; }
+#endif // VK_USE_PLATFORM_SCREEN_QNX
+
+    // ---- VK_GOOGLE_surfaceless_query extension commands
+        else if (0 == strcmp(extension_list[i], VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME)) { enables->google_surfaceless_query = 1; }
+
+    // ---- VK_LUNARG_direct_driver_loading extension commands
+        else if (0 == strcmp(extension_list[i], VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)) { enables->lunarg_direct_driver_loading = 1; }
+
+    // ---- VK_EXT_layer_settings extension commands
+        else if (0 == strcmp(extension_list[i], VK_EXT_LAYER_SETTINGS_EXTENSION_NAME)) { enables->ext_layer_settings = 1; }
+
+    // ---- VK_NV_display_stereo extension commands
+        else if (0 == strcmp(extension_list[i], VK_NV_DISPLAY_STEREO_EXTENSION_NAME)) { enables->nv_display_stereo = 1; }
+
+    // ---- VK_OHOS_surface extension commands
+#if defined(VK_USE_PLATFORM_OHOS)
+        else if (0 == strcmp(extension_list[i], VK_OHOS_SURFACE_EXTENSION_NAME)) { enables->ohos_surface = 1; }
+#endif // VK_USE_PLATFORM_OHOS
+
+    // ---- VK_SEC_ubm_surface extension commands
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+        else if (0 == strcmp(extension_list[i], VK_SEC_UBM_SURFACE_EXTENSION_NAME)) { enables->sec_ubm_surface = 1; }
+#endif // VK_USE_PLATFORM_UBM_SEC
     }
 }
 
@@ -12405,7 +15294,7 @@
     }
     if (!strcmp(name, "GetDeviceGroupSurfacePresentModesKHR")) {
         *found_name = true;
-        return dev->driver_extensions.khr_swapchain_enabled ?
+        return dev->driver_extensions.khr_swapchain_enabled || dev->driver_extensions.khr_device_group_enabled ?
             (PFN_vkVoidFunction)terminator_GetDeviceGroupSurfacePresentModesKHR : NULL;
     }
     // ---- VK_KHR_display_swapchain extension commands
@@ -12470,7 +15359,7 @@
     // ---- VK_EXT_full_screen_exclusive extension commands
     if (!strcmp(name, "GetDeviceGroupSurfacePresentModes2EXT")) {
         *found_name = true;
-        return (dev->driver_extensions.ext_full_screen_exclusive_enabled && (dev->driver_extensions.khr_device_group_enabled || dev->driver_extensions.version_1_1_enabled)) ?
+        return dev->driver_extensions.ext_full_screen_exclusive_enabled ?
             (PFN_vkVoidFunction)terminator_GetDeviceGroupSurfacePresentModes2EXT : NULL;
     }
 #endif // VK_USE_PLATFORM_WIN32_KHR
@@ -12666,6 +15555,9 @@
     .DestroyDebugUtilsMessengerEXT = terminator_DestroyDebugUtilsMessengerEXT,
     .SubmitDebugUtilsMessageEXT = terminator_SubmitDebugUtilsMessageEXT,
 
+    // ---- VK_EXT_descriptor_heap extension commands
+    .GetPhysicalDeviceDescriptorSizeEXT = terminator_GetPhysicalDeviceDescriptorSizeEXT,
+
     // ---- VK_EXT_sample_locations extension commands
     .GetPhysicalDeviceMultisamplePropertiesEXT = terminator_GetPhysicalDeviceMultisamplePropertiesEXT,
 
@@ -12727,11 +15619,46 @@
     .GetPhysicalDeviceScreenPresentationSupportQNX = terminator_GetPhysicalDeviceScreenPresentationSupportQNX,
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_ARM_tensors extension commands
+    .GetPhysicalDeviceExternalTensorPropertiesARM = terminator_GetPhysicalDeviceExternalTensorPropertiesARM,
+
     // ---- VK_NV_optical_flow extension commands
     .GetPhysicalDeviceOpticalFlowImageFormatsNV = terminator_GetPhysicalDeviceOpticalFlowImageFormatsNV,
 
+    // ---- VK_NV_cooperative_vector extension commands
+    .GetPhysicalDeviceCooperativeVectorPropertiesNV = terminator_GetPhysicalDeviceCooperativeVectorPropertiesNV,
+
+    // ---- VK_ARM_data_graph extension commands
+    .GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM = terminator_GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM,
+    .GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM = terminator_GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM,
+
+    // ---- VK_ARM_data_graph_instruction_set_tosa extension commands
+    .GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM = terminator_GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM,
+
+    // ---- VK_OHOS_surface extension commands
+#if defined(VK_USE_PLATFORM_OHOS)
+    .CreateSurfaceOHOS = terminator_CreateSurfaceOHOS,
+#endif // VK_USE_PLATFORM_OHOS
+
     // ---- VK_NV_cooperative_matrix2 extension commands
     .GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV = terminator_GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV,
+
+    // ---- VK_ARM_performance_counters_by_region extension commands
+    .EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM = terminator_EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM,
+
+    // ---- VK_ARM_shader_instrumentation extension commands
+    .EnumeratePhysicalDeviceShaderInstrumentationMetricsARM = terminator_EnumeratePhysicalDeviceShaderInstrumentationMetricsARM,
+
+    // ---- VK_ARM_data_graph_optical_flow extension commands
+    .GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM = terminator_GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM,
+
+    // ---- VK_SEC_ubm_surface extension commands
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    .CreateUbmSurfaceSEC = terminator_CreateUbmSurfaceSEC,
+#endif // VK_USE_PLATFORM_UBM_SEC
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    .GetPhysicalDeviceUbmPresentationSupportSEC = terminator_GetPhysicalDeviceUbmPresentationSupportSEC,
+#endif // VK_USE_PLATFORM_UBM_SEC
 };
 
 // A null-terminated list of all of the instance extensions supported by the loader.
@@ -12750,6 +15677,9 @@
 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
                                                   VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
 #endif // VK_USE_PLATFORM_WAYLAND_KHR
+#if defined(VK_USE_PLATFORM_ANDROID_KHR)
+                                                  VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_ANDROID_KHR
 #if defined(VK_USE_PLATFORM_WIN32_KHR)
                                                   VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
 #endif // VK_USE_PLATFORM_WIN32_KHR
@@ -12762,6 +15692,7 @@
                                                   VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME,
                                                   VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME,
                                                   VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
+                                                  VK_KHR_SURFACE_MAINTENANCE_1_EXTENSION_NAME,
                                                   VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
 #if defined(VK_USE_PLATFORM_GGP)
                                                   VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME,
@@ -12804,5 +15735,11 @@
                                                   VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME,
                                                   VK_EXT_LAYER_SETTINGS_EXTENSION_NAME,
                                                   VK_NV_DISPLAY_STEREO_EXTENSION_NAME,
+#if defined(VK_USE_PLATFORM_OHOS)
+                                                  VK_OHOS_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_OHOS
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+                                                  VK_SEC_UBM_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_UBM_SEC
                                                   NULL };
 // clang-format on
diff --git a/loader/generated/vk_loader_extensions.h b/loader/generated/vk_loader_extensions.h
index 689a3ae..472e852 100644
--- a/loader/generated/vk_loader_extensions.h
+++ b/loader/generated/vk_loader_extensions.h
@@ -2,9 +2,9 @@
 // See loader_extension_generator.py for modifications
 
 /*
- * Copyright (c) 2015-2022 The Khronos Group Inc.
- * Copyright (c) 2015-2022 Valve Corporation
- * Copyright (c) 2015-2022 LunarG, Inc.
+ * Copyright (c) 2015-2025 The Khronos Group Inc.
+ * Copyright (c) 2015-2025 Valve Corporation
+ * Copyright (c) 2015-2025 LunarG, Inc.
  * Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  * Copyright (c) 2023-2023 RasterGrid Kft.
  *
@@ -22,6 +22,7 @@
  *
  * Author: Mark Lobodzinski <mark@lunarg.com>
  * Author: Mark Young <marky@lunarg.com>
+ * Author: Charles Giessen <charles@lunarg.com>
  */
 
 // clang-format off
@@ -46,10 +47,12 @@
 // the appropriate information for any instance extensions we know about.
 bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr);
 
+struct loader_instance_extension_enable_list; // Forward declaration
+
 // Extension interception for vkCreateInstance function, so we can properly
 // detect and enable any instance extension information for extensions we know
 // about.
-void extensions_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo);
+void fill_out_enabled_instance_extensions(uint32_t extension_count, const char *const * extension_list, struct loader_instance_extension_enable_list* enables);
 
 // Extension interception for vkGetDeviceProcAddr function, so we can return
 // an appropriate terminator if this is one of those few device commands requiring
@@ -413,6 +416,9 @@
     PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT;
     PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT;
 
+    // ---- VK_EXT_descriptor_heap extension commands
+    PFN_vkGetPhysicalDeviceDescriptorSizeEXT GetPhysicalDeviceDescriptorSizeEXT;
+
     // ---- VK_EXT_sample_locations extension commands
     PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT GetPhysicalDeviceMultisamplePropertiesEXT;
 
@@ -474,39 +480,141 @@
     PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX GetPhysicalDeviceScreenPresentationSupportQNX;
 #endif // VK_USE_PLATFORM_SCREEN_QNX
 
+    // ---- VK_ARM_tensors extension commands
+    PFN_vkGetPhysicalDeviceExternalTensorPropertiesARM GetPhysicalDeviceExternalTensorPropertiesARM;
+
     // ---- VK_NV_optical_flow extension commands
     PFN_vkGetPhysicalDeviceOpticalFlowImageFormatsNV GetPhysicalDeviceOpticalFlowImageFormatsNV;
 
+    // ---- VK_NV_cooperative_vector extension commands
+    PFN_vkGetPhysicalDeviceCooperativeVectorPropertiesNV GetPhysicalDeviceCooperativeVectorPropertiesNV;
+
+    // ---- VK_ARM_data_graph extension commands
+    PFN_vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM;
+    PFN_vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM;
+
+    // ---- VK_ARM_data_graph_instruction_set_tosa extension commands
+    PFN_vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM;
+
+    // ---- VK_OHOS_surface extension commands
+#if defined(VK_USE_PLATFORM_OHOS)
+    PFN_vkCreateSurfaceOHOS CreateSurfaceOHOS;
+#endif // VK_USE_PLATFORM_OHOS
+
     // ---- VK_NV_cooperative_matrix2 extension commands
     PFN_vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV;
+
+    // ---- VK_ARM_performance_counters_by_region extension commands
+    PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM;
+
+    // ---- VK_ARM_shader_instrumentation extension commands
+    PFN_vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM EnumeratePhysicalDeviceShaderInstrumentationMetricsARM;
+
+    // ---- VK_ARM_data_graph_optical_flow extension commands
+    PFN_vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM;
+
+    // ---- VK_SEC_ubm_surface extension commands
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    PFN_vkCreateUbmSurfaceSEC CreateUbmSurfaceSEC;
+#endif // VK_USE_PLATFORM_UBM_SEC
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    PFN_vkGetPhysicalDeviceUbmPresentationSupportSEC GetPhysicalDeviceUbmPresentationSupportSEC;
+#endif // VK_USE_PLATFORM_UBM_SEC
 };
 
-struct loader_instance_extension_enables {
+struct loader_instance_extension_enable_list {
+    uint8_t khr_surface;
+    uint8_t khr_display;
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+    uint8_t khr_xlib_surface;
+#endif // defined(VK_USE_PLATFORM_XLIB_KHR)
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+    uint8_t khr_xcb_surface;
+#endif // defined(VK_USE_PLATFORM_XCB_KHR)
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    uint8_t khr_wayland_surface;
+#endif // defined(VK_USE_PLATFORM_WAYLAND_KHR)
+#if defined(VK_USE_PLATFORM_ANDROID_KHR)
+    uint8_t khr_android_surface;
+#endif // defined(VK_USE_PLATFORM_ANDROID_KHR)
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    uint8_t khr_win32_surface;
+#endif // defined(VK_USE_PLATFORM_WIN32_KHR)
     uint8_t khr_get_physical_device_properties2;
     uint8_t khr_device_group_creation;
     uint8_t khr_external_memory_capabilities;
     uint8_t khr_external_semaphore_capabilities;
     uint8_t khr_external_fence_capabilities;
+    uint8_t khr_get_surface_capabilities2;
+    uint8_t khr_get_display_properties2;
+    uint8_t khr_surface_protected_capabilities;
+    uint8_t khr_portability_enumeration;
+    uint8_t khr_surface_maintenance1;
     uint8_t ext_debug_report;
+#if defined(VK_USE_PLATFORM_GGP)
+    uint8_t ggp_stream_descriptor_surface;
+#endif // defined(VK_USE_PLATFORM_GGP)
     uint8_t nv_external_memory_capabilities;
+    uint8_t ext_validation_flags;
+#if defined(VK_USE_PLATFORM_VI_NN)
+    uint8_t nn_vi_surface;
+#endif // defined(VK_USE_PLATFORM_VI_NN)
     uint8_t ext_direct_mode_display;
+#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
     uint8_t ext_acquire_xlib_display;
+#endif // defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
     uint8_t ext_display_surface_counter;
+    uint8_t ext_swapchain_colorspace;
+#if defined(VK_USE_PLATFORM_IOS_MVK)
+    uint8_t mvk_ios_surface;
+#endif // defined(VK_USE_PLATFORM_IOS_MVK)
+#if defined(VK_USE_PLATFORM_MACOS_MVK)
+    uint8_t mvk_macos_surface;
+#endif // defined(VK_USE_PLATFORM_MACOS_MVK)
     uint8_t ext_debug_utils;
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    uint8_t fuchsia_imagepipe_surface;
+#endif // defined(VK_USE_PLATFORM_FUCHSIA)
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    uint8_t ext_metal_surface;
+#endif // defined(VK_USE_PLATFORM_METAL_EXT)
+    uint8_t ext_validation_features;
+    uint8_t ext_headless_surface;
+    uint8_t ext_surface_maintenance1;
     uint8_t ext_acquire_drm_display;
+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    uint8_t ext_directfb_surface;
+#endif // defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+#if defined(VK_USE_PLATFORM_SCREEN_QNX)
+    uint8_t qnx_screen_surface;
+#endif // defined(VK_USE_PLATFORM_SCREEN_QNX)
+    uint8_t google_surfaceless_query;
+    uint8_t lunarg_direct_driver_loading;
+    uint8_t ext_layer_settings;
+    uint8_t nv_display_stereo;
+#if defined(VK_USE_PLATFORM_OHOS)
+    uint8_t ohos_surface;
+#endif // defined(VK_USE_PLATFORM_OHOS)
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    uint8_t sec_ubm_surface;
+#endif // defined(VK_USE_PLATFORM_UBM_SEC)
 };
 
 // Functions that required a terminator need to have a separate dispatch table which contains their corresponding
 // device function. This is used in the terminators themselves.
 struct loader_device_terminator_dispatch {
+
     // ---- VK_KHR_swapchain extension commands
     PFN_vkCreateSwapchainKHR CreateSwapchainKHR;
     PFN_vkGetDeviceGroupSurfacePresentModesKHR GetDeviceGroupSurfacePresentModesKHR;
+
     // ---- VK_KHR_display_swapchain extension commands
     PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR;
+
     // ---- VK_EXT_debug_marker extension commands
     PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT;
     PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT;
+
     // ---- VK_EXT_debug_utils extension commands
     PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT;
     PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT;
@@ -517,6 +625,7 @@
     PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT;
     PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT;
 #if defined(VK_USE_PLATFORM_WIN32_KHR)
+
     // ---- VK_EXT_full_screen_exclusive extension commands
     PFN_vkGetDeviceGroupSurfacePresentModes2EXT GetDeviceGroupSurfacePresentModes2EXT;
 #endif // VK_USE_PLATFORM_WIN32_KHR
diff --git a/loader/generated/vk_object_types.h b/loader/generated/vk_object_types.h
index c7666ef..2f979d6 100644
--- a/loader/generated/vk_object_types.h
+++ b/loader/generated/vk_object_types.h
@@ -5,9 +5,9 @@
 
 /***************************************************************************
  *
- * Copyright (c) 2015-2017 The Khronos Group Inc.
- * Copyright (c) 2015-2017 Valve Corporation
- * Copyright (c) 2015-2017 LunarG, Inc.
+ * Copyright (c) 2015-2025 The Khronos Group Inc.
+ * Copyright (c) 2015-2025 Valve Corporation
+ * Copyright (c) 2015-2025 LunarG, Inc.
  * Copyright (c) 2015-2017 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,6 +27,7 @@
  * Author: Tobin Ehlis <tobine@google.com>
  * Author: Chris Forbes <chrisforbes@google.com>
  * Author: John Zulauf<jzulauf@lunarg.com>
+ * Author: Charles Giessen<charles@lunarg.com>
  *
  ****************************************************************************/
 
@@ -38,33 +39,33 @@
 // Object Type enum for validation layer internal object handling
 typedef enum VulkanObjectType {
     kVulkanObjectTypeUnknown = 0,
-    kVulkanObjectTypeBuffer = 1,
-    kVulkanObjectTypeImage = 2,
-    kVulkanObjectTypeInstance = 3,
-    kVulkanObjectTypePhysicalDevice = 4,
-    kVulkanObjectTypeDevice = 5,
-    kVulkanObjectTypeQueue = 6,
-    kVulkanObjectTypeSemaphore = 7,
-    kVulkanObjectTypeCommandBuffer = 8,
-    kVulkanObjectTypeFence = 9,
-    kVulkanObjectTypeDeviceMemory = 10,
-    kVulkanObjectTypeEvent = 11,
-    kVulkanObjectTypeQueryPool = 12,
-    kVulkanObjectTypeBufferView = 13,
-    kVulkanObjectTypeImageView = 14,
-    kVulkanObjectTypeShaderModule = 15,
-    kVulkanObjectTypePipelineCache = 16,
-    kVulkanObjectTypePipelineLayout = 17,
-    kVulkanObjectTypePipeline = 18,
-    kVulkanObjectTypeRenderPass = 19,
-    kVulkanObjectTypeDescriptorSetLayout = 20,
-    kVulkanObjectTypeSampler = 21,
-    kVulkanObjectTypeDescriptorSet = 22,
-    kVulkanObjectTypeDescriptorPool = 23,
-    kVulkanObjectTypeFramebuffer = 24,
-    kVulkanObjectTypeCommandPool = 25,
-    kVulkanObjectTypeSamplerYcbcrConversion = 26,
-    kVulkanObjectTypeDescriptorUpdateTemplate = 27,
+    kVulkanObjectTypeInstance = 1,
+    kVulkanObjectTypePhysicalDevice = 2,
+    kVulkanObjectTypeDevice = 3,
+    kVulkanObjectTypeQueue = 4,
+    kVulkanObjectTypeSemaphore = 5,
+    kVulkanObjectTypeCommandBuffer = 6,
+    kVulkanObjectTypeFence = 7,
+    kVulkanObjectTypeDeviceMemory = 8,
+    kVulkanObjectTypeBuffer = 9,
+    kVulkanObjectTypeImage = 10,
+    kVulkanObjectTypeQueryPool = 11,
+    kVulkanObjectTypeImageView = 12,
+    kVulkanObjectTypeCommandPool = 13,
+    kVulkanObjectTypeRenderPass = 14,
+    kVulkanObjectTypeFramebuffer = 15,
+    kVulkanObjectTypeEvent = 16,
+    kVulkanObjectTypeBufferView = 17,
+    kVulkanObjectTypeShaderModule = 18,
+    kVulkanObjectTypePipelineCache = 19,
+    kVulkanObjectTypePipeline = 20,
+    kVulkanObjectTypePipelineLayout = 21,
+    kVulkanObjectTypeDescriptorSetLayout = 22,
+    kVulkanObjectTypeSampler = 23,
+    kVulkanObjectTypeDescriptorSet = 24,
+    kVulkanObjectTypeDescriptorPool = 25,
+    kVulkanObjectTypeDescriptorUpdateTemplate = 26,
+    kVulkanObjectTypeSamplerYcbcrConversion = 27,
     kVulkanObjectTypePrivateDataSlot = 28,
     kVulkanObjectTypeSurfaceKHR = 29,
     kVulkanObjectTypeSwapchainKHR = 30,
@@ -73,26 +74,31 @@
     kVulkanObjectTypeVideoSessionKHR = 33,
     kVulkanObjectTypeVideoSessionParametersKHR = 34,
     kVulkanObjectTypeDeferredOperationKHR = 35,
-    kVulkanObjectTypePipelineBinaryKHR = 36,
-    kVulkanObjectTypeDebugReportCallbackEXT = 37,
-    kVulkanObjectTypeCuModuleNVX = 38,
-    kVulkanObjectTypeCuFunctionNVX = 39,
-    kVulkanObjectTypeDebugUtilsMessengerEXT = 40,
-    kVulkanObjectTypeValidationCacheEXT = 41,
-    kVulkanObjectTypeAccelerationStructureNV = 42,
-    kVulkanObjectTypePerformanceConfigurationINTEL = 43,
-    kVulkanObjectTypeIndirectCommandsLayoutNV = 44,
-    kVulkanObjectTypeCudaModuleNV = 45,
-    kVulkanObjectTypeCudaFunctionNV = 46,
-    kVulkanObjectTypeAccelerationStructureKHR = 47,
-    kVulkanObjectTypeBufferCollectionFUCHSIA = 48,
-    kVulkanObjectTypeMicromapEXT = 49,
-    kVulkanObjectTypeOpticalFlowSessionNV = 50,
-    kVulkanObjectTypeShaderEXT = 51,
-    kVulkanObjectTypeIndirectExecutionSetEXT = 52,
-    kVulkanObjectTypeIndirectCommandsLayoutEXT = 53,
-    kVulkanObjectTypeMax = 54,
-    // Aliases for backwards compatibilty of "promoted" types
+    kVulkanObjectTypeAccelerationStructureKHR = 36,
+    kVulkanObjectTypePipelineBinaryKHR = 37,
+    kVulkanObjectTypeDebugReportCallbackEXT = 38,
+    kVulkanObjectTypeCuModuleNVX = 39,
+    kVulkanObjectTypeCuFunctionNVX = 40,
+    kVulkanObjectTypeDebugUtilsMessengerEXT = 41,
+    kVulkanObjectTypeTensorARM = 42,
+    kVulkanObjectTypeValidationCacheEXT = 43,
+    kVulkanObjectTypeAccelerationStructureNV = 44,
+    kVulkanObjectTypePerformanceConfigurationINTEL = 45,
+    kVulkanObjectTypeIndirectCommandsLayoutNV = 46,
+    kVulkanObjectTypeCudaModuleNV = 47,
+    kVulkanObjectTypeCudaFunctionNV = 48,
+    kVulkanObjectTypeBufferCollectionFUCHSIA = 49,
+    kVulkanObjectTypeMicromapEXT = 50,
+    kVulkanObjectTypeTensorViewARM = 51,
+    kVulkanObjectTypeOpticalFlowSessionNV = 52,
+    kVulkanObjectTypeShaderEXT = 53,
+    kVulkanObjectTypeDataGraphPipelineSessionARM = 54,
+    kVulkanObjectTypeExternalComputeQueueNV = 55,
+    kVulkanObjectTypeIndirectExecutionSetEXT = 56,
+    kVulkanObjectTypeIndirectCommandsLayoutEXT = 57,
+    kVulkanObjectTypeShaderInstrumentationARM = 58,
+    kVulkanObjectTypeMax = 59,
+    // Aliases for backwards compatibility of "promoted" types
     kVulkanObjectTypeDescriptorUpdateTemplateKHR = kVulkanObjectTypeDescriptorUpdateTemplate,
     kVulkanObjectTypeSamplerYcbcrConversionKHR = kVulkanObjectTypeSamplerYcbcrConversion,
     kVulkanObjectTypePrivateDataSlotEXT = kVulkanObjectTypePrivateDataSlot,
@@ -101,8 +107,6 @@
 // Array of object name strings for OBJECT_TYPE enum conversion
 static const char * const object_string[kVulkanObjectTypeMax] = {
     "Unknown",
-    "Buffer",
-    "Image",
     "Instance",
     "PhysicalDevice",
     "Device",
@@ -111,23 +115,25 @@
     "CommandBuffer",
     "Fence",
     "DeviceMemory",
-    "Event",
+    "Buffer",
+    "Image",
     "QueryPool",
-    "BufferView",
     "ImageView",
+    "CommandPool",
+    "RenderPass",
+    "Framebuffer",
+    "Event",
+    "BufferView",
     "ShaderModule",
     "PipelineCache",
-    "PipelineLayout",
     "Pipeline",
-    "RenderPass",
+    "PipelineLayout",
     "DescriptorSetLayout",
     "Sampler",
     "DescriptorSet",
     "DescriptorPool",
-    "Framebuffer",
-    "CommandPool",
-    "SamplerYcbcrConversion",
     "DescriptorUpdateTemplate",
+    "SamplerYcbcrConversion",
     "PrivateDataSlot",
     "SurfaceKHR",
     "SwapchainKHR",
@@ -136,31 +142,34 @@
     "VideoSessionKHR",
     "VideoSessionParametersKHR",
     "DeferredOperationKHR",
+    "AccelerationStructureKHR",
     "PipelineBinaryKHR",
     "DebugReportCallbackEXT",
     "CuModuleNVX",
     "CuFunctionNVX",
     "DebugUtilsMessengerEXT",
+    "TensorARM",
     "ValidationCacheEXT",
     "AccelerationStructureNV",
     "PerformanceConfigurationINTEL",
     "IndirectCommandsLayoutNV",
     "CudaModuleNV",
     "CudaFunctionNV",
-    "AccelerationStructureKHR",
     "BufferCollectionFUCHSIA",
     "MicromapEXT",
+    "TensorViewARM",
     "OpticalFlowSessionNV",
     "ShaderEXT",
+    "DataGraphPipelineSessionARM",
+    "ExternalComputeQueueNV",
     "IndirectExecutionSetEXT",
     "IndirectCommandsLayoutEXT",
+    "ShaderInstrumentationARM",
 };
 
 // Helper array to get Vulkan VK_EXT_debug_report object type enum from the internal layers version
 const VkDebugReportObjectTypeEXT get_debug_report_enum[] = {
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeUnknown
-    VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,   // kVulkanObjectTypeBuffer
-    VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,   // kVulkanObjectTypeImage
     VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,   // kVulkanObjectTypeInstance
     VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,   // kVulkanObjectTypePhysicalDevice
     VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,   // kVulkanObjectTypeDevice
@@ -169,23 +178,25 @@
     VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,   // kVulkanObjectTypeCommandBuffer
     VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,   // kVulkanObjectTypeFence
     VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,   // kVulkanObjectTypeDeviceMemory
-    VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT,   // kVulkanObjectTypeEvent
+    VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,   // kVulkanObjectTypeBuffer
+    VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,   // kVulkanObjectTypeImage
     VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT,   // kVulkanObjectTypeQueryPool
-    VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT,   // kVulkanObjectTypeBufferView
     VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT,   // kVulkanObjectTypeImageView
+    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT,   // kVulkanObjectTypeCommandPool
+    VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,   // kVulkanObjectTypeRenderPass
+    VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT,   // kVulkanObjectTypeFramebuffer
+    VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT,   // kVulkanObjectTypeEvent
+    VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT,   // kVulkanObjectTypeBufferView
     VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT,   // kVulkanObjectTypeShaderModule
     VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT,   // kVulkanObjectTypePipelineCache
-    VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT,   // kVulkanObjectTypePipelineLayout
     VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,   // kVulkanObjectTypePipeline
-    VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,   // kVulkanObjectTypeRenderPass
+    VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT,   // kVulkanObjectTypePipelineLayout
     VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT,   // kVulkanObjectTypeDescriptorSetLayout
     VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT,   // kVulkanObjectTypeSampler
     VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,   // kVulkanObjectTypeDescriptorSet
     VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,   // kVulkanObjectTypeDescriptorPool
-    VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT,   // kVulkanObjectTypeFramebuffer
-    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT,   // kVulkanObjectTypeCommandPool
-    VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT,   // kVulkanObjectTypeSamplerYcbcrConversion
     VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT,   // kVulkanObjectTypeDescriptorUpdateTemplate
+    VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT,   // kVulkanObjectTypeSamplerYcbcrConversion
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypePrivateDataSlot
     VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT,   // kVulkanObjectTypeSurfaceKHR
     VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,   // kVulkanObjectTypeSwapchainKHR
@@ -194,31 +205,34 @@
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeVideoSessionKHR
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeVideoSessionParametersKHR
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeDeferredOperationKHR
+    VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT,   // kVulkanObjectTypeAccelerationStructureKHR
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypePipelineBinaryKHR
     VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT,   // kVulkanObjectTypeDebugReportCallbackEXT
     VK_DEBUG_REPORT_OBJECT_TYPE_CU_MODULE_NVX_EXT,   // kVulkanObjectTypeCuModuleNVX
     VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT,   // kVulkanObjectTypeCuFunctionNVX
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeDebugUtilsMessengerEXT
+    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeTensorARM
     VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT,   // kVulkanObjectTypeValidationCacheEXT
     VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT,   // kVulkanObjectTypeAccelerationStructureNV
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypePerformanceConfigurationINTEL
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeIndirectCommandsLayoutNV
     VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_MODULE_NV_EXT,   // kVulkanObjectTypeCudaModuleNV
     VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_FUNCTION_NV_EXT,   // kVulkanObjectTypeCudaFunctionNV
-    VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT,   // kVulkanObjectTypeAccelerationStructureKHR
     VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT,   // kVulkanObjectTypeBufferCollectionFUCHSIA
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeMicromapEXT
+    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeTensorViewARM
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeOpticalFlowSessionNV
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeShaderEXT
+    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeDataGraphPipelineSessionARM
+    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeExternalComputeQueueNV
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeIndirectExecutionSetEXT
     VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeIndirectCommandsLayoutEXT
+    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,   // kVulkanObjectTypeShaderInstrumentationARM
 };
 
 // Helper array to get Official Vulkan VkObjectType enum from the internal layers version
 const VkObjectType get_object_type_enum[] = {
     VK_OBJECT_TYPE_UNKNOWN, // kVulkanObjectTypeUnknown
-    VK_OBJECT_TYPE_BUFFER,   // kVulkanObjectTypeBuffer
-    VK_OBJECT_TYPE_IMAGE,   // kVulkanObjectTypeImage
     VK_OBJECT_TYPE_INSTANCE,   // kVulkanObjectTypeInstance
     VK_OBJECT_TYPE_PHYSICAL_DEVICE,   // kVulkanObjectTypePhysicalDevice
     VK_OBJECT_TYPE_DEVICE,   // kVulkanObjectTypeDevice
@@ -227,23 +241,25 @@
     VK_OBJECT_TYPE_COMMAND_BUFFER,   // kVulkanObjectTypeCommandBuffer
     VK_OBJECT_TYPE_FENCE,   // kVulkanObjectTypeFence
     VK_OBJECT_TYPE_DEVICE_MEMORY,   // kVulkanObjectTypeDeviceMemory
-    VK_OBJECT_TYPE_EVENT,   // kVulkanObjectTypeEvent
+    VK_OBJECT_TYPE_BUFFER,   // kVulkanObjectTypeBuffer
+    VK_OBJECT_TYPE_IMAGE,   // kVulkanObjectTypeImage
     VK_OBJECT_TYPE_QUERY_POOL,   // kVulkanObjectTypeQueryPool
-    VK_OBJECT_TYPE_BUFFER_VIEW,   // kVulkanObjectTypeBufferView
     VK_OBJECT_TYPE_IMAGE_VIEW,   // kVulkanObjectTypeImageView
+    VK_OBJECT_TYPE_COMMAND_POOL,   // kVulkanObjectTypeCommandPool
+    VK_OBJECT_TYPE_RENDER_PASS,   // kVulkanObjectTypeRenderPass
+    VK_OBJECT_TYPE_FRAMEBUFFER,   // kVulkanObjectTypeFramebuffer
+    VK_OBJECT_TYPE_EVENT,   // kVulkanObjectTypeEvent
+    VK_OBJECT_TYPE_BUFFER_VIEW,   // kVulkanObjectTypeBufferView
     VK_OBJECT_TYPE_SHADER_MODULE,   // kVulkanObjectTypeShaderModule
     VK_OBJECT_TYPE_PIPELINE_CACHE,   // kVulkanObjectTypePipelineCache
-    VK_OBJECT_TYPE_PIPELINE_LAYOUT,   // kVulkanObjectTypePipelineLayout
     VK_OBJECT_TYPE_PIPELINE,   // kVulkanObjectTypePipeline
-    VK_OBJECT_TYPE_RENDER_PASS,   // kVulkanObjectTypeRenderPass
+    VK_OBJECT_TYPE_PIPELINE_LAYOUT,   // kVulkanObjectTypePipelineLayout
     VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT,   // kVulkanObjectTypeDescriptorSetLayout
     VK_OBJECT_TYPE_SAMPLER,   // kVulkanObjectTypeSampler
     VK_OBJECT_TYPE_DESCRIPTOR_SET,   // kVulkanObjectTypeDescriptorSet
     VK_OBJECT_TYPE_DESCRIPTOR_POOL,   // kVulkanObjectTypeDescriptorPool
-    VK_OBJECT_TYPE_FRAMEBUFFER,   // kVulkanObjectTypeFramebuffer
-    VK_OBJECT_TYPE_COMMAND_POOL,   // kVulkanObjectTypeCommandPool
-    VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION,   // kVulkanObjectTypeSamplerYcbcrConversion
     VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE,   // kVulkanObjectTypeDescriptorUpdateTemplate
+    VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION,   // kVulkanObjectTypeSamplerYcbcrConversion
     VK_OBJECT_TYPE_PRIVATE_DATA_SLOT,   // kVulkanObjectTypePrivateDataSlot
     VK_OBJECT_TYPE_SURFACE_KHR,   // kVulkanObjectTypeSurfaceKHR
     VK_OBJECT_TYPE_SWAPCHAIN_KHR,   // kVulkanObjectTypeSwapchainKHR
@@ -252,24 +268,29 @@
     VK_OBJECT_TYPE_VIDEO_SESSION_KHR,   // kVulkanObjectTypeVideoSessionKHR
     VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR,   // kVulkanObjectTypeVideoSessionParametersKHR
     VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR,   // kVulkanObjectTypeDeferredOperationKHR
+    VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR,   // kVulkanObjectTypeAccelerationStructureKHR
     VK_OBJECT_TYPE_PIPELINE_BINARY_KHR,   // kVulkanObjectTypePipelineBinaryKHR
     VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT,   // kVulkanObjectTypeDebugReportCallbackEXT
     VK_OBJECT_TYPE_CU_MODULE_NVX,   // kVulkanObjectTypeCuModuleNVX
     VK_OBJECT_TYPE_CU_FUNCTION_NVX,   // kVulkanObjectTypeCuFunctionNVX
     VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT,   // kVulkanObjectTypeDebugUtilsMessengerEXT
+    VK_OBJECT_TYPE_TENSOR_ARM,   // kVulkanObjectTypeTensorARM
     VK_OBJECT_TYPE_VALIDATION_CACHE_EXT,   // kVulkanObjectTypeValidationCacheEXT
     VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV,   // kVulkanObjectTypeAccelerationStructureNV
     VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL,   // kVulkanObjectTypePerformanceConfigurationINTEL
     VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV,   // kVulkanObjectTypeIndirectCommandsLayoutNV
     VK_OBJECT_TYPE_CUDA_MODULE_NV,   // kVulkanObjectTypeCudaModuleNV
     VK_OBJECT_TYPE_CUDA_FUNCTION_NV,   // kVulkanObjectTypeCudaFunctionNV
-    VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR,   // kVulkanObjectTypeAccelerationStructureKHR
     VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA,   // kVulkanObjectTypeBufferCollectionFUCHSIA
     VK_OBJECT_TYPE_MICROMAP_EXT,   // kVulkanObjectTypeMicromapEXT
+    VK_OBJECT_TYPE_TENSOR_VIEW_ARM,   // kVulkanObjectTypeTensorViewARM
     VK_OBJECT_TYPE_OPTICAL_FLOW_SESSION_NV,   // kVulkanObjectTypeOpticalFlowSessionNV
     VK_OBJECT_TYPE_SHADER_EXT,   // kVulkanObjectTypeShaderEXT
+    VK_OBJECT_TYPE_DATA_GRAPH_PIPELINE_SESSION_ARM,   // kVulkanObjectTypeDataGraphPipelineSessionARM
+    VK_OBJECT_TYPE_EXTERNAL_COMPUTE_QUEUE_NV,   // kVulkanObjectTypeExternalComputeQueueNV
     VK_OBJECT_TYPE_INDIRECT_EXECUTION_SET_EXT,   // kVulkanObjectTypeIndirectExecutionSetEXT
     VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_EXT,   // kVulkanObjectTypeIndirectCommandsLayoutEXT
+    VK_OBJECT_TYPE_SHADER_INSTRUMENTATION_ARM,   // kVulkanObjectTypeShaderInstrumentationARM
 };
 
 // Helper function to convert from VkDebugReportObjectTypeEXT to VkObjectType
@@ -328,10 +349,10 @@
         return VK_OBJECT_TYPE_FRAMEBUFFER;
     } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT) {
         return VK_OBJECT_TYPE_COMMAND_POOL;
-    } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT) {
-        return VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION;
     } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT) {
         return VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE;
+    } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT) {
+        return VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION;
     } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
         return VK_OBJECT_TYPE_SURFACE_KHR;
     } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT) {
@@ -346,12 +367,8 @@
         return VK_OBJECT_TYPE_CU_MODULE_NVX;
     } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT) {
         return VK_OBJECT_TYPE_CU_FUNCTION_NVX;
-    } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT) {
-        return VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR;
     } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT) {
         return VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR;
-    } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT) {
-        return VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR;
     } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT) {
         return VK_OBJECT_TYPE_VALIDATION_CACHE_EXT;
     } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT) {
@@ -422,10 +439,10 @@
         return VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT;
     } else if (core_report_obj == VK_OBJECT_TYPE_COMMAND_POOL) {
         return VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT;
-    } else if (core_report_obj == VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION) {
-        return VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT;
     } else if (core_report_obj == VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE) {
         return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT;
+    } else if (core_report_obj == VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION) {
+        return VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT;
     } else if (core_report_obj == VK_OBJECT_TYPE_SURFACE_KHR) {
         return VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT;
     } else if (core_report_obj == VK_OBJECT_TYPE_SWAPCHAIN_KHR) {
@@ -440,12 +457,8 @@
         return VK_DEBUG_REPORT_OBJECT_TYPE_CU_MODULE_NVX_EXT;
     } else if (core_report_obj == VK_OBJECT_TYPE_CU_FUNCTION_NVX) {
         return VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT;
-    } else if (core_report_obj == VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR) {
-        return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT;
     } else if (core_report_obj == VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR) {
         return VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT;
-    } else if (core_report_obj == VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR) {
-        return VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT;
     } else if (core_report_obj == VK_OBJECT_TYPE_VALIDATION_CACHE_EXT) {
         return VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT;
     } else if (core_report_obj == VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV) {
diff --git a/loader/loader.c b/loader/loader.c
index ef37ecc..79f08e0 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -33,6 +33,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -98,7 +99,6 @@
 // additionally CreateDevice and DestroyDevice needs to be locked
 loader_platform_thread_mutex loader_lock;
 loader_platform_thread_mutex loader_preload_icd_lock;
-loader_platform_thread_mutex loader_global_instance_list_lock;
 
 // A list of ICDs that gets initialized when the loader does its global initialization. This list should never be used by anything
 // other than EnumerateInstanceExtensionProperties(), vkDestroyInstance, and loader_release(). This list does not change
@@ -310,32 +310,53 @@
     return VK_SUCCESS;
 }
 
-VkResult append_str_to_string_list(const struct loader_instance *inst, struct loader_string_list *string_list, char *str) {
-    assert(string_list && str);
+VkResult increase_str_capacity_by_at_least_one(const struct loader_instance *inst, struct loader_string_list *string_list) {
+    assert(string_list);
     if (string_list->allocated_count == 0) {
         string_list->allocated_count = 32;
         string_list->list =
             loader_instance_heap_calloc(inst, sizeof(char *) * string_list->allocated_count, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
         if (NULL == string_list->list) {
-            loader_instance_heap_free(inst, str);  // Must clean up in case of failure
             return VK_ERROR_OUT_OF_HOST_MEMORY;
         }
     } else if (string_list->count + 1 > string_list->allocated_count) {
         uint32_t new_allocated_count = string_list->allocated_count * 2;
-        string_list->list = loader_instance_heap_realloc(inst, string_list->list, sizeof(char *) * string_list->allocated_count,
-                                                         sizeof(char *) * new_allocated_count, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
-        if (NULL == string_list->list) {
-            loader_instance_heap_free(inst, str);  // Must clean up in case of failure
+        void *new_ptr = loader_instance_heap_realloc(inst, string_list->list, sizeof(char *) * string_list->allocated_count,
+                                                     sizeof(char *) * new_allocated_count, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+        if (NULL == new_ptr) {
             return VK_ERROR_OUT_OF_HOST_MEMORY;
         }
-        // Null out the new space
-        memset(string_list->list + string_list->allocated_count, 0, string_list->allocated_count);
+        string_list->list = new_ptr;
         string_list->allocated_count *= 2;
     }
+    return VK_SUCCESS;
+}
+
+VkResult append_str_to_string_list(const struct loader_instance *inst, struct loader_string_list *string_list, char *str) {
+    assert(string_list && str);
+    VkResult res = increase_str_capacity_by_at_least_one(inst, string_list);
+    if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
+        loader_instance_heap_free(inst, str);  // Must clean up in case of failure
+        return res;
+    }
     string_list->list[string_list->count++] = str;
     return VK_SUCCESS;
 }
 
+VkResult prepend_str_to_string_list(const struct loader_instance *inst, struct loader_string_list *string_list, char *str) {
+    assert(string_list && str);
+    VkResult res = increase_str_capacity_by_at_least_one(inst, string_list);
+    if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
+        loader_instance_heap_free(inst, str);  // Must clean up in case of failure
+        return res;
+    }
+    // Shift everything down one
+    void *ptr_to_list = memmove(string_list->list + 1, string_list->list, sizeof(char *) * string_list->count);
+    if (ptr_to_list) string_list->list[0] = str;  // Write new string to start of list
+    string_list->count++;
+    return VK_SUCCESS;
+}
+
 VkResult copy_str_to_string_list(const struct loader_instance *inst, struct loader_string_list *string_list, const char *str,
                                  size_t str_len) {
     assert(string_list && str);
@@ -348,6 +369,18 @@
     return append_str_to_string_list(inst, string_list, new_str);
 }
 
+VkResult copy_str_to_start_of_string_list(const struct loader_instance *inst, struct loader_string_list *string_list,
+                                          const char *str, size_t str_len) {
+    assert(string_list && str);
+    char *new_str = loader_instance_heap_calloc(inst, sizeof(char *) * str_len + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    if (NULL == new_str) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+    loader_strncpy(new_str, sizeof(char *) * str_len + 1, str, str_len);
+    new_str[str_len] = '\0';
+    return prepend_str_to_string_list(inst, string_list, new_str);
+}
+
 void free_string_list(const struct loader_instance *inst, struct loader_string_list *string_list) {
     assert(string_list);
     if (string_list->list) {
@@ -360,6 +393,278 @@
     memset(string_list, 0, sizeof(struct loader_string_list));
 }
 
+// In place modify the passed in path to do the following:
+// If HAVE_REALPATH is defined, then this simply calls realpath() so its behavior is defined by realpath()
+// Else:
+// * Windows-only: Replace forward slashes with backwards slashes (platform correct directory separator)
+// * Replace contiguous directory separators with a single directory separator
+// * Replace "/./" separator with "/" (where / is the platform correct directory separator)
+// * Replace "/<directory_name>/../" with just "/" (where / is the platform correct directory separator)
+VkResult normalize_path(const struct loader_instance *inst, char **passed_in_path) {
+    // passed_in_path doesn't point to anything, can't modify inplace so just return
+    if (passed_in_path == NULL) {
+        return VK_SUCCESS;
+    }
+
+// POSIX systems has the realpath() function to do this for us, fallback to basic normalization on other platforms
+#if defined(HAVE_REALPATH)
+    char *path = loader_instance_heap_calloc(inst, PATH_MAX, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    if (NULL == path) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+    char *ret = realpath(*passed_in_path, path);
+    if (NULL == ret) {
+        // error path
+        int error_code = errno;
+        loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
+                   "normalize_path: Call to realpath() failed with error code %d when given the path %s", error_code,
+                   *passed_in_path);
+        loader_instance_heap_free(inst, path);
+    } else {
+        // Replace string pointed to by passed_in_path with the one given to us by realpath()
+        loader_instance_heap_free(inst, *passed_in_path);
+        *passed_in_path = path;
+    }
+    return VK_SUCCESS;
+
+// Windows has GetFullPathName which does essentially the same thing. Note that we call GetFullPathNameA because the path has
+// already been converted from the wide char format when it was initially gotten
+#elif defined(WIN32)
+    VkResult res = VK_SUCCESS;
+    DWORD path_len = (DWORD)strlen(*passed_in_path) + 1;
+    char *path = loader_instance_heap_calloc(inst, (size_t)path_len, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    if (NULL == path) {
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
+    }
+    DWORD actual_len = GetFullPathNameA(*passed_in_path, path_len, path, NULL);
+    if (actual_len == 0) {
+        size_t last_error = (size_t)GetLastError();
+        loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
+                   "normalize_path: Call to GetFullPathNameA() failed with error code %zu when given the path %s", last_error,
+                   *passed_in_path);
+        res = VK_ERROR_INITIALIZATION_FAILED;
+        goto out;
+    }
+
+    // If path_len wasn't big enough, need to realloc and call again
+    // actual_len doesn't include null terminator
+    if (actual_len + 1 > path_len) {
+        char *new_path = loader_instance_heap_realloc(inst, path, path_len, actual_len + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+        if (NULL == new_path) {
+            loader_instance_heap_free(inst, path);
+            res = VK_ERROR_OUT_OF_HOST_MEMORY;
+            goto out;
+        }
+        path = new_path;
+        // store the updated allocation size (sans null terminator)
+        path_len = actual_len + 1;
+
+        actual_len = GetFullPathNameA(*passed_in_path, path_len, path, NULL);
+        if (actual_len == 0) {
+            size_t last_error = (size_t)GetLastError();
+            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
+                       "normalize_path: Call to GetFullPathNameA() failed with error code %zu when given the path %s", last_error,
+                       *passed_in_path);
+            res = VK_ERROR_INITIALIZATION_FAILED;
+            goto out;
+            // actual_len doesn't include null terminator
+        } else if (actual_len + 1 != path_len) {
+            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
+                       "normalize_path: Call to GetFullPathNameA() with too small of a buffer when given the path %s after the "
+                       "initial call to GetFullPathNameA() failed for the same reason. Buffer size is %zu, actual size is %zu",
+                       *passed_in_path, (size_t)path_len, (size_t)actual_len);
+            res = VK_ERROR_INITIALIZATION_FAILED;
+            goto out;
+        }
+    }
+    // Replace string pointed to by passed_in_path with the one given to us by realpath()
+    loader_instance_heap_free(inst, *passed_in_path);
+    *passed_in_path = path;
+out:
+    if (VK_SUCCESS != res) {
+        if (NULL != path) {
+            loader_instance_heap_free(inst, path);
+        }
+    }
+    return res;
+
+#else
+    (void)inst;
+    char *path = *passed_in_path;
+    size_t path_len = strlen(path) + 1;
+
+    size_t output_index = 0;
+    // Iterate through the string up to the last character, excluding the null terminator
+    for (size_t i = 0; i < path_len - 1; i++) {
+        if (i + 1 < path_len && path[i] == DIRECTORY_SYMBOL && path[i + 1] == DIRECTORY_SYMBOL) {
+            continue;
+        } else if (i + 2 < path_len && path[i] == DIRECTORY_SYMBOL && path[i + 1] == '.' && path[i + 2] == DIRECTORY_SYMBOL) {
+            i += 1;
+        } else {
+            path[output_index++] = path[i];
+        }
+    }
+    // Add null terminator and set the new length
+    path[output_index++] = '\0';
+    path_len = output_index;
+
+    // Loop while there are still ..'s in the path. Easiest implementation resolves them one by one, which requires quadratic
+    // iteration through the string
+    char *directory_stack = loader_stack_alloc(path_len);
+    if (directory_stack == NULL) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+
+    size_t top_of_stack = 0;
+
+    // Iterate through the path, push characters as we see them, if we find a "..", pop off the top of the directory stack until the
+    // current directory is gone.
+    for (size_t i = 0; i < path_len - 1; i++) {
+        // if the next part of path is "/../" we need to pop from the directory stack until we hit the previous directory symbol.
+        if (i + 3 < path_len && path[i] == DIRECTORY_SYMBOL && path[i + 1] == '.' && path[i + 2] == '.' && path_len &&
+            path[i + 3] == DIRECTORY_SYMBOL) {
+            // Pop until we hit the next directory symbol in the stack
+            while (top_of_stack > 0 && directory_stack[top_of_stack - 1] != DIRECTORY_SYMBOL) {
+                top_of_stack--;
+                directory_stack[top_of_stack] = '\0';
+            }
+            // Amend the directory stack so that the top isn't a directory separator
+            if (top_of_stack > 0 && directory_stack[top_of_stack - 1] == DIRECTORY_SYMBOL) {
+                top_of_stack--;
+                directory_stack[top_of_stack] = '\0';
+            }
+            i += 2;  // need to skip the second dot & directory separator
+        } else {
+            // push characters as we come across them
+            directory_stack[top_of_stack++] = path[i];
+        }
+    }
+
+    // Can't forget the null terminator
+    directory_stack[top_of_stack] = '\0';
+
+    // We now have the path without any ..'s, so just copy it out
+    loader_strncpy(path, path_len, directory_stack, path_len);
+    path[top_of_stack] = '\0';
+    path_len = top_of_stack + 1;
+
+    return VK_SUCCESS;
+#endif
+}
+
+// Queries the path to the library that lib_handle & gipa are associated with, allocating a string to hold it and returning it in
+// out_path
+VkResult get_library_path_of_dl_handle(const struct loader_instance *inst, loader_platform_dl_handle lib_handle,
+                                       PFN_vkGetInstanceProcAddr gipa, char **out_path) {
+#if COMMON_UNIX_PLATFORMS
+    (void)lib_handle;
+    Dl_info dl_info = {0};
+    if (dladdr(gipa, &dl_info) != 0 && NULL != dl_info.dli_fname) {
+        return loader_copy_to_new_str(inst, dl_info.dli_fname, out_path);
+    }
+    return VK_SUCCESS;
+
+#elif defined(WIN32)
+    (void)gipa;
+    size_t module_file_name_len = MAX_PATH;  // start with reasonably large buffer
+    wchar_t *buffer_utf16 = (wchar_t *)loader_stack_alloc(module_file_name_len * sizeof(wchar_t));
+    DWORD ret = GetModuleFileNameW(lib_handle, buffer_utf16, (DWORD)module_file_name_len);
+    if (ret == 0) {
+        return VK_SUCCESS;
+    }
+    while (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+        module_file_name_len *= 2;
+        buffer_utf16 = (wchar_t *)loader_stack_alloc(module_file_name_len * sizeof(wchar_t));
+        ret = GetModuleFileNameW(lib_handle, buffer_utf16, (DWORD)module_file_name_len);
+        if (ret == 0) {
+            return VK_SUCCESS;
+        }
+    }
+
+    // Need to convert from utf16 to utf8
+    int buffer_utf8_size = WideCharToMultiByte(CP_UTF8, 0, buffer_utf16, -1, NULL, 0, NULL, NULL);
+    if (buffer_utf8_size <= 0) {
+        return VK_SUCCESS;
+    }
+
+    char *buffer_utf8 = loader_instance_heap_calloc(inst, buffer_utf8_size, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    if (NULL == buffer_utf8) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+    if (WideCharToMultiByte(CP_UTF8, 0, buffer_utf16, -1, buffer_utf8, buffer_utf8_size, NULL, NULL) != buffer_utf8_size) {
+        return VK_SUCCESS;
+    }
+
+    // Successfully got the 'real' path to the library.
+    *out_path = buffer_utf8;
+    return VK_SUCCESS;
+
+#else
+    // Do nothing, platform doesn't handle getting the path to a library
+#endif
+}
+
+// Find and replace the path that was loaded using the lib_name path with the real path of the library. This is done to provide
+// accurate logging info for users.
+// This function prints a warning if there is a mismatch between the lib_name path and the real path.
+VkResult fixup_library_binary_path(const struct loader_instance *inst, char **lib_name, loader_platform_dl_handle lib_handle,
+                                   PFN_vkGetInstanceProcAddr gipa) {
+    if (lib_name == NULL) {
+        // do nothing as we got an invalid lib_path pointer
+        return VK_SUCCESS;
+    }
+
+    bool system_path = true;
+    size_t lib_name_len = strlen(*lib_name) + 1;
+    for (size_t i = 0; i < lib_name_len; i++) {
+        if ((*lib_name)[i] == DIRECTORY_SYMBOL) {
+            system_path = false;
+            break;
+        }
+    }
+
+    if (!system_path) {
+        // The OS path we get for a binary is normalized, so we need to normalize the path passed into LoadLibrary/dlopen so that
+        // mismatches are minimized. EG, do not warn when we give dlopen/LoadLibrary "/foo/./bar" but get "/foo/bar" as the loaded
+        // binary path from the OS.
+        VkResult res = normalize_path(inst, lib_name);
+        if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
+            return res;
+        }
+    }
+    char *os_determined_lib_name = NULL;
+    VkResult res = get_library_path_of_dl_handle(inst, lib_handle, gipa, &os_determined_lib_name);
+    if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
+        return res;
+    }
+
+    if (NULL != os_determined_lib_name) {
+        // Normalize the path so that the comparison doesn't yield false positives
+        res = normalize_path(inst, &os_determined_lib_name);
+        if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
+            loader_instance_heap_free(inst, os_determined_lib_name);
+            return res;
+        }
+
+        if (0 != strcmp(os_determined_lib_name, *lib_name)) {
+            // Paths do not match, so we need to replace lib_name with the real path
+            if (!system_path) {
+                // Only warn when the library_path is relative or absolute, not system. EG lib_name had no directory separators
+                loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0,
+                           "Path to given binary %s was found to differ from OS loaded path %s", *lib_name, os_determined_lib_name);
+            }
+            loader_instance_heap_free(inst, *lib_name);
+            *lib_name = os_determined_lib_name;
+        } else {
+            // Paths match, so just need to free temporary allocation
+            loader_instance_heap_free(inst, os_determined_lib_name);
+        }
+    }
+
+    return res;
+}
+
 // Given string of three part form "maj.min.pat" convert to a vulkan version number.
 // Also can understand four part form "variant.major.minor.patch" if provided.
 uint32_t loader_parse_version_string(char *vers_str) {
@@ -444,7 +749,6 @@
             goto out;
         }
         layer_list->list = new_ptr;
-        memset((uint8_t *)layer_list->list + layer_list->capacity, 0, layer_list->capacity);
         layer_list->capacity *= 2;
     }
     memcpy(&layer_list->list[layer_list->count], layer_property, sizeof(struct loader_layer_properties));
@@ -513,7 +817,8 @@
 }
 
 // Remove all layer properties entries from the list
-void loader_delete_layer_list_and_properties(const struct loader_instance *inst, struct loader_layer_list *layer_list) {
+TEST_FUNCTION_EXPORT void loader_delete_layer_list_and_properties(const struct loader_instance *inst,
+                                                                  struct loader_layer_list *layer_list) {
     uint32_t i;
     if (!layer_list) return;
 
@@ -672,6 +977,7 @@
         res = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
     }
+    memset(ext_props, 0, count * sizeof(VkExtensionProperties));
 
     res = fp_get_props(NULL, &count, ext_props);
     if (res != VK_SUCCESS) {
@@ -745,12 +1051,13 @@
 }
 
 VkResult loader_resize_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info) {
-    list_info->list = loader_instance_heap_realloc(inst, list_info->list, list_info->capacity, list_info->capacity * 2,
-                                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
-    if (list_info->list == NULL) {
+    void *new_ptr = loader_instance_heap_realloc(inst, list_info->list, list_info->capacity, list_info->capacity * 2,
+                                                 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    if (new_ptr == NULL) {
         loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_resize_generic_list: Failed to allocate space for generic list");
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
+    list_info->list = new_ptr;
     list_info->capacity = list_info->capacity * 2;
     return VK_SUCCESS;
 }
@@ -1328,7 +1635,7 @@
         *found_dev = NULL;
         return NULL;
     }
-    loader_platform_thread_lock_mutex(&loader_global_instance_list_lock);
+    loader_platform_thread_lock_mutex(&loader_lock);
     *found_dev = NULL;
 
     for (struct loader_instance *inst = loader.instances; inst; inst = inst->next) {
@@ -1338,13 +1645,13 @@
                 if (loader_get_dispatch(dev->icd_device) == dispatch_table_device ||
                     (dev->chain_device != VK_NULL_HANDLE && loader_get_dispatch(dev->chain_device) == dispatch_table_device)) {
                     *found_dev = dev;
-                    loader_platform_thread_unlock_mutex(&loader_global_instance_list_lock);
+                    loader_platform_thread_unlock_mutex(&loader_lock);
                     return icd_term;
                 }
             }
         }
     }
-    loader_platform_thread_unlock_mutex(&loader_global_instance_list_lock);
+    loader_platform_thread_unlock_mutex(&loader_lock);
     return NULL;
 }
 
@@ -1831,6 +2138,7 @@
         loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "loader_scanned_icd_add: ICD %s doesn't support interface version compatible with loader, skip this ICD.",
                    filename);
+        res = VK_ERROR_INCOMPATIBLE_DRIVER;
         goto out;
     }
 
@@ -1848,6 +2156,7 @@
                        "loader_scanned_icd_add: ICD %s reports an interface version of %d but doesn't export "
                        "vk_icdGetInstanceProcAddr, skip this ICD.",
                        filename, interface_vers);
+            res = VK_ERROR_INCOMPATIBLE_DRIVER;
             goto out;
         }
         // Use deprecated interface from version 0
@@ -1857,6 +2166,7 @@
                        "loader_scanned_icd_add: Attempt to retrieve either \'vkGetInstanceProcAddr\' or "
                        "\'vk_icdGetInstanceProcAddr\' from ICD %s failed.",
                        filename);
+            res = VK_ERROR_INCOMPATIBLE_DRIVER;
             goto out;
         } else {
             loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
@@ -1868,6 +2178,7 @@
         if (NULL == fp_create_inst) {
             loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
                        "loader_scanned_icd_add:  Failed querying \'vkCreateInstance\' via dlsym/LoadLibrary for ICD %s", filename);
+            res = VK_ERROR_INCOMPATIBLE_DRIVER;
             goto out;
         }
         fp_get_inst_ext_props = loader_platform_get_proc_address(handle, "vkEnumerateInstanceExtensionProperties");
@@ -1876,6 +2187,7 @@
                        "loader_scanned_icd_add: Could not get \'vkEnumerateInstanceExtensionProperties\' via dlsym/LoadLibrary "
                        "for ICD %s",
                        filename);
+            res = VK_ERROR_INCOMPATIBLE_DRIVER;
             goto out;
         }
     } else {
@@ -1891,6 +2203,7 @@
             loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
                        "loader_scanned_icd_add: Could not get \'vkCreateInstance\' via \'vk_icdGetInstanceProcAddr\' for ICD %s",
                        filename);
+            res = VK_ERROR_INCOMPATIBLE_DRIVER;
             goto out;
         }
         fp_get_inst_ext_props =
@@ -1900,6 +2213,7 @@
                        "loader_scanned_icd_add: Could not get \'vkEnumerateInstanceExtensionProperties\' via "
                        "\'vk_icdGetInstanceProcAddr\' for ICD %s",
                        filename);
+            res = VK_ERROR_INCOMPATIBLE_DRIVER;
             goto out;
         }
         // Query "vk_icdGetPhysicalDeviceProcAddr" with vk_icdGetInstanceProcAddr if the library reports interface version 7 or
@@ -1965,9 +2279,22 @@
         loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_scanned_icd_add: Out of memory can't add ICD %s", filename);
         goto out;
     }
+
+    // Uses OS calls to find the 'true' path to the binary, for more accurate logging later on.
+    res = fixup_library_binary_path(inst, &(new_scanned_icd->lib_name), new_scanned_icd->handle, fp_get_proc_addr);
+    if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
+        loader_instance_heap_free(inst, new_scanned_icd->lib_name);
+        goto out;
+    }
+
     icd_tramp_list->count++;
 
 out:
+    if (res != VK_SUCCESS) {
+        if (NULL != handle) {
+            loader_platform_close_library(handle);
+        }
+    }
 
     return res;
 }
@@ -1981,7 +2308,6 @@
 void loader_initialize(void) {
     loader_platform_thread_create_mutex(&loader_lock);
     loader_platform_thread_create_mutex(&loader_preload_icd_lock);
-    loader_platform_thread_create_mutex(&loader_global_instance_list_lock);
     init_global_loader_settings();
 #endif
 
@@ -2018,7 +2344,7 @@
 #endif
 }
 
-void loader_release() {
+void loader_release(void) {
     // Guarantee release of the preloaded ICD libraries. This may have already been called in vkDestroyInstance.
     loader_unload_preloaded_icds();
 
@@ -2030,7 +2356,6 @@
     teardown_global_loader_settings();
     loader_platform_thread_delete_mutex(&loader_lock);
     loader_platform_thread_delete_mutex(&loader_preload_icd_lock);
-    loader_platform_thread_delete_mutex(&loader_global_instance_list_lock);
 }
 
 // Preload the ICD libraries that are likely to be needed so we don't repeatedly load/unload them later
@@ -2243,7 +2568,7 @@
             }
             if (comp_prop_index != INT32_MAX && already_checked_meta_layers[comp_prop_index]) {
                 loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
-                           "verify_meta_layer_component_layers: Recursive depedency between Meta-layer %s and  Meta-layer %s.  "
+                           "verify_meta_layer_component_layers: Recursive dependency between Meta-layer %s and  Meta-layer %s.  "
                            "Skipping this layer.",
                            instance_layers->list[prop_index].info.layerName, comp_prop->info.layerName);
                 return false;
@@ -2472,6 +2797,7 @@
         loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
                    "Layer located at %s didn't find required layer value \"type\" in manifest JSON file, skipping this layer",
                    filename);
+        result = VK_ERROR_INITIALIZATION_FAILED;
         goto out;
     }
 
@@ -2529,8 +2855,7 @@
 
     // Parse description
 
-    result =
-        loader_parse_json_string_to_existing_str(layer_node, "description", VK_MAX_EXTENSION_NAME_SIZE, props.info.description);
+    result = loader_parse_json_string_to_existing_str(layer_node, "description", VK_MAX_DESCRIPTION_SIZE, props.info.description);
     if (VK_ERROR_INITIALIZATION_FAILED == result) {
         loader_log(
             inst, VULKAN_LOADER_WARN_BIT, 0,
@@ -2913,9 +3238,13 @@
         // Otherwise, try to read in individual layers
         cJSON *layer_node = loader_cJSON_GetObjectItem(json, "layer");
         if (layer_node == NULL) {
-            loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0,
-                       "loader_add_layer_properties: Can not find 'layer' object in manifest JSON file %s.  Skipping this file.",
-                       filename);
+            // Don't warn if this happens to be an ICD manifest
+            if (loader_cJSON_GetObjectItem(json, "ICD") == NULL) {
+                loader_log(
+                    inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0,
+                    "loader_add_layer_properties: Can not find 'layer' object in manifest JSON file %s.  Skipping this file.",
+                    filename);
+            }
             goto out;
         }
         // Loop through all "layer" objects in the file to get a count of them
@@ -2974,7 +3303,7 @@
         char *cur_write = *output_path;
 
         while (cur_path[start] != '\0') {
-            while (cur_path[start] == PATH_SEPARATOR) {
+            while (cur_path[start] == PATH_SEPARATOR && cur_path[start] != '\0') {
                 start++;
             }
             stop = start;
@@ -3008,10 +3337,8 @@
     }
 }
 
-// If the file found is a manifest file name, add it to the out_files manifest list.
+// If the file found is a manifest file name, add it to the end of out_files manifest list.
 VkResult add_if_manifest_file(const struct loader_instance *inst, const char *file_name, struct loader_string_list *out_files) {
-    VkResult vk_result = VK_SUCCESS;
-
     assert(NULL != file_name && "add_if_manifest_file: Received NULL pointer for file_name");
     assert(NULL != out_files && "add_if_manifest_file: Received NULL pointer for out_files");
 
@@ -3020,15 +3347,26 @@
     const char *name_suffix = file_name + name_len - 5;
     if (!is_json(name_suffix, name_len)) {
         // Use incomplete to indicate invalid name, but to keep going.
-        vk_result = VK_INCOMPLETE;
-        goto out;
+        return VK_INCOMPLETE;
     }
 
-    vk_result = copy_str_to_string_list(inst, out_files, file_name, name_len);
+    return copy_str_to_string_list(inst, out_files, file_name, name_len);
+}
 
-out:
+// If the file found is a manifest file name, add it to the start of the out_files manifest list.
+VkResult prepend_if_manifest_file(const struct loader_instance *inst, const char *file_name, struct loader_string_list *out_files) {
+    assert(NULL != file_name && "prepend_if_manifest_file: Received NULL pointer for file_name");
+    assert(NULL != out_files && "prepend_if_manifest_file: Received NULL pointer for out_files");
 
-    return vk_result;
+    // Look for files ending with ".json" suffix
+    size_t name_len = strlen(file_name);
+    const char *name_suffix = file_name + name_len - 5;
+    if (!is_json(name_suffix, name_len)) {
+        // Use incomplete to indicate invalid name, but to keep going.
+        return VK_INCOMPLETE;
+    }
+
+    return copy_str_to_start_of_string_list(inst, out_files, file_name, name_len);
 }
 
 // Add any files found in the search_path.  If any path in the search path points to a specific JSON, attempt to
@@ -3153,8 +3491,8 @@
     char *cur_path_ptr = NULL;
     bool use_first_found_manifest = false;
 #if COMMON_UNIX_PLATFORMS
-    char *relative_location = NULL;  // Only used on unix platforms
-    size_t rel_size = 0;             // unused in windows, dont declare so no compiler warnings are generated
+    const char *relative_location = NULL;  // Only used on unix platforms
+    size_t rel_size = 0;                   // unused in windows, dont declare so no compiler warnings are generated
 #endif
     int dir_fd = -1;
 
@@ -3230,12 +3568,14 @@
 
     switch (manifest_type) {
         case LOADER_DATA_FILE_MANIFEST_DRIVER:
-            override_env = loader_secure_getenv(VK_DRIVER_FILES_ENV_VAR, inst);
-            if (NULL == override_env) {
-                // Not there, so fall back to the old name
-                override_env = loader_secure_getenv(VK_ICD_FILENAMES_ENV_VAR, inst);
+            if (loader_settings_should_use_driver_environment_variables(inst)) {
+                override_env = loader_secure_getenv(VK_DRIVER_FILES_ENV_VAR, inst);
+                if (NULL == override_env) {
+                    // Not there, so fall back to the old name
+                    override_env = loader_secure_getenv(VK_ICD_FILENAMES_ENV_VAR, inst);
+                }
+                additional_env = loader_secure_getenv(VK_ADDITIONAL_DRIVER_FILES_ENV_VAR, inst);
             }
-            additional_env = loader_secure_getenv(VK_ADDITIONAL_DRIVER_FILES_ENV_VAR, inst);
 #if COMMON_UNIX_PLATFORMS
             relative_location = VK_DRIVERS_INFO_RELATIVE_DIR;
 #endif
@@ -3380,9 +3720,6 @@
                         memcpy(cur_path_ptr, relative_location, rel_size);
                         cur_path_ptr += rel_size;
                         *cur_path_ptr++ = PATH_SEPARATOR;
-                        if (manifest_type == LOADER_DATA_FILE_MANIFEST_DRIVER) {
-                            use_first_found_manifest = true;
-                        }
                     }
                     CFRelease(ref);
                 }
@@ -3650,8 +3987,12 @@
 
     cJSON *itemICD = loader_cJSON_GetObjectItem(icd_manifest_json, "ICD");
     if (itemICD == NULL) {
-        loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
-                   "loader_parse_icd_manifest: Can not find \'ICD\' object in ICD JSON file %s. Skipping ICD JSON", file_str);
+        // Don't warn if this happens to be a layer manifest file
+        if (loader_cJSON_GetObjectItem(icd_manifest_json, "layer") == NULL &&
+            loader_cJSON_GetObjectItem(icd_manifest_json, "layers") == NULL) {
+            loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
+                       "loader_parse_icd_manifest: Can not find \'ICD\' object in ICD JSON file %s. Skipping ICD JSON", file_str);
+        }
         res = VK_ERROR_INCOMPATIBLE_DRIVER;
         goto out;
     }
@@ -3726,9 +4067,8 @@
 
     char *library_arch_str = loader_cJSON_GetStringValue(loader_cJSON_GetObjectItem(itemICD, "library_arch"));
     if (library_arch_str != NULL) {
-        // cJSON includes the quotes by default, so we need to look for those here
-        if ((strncmp(library_arch_str, "32", 4) == 0 && sizeof(void *) != 4) ||
-            (strncmp(library_arch_str, "64", 4) == 0 && sizeof(void *) != 8)) {
+        if ((strncmp(library_arch_str, "32", 2) == 0 && sizeof(void *) != 4) ||
+            (strncmp(library_arch_str, "64", 2) == 0 && sizeof(void *) != 8)) {
             loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
                        "loader_parse_icd_manifest: Driver library architecture doesn't match the current running "
                        "architecture, skipping this driver");
@@ -3780,14 +4120,16 @@
         goto out;
     }
 
-    // Parse the filter environment variables to determine if we have any special behavior
-    res = parse_generic_filter_environment_var(inst, VK_DRIVERS_SELECT_ENV_VAR, &select_filter);
-    if (VK_SUCCESS != res) {
-        goto out;
-    }
-    res = parse_generic_filter_environment_var(inst, VK_DRIVERS_DISABLE_ENV_VAR, &disable_filter);
-    if (VK_SUCCESS != res) {
-        goto out;
+    if (loader_settings_should_use_driver_environment_variables(inst)) {
+        // Parse the filter environment variables to determine if we have any special behavior
+        res = parse_generic_filter_environment_var(inst, VK_DRIVERS_SELECT_ENV_VAR, &select_filter);
+        if (VK_SUCCESS != res) {
+            goto out;
+        }
+        res = parse_generic_filter_environment_var(inst, VK_DRIVERS_DISABLE_ENV_VAR, &disable_filter);
+        if (VK_SUCCESS != res) {
+            goto out;
+        }
     }
 
     // Get a list of manifest files for ICDs
@@ -3796,6 +4138,12 @@
         goto out;
     }
 
+    // Add any drivers provided by the loader settings file
+    res = loader_settings_get_additional_driver_files(inst, &manifest_files);
+    if (VK_SUCCESS != res) {
+        goto out;
+    }
+
     icd_details = loader_stack_alloc(sizeof(struct ICDManifestInfo) * manifest_files.count);
     if (NULL == icd_details) {
         res = VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -3954,9 +4302,13 @@
         for (uint32_t j = 0; j < prop->override_paths.count; j++) {
             copy_data_file_info(prop->override_paths.list[j], NULL, 0, &cur_write_ptr);
         }
+
+        // Subtract one from cur_write_ptr only if something was written so we can set the null terminator
+        if (*override_paths < cur_write_ptr) {
+            --cur_write_ptr;
+            assert(cur_write_ptr - (*override_paths) < (ptrdiff_t)override_path_size);
+        }
         // Remove the last path separator
-        --cur_write_ptr;
-        assert(cur_write_ptr - (*override_paths) < (ptrdiff_t)override_path_size);
         *cur_write_ptr = '\0';
         loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0, "Override layer has override paths set to %s",
                    *override_paths);
@@ -3964,6 +4316,27 @@
     return VK_SUCCESS;
 }
 
+void loader_remove_duplicate_layers(struct loader_instance *inst, struct loader_layer_list *layers) {
+    // Remove duplicate layers (that share the same layerName)
+    for (uint32_t i = 0; i < layers->count; ++i) {
+        bool has_duplicate = false;
+        uint32_t duplicate_index = 0;
+        for (uint32_t j = i + 1; j < layers->count; ++j) {
+            if (strcmp(layers->list[i].info.layerName, layers->list[j].info.layerName) == 0) {
+                has_duplicate = true;
+                duplicate_index = j;
+                break;
+            }
+        }
+        if (has_duplicate) {
+            loader_log(inst, VULKAN_LOADER_WARN_BIT, 0, "Removing layer %s (%s) because it is a duplicate of %s (%s)",
+                       layers->list[duplicate_index].info.layerName, layers->list[duplicate_index].manifest_file_name,
+                       layers->list[i].info.layerName, layers->list[i].manifest_file_name);
+            loader_remove_layer_in_list(inst, layers, duplicate_index);
+        }
+    }
+}
+
 VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers,
                                 const struct loader_envvar_all_filters *filters) {
     VkResult res = VK_SUCCESS;
@@ -4034,6 +4407,9 @@
         }
     }
 
+    // Make sure no layers have the same layerName
+    loader_remove_duplicate_layers(inst, &regular_instance_layers);
+
     res = combine_settings_layers_with_regular_layers(inst, &settings_layers, &regular_instance_layers, instance_layers);
 
 out:
@@ -4134,6 +4510,9 @@
         }
     }
 
+    // Make sure no layers have the same layerName
+    loader_remove_duplicate_layers(inst, &regular_instance_layers);
+
     res = combine_settings_layers_with_regular_layers(inst, &settings_layers, &regular_instance_layers, instance_layers);
 
 out:
@@ -4223,36 +4602,29 @@
     // These functions need a terminator to handle the case of a driver not supporting VK_EXT_debug_utils when there are layers
     // present which not check for NULL before calling the function.
     if (!strcmp(pName, "vkSetDebugUtilsObjectNameEXT")) {
-        return loader_inst->enabled_known_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_SetDebugUtilsObjectNameEXT
-                                                                     : NULL;
+        return loader_inst->enabled_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_SetDebugUtilsObjectNameEXT : NULL;
     }
     if (!strcmp(pName, "vkSetDebugUtilsObjectTagEXT")) {
-        return loader_inst->enabled_known_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_SetDebugUtilsObjectTagEXT
-                                                                     : NULL;
+        return loader_inst->enabled_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_SetDebugUtilsObjectTagEXT : NULL;
     }
     if (!strcmp(pName, "vkQueueBeginDebugUtilsLabelEXT")) {
-        return loader_inst->enabled_known_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_QueueBeginDebugUtilsLabelEXT
-                                                                     : NULL;
+        return loader_inst->enabled_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_QueueBeginDebugUtilsLabelEXT : NULL;
     }
     if (!strcmp(pName, "vkQueueEndDebugUtilsLabelEXT")) {
-        return loader_inst->enabled_known_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_QueueEndDebugUtilsLabelEXT
-                                                                     : NULL;
+        return loader_inst->enabled_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_QueueEndDebugUtilsLabelEXT : NULL;
     }
     if (!strcmp(pName, "vkQueueInsertDebugUtilsLabelEXT")) {
-        return loader_inst->enabled_known_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_QueueInsertDebugUtilsLabelEXT
-                                                                     : NULL;
+        return loader_inst->enabled_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_QueueInsertDebugUtilsLabelEXT
+                                                               : NULL;
     }
     if (!strcmp(pName, "vkCmdBeginDebugUtilsLabelEXT")) {
-        return loader_inst->enabled_known_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_CmdBeginDebugUtilsLabelEXT
-                                                                     : NULL;
+        return loader_inst->enabled_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_CmdBeginDebugUtilsLabelEXT : NULL;
     }
     if (!strcmp(pName, "vkCmdEndDebugUtilsLabelEXT")) {
-        return loader_inst->enabled_known_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_CmdEndDebugUtilsLabelEXT
-                                                                     : NULL;
+        return loader_inst->enabled_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_CmdEndDebugUtilsLabelEXT : NULL;
     }
     if (!strcmp(pName, "vkCmdInsertDebugUtilsLabelEXT")) {
-        return loader_inst->enabled_known_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_CmdInsertDebugUtilsLabelEXT
-                                                                     : NULL;
+        return loader_inst->enabled_extensions.ext_debug_utils ? (PFN_vkVoidFunction)terminator_CmdInsertDebugUtilsLabelEXT : NULL;
     }
 
     if (loader_inst->instance_finished_creation) {
@@ -4328,14 +4700,14 @@
         return NULL;
     } else {
         disp = loader_get_instance_layer_dispatch(instance);
-        loader_platform_thread_lock_mutex(&loader_global_instance_list_lock);
+        loader_platform_thread_lock_mutex(&loader_lock);
         for (struct loader_instance *inst = loader.instances; inst; inst = inst->next) {
             if (&inst->disp->layer_inst_disp == disp) {
                 ptr_instance = inst;
                 break;
             }
         }
-        loader_platform_thread_unlock_mutex(&loader_global_instance_list_lock);
+        loader_platform_thread_unlock_mutex(&loader_lock);
     }
     return ptr_instance;
 }
@@ -4353,15 +4725,20 @@
 
 // Go through the search_list and find any layers which match type. If layer
 // type match is found in then add it to ext_list.
-VkResult loader_add_implicit_layers(const struct loader_instance *inst, const struct loader_envvar_all_filters *filters,
-                                    struct loader_pointer_layer_list *target_list,
+// If the layer name is in enabled_layers_env, do not add it to the list, that way it can be ordered alongside the other env-var
+// enabled layers
+VkResult loader_add_implicit_layers(const struct loader_instance *inst, const char *enabled_layers_env,
+                                    const struct loader_envvar_all_filters *filters, struct loader_pointer_layer_list *target_list,
                                     struct loader_pointer_layer_list *expanded_target_list,
                                     const struct loader_layer_list *source_list) {
     for (uint32_t src_layer = 0; src_layer < source_list->count; src_layer++) {
         struct loader_layer_properties *prop = &source_list->list[src_layer];
         if (0 == (prop->type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER)) {
-            VkResult result = loader_add_implicit_layer(inst, prop, filters, target_list, expanded_target_list, source_list);
-            if (result == VK_ERROR_OUT_OF_HOST_MEMORY) return result;
+            // If this layer appears in the enabled_layers_env, don't add it. We will let loader_add_environment_layers handle it
+            if (NULL == enabled_layers_env || NULL == strstr(enabled_layers_env, prop->info.layerName)) {
+                VkResult result = loader_add_implicit_layer(inst, prop, filters, target_list, expanded_target_list, source_list);
+                if (result == VK_ERROR_OUT_OF_HOST_MEMORY) return result;
+            }
         }
     }
     return VK_SUCCESS;
@@ -4387,6 +4764,7 @@
                                        const struct loader_layer_list *instance_layers,
                                        const struct loader_envvar_all_filters *layer_filters) {
     VkResult res = VK_SUCCESS;
+    char *enabled_layers_env = NULL;
 
     assert(inst && "Cannot have null instance");
 
@@ -4404,7 +4782,7 @@
         goto out;
     }
 
-    if (inst->settings.settings_active) {
+    if (inst->settings.settings_active && inst->settings.layer_configurations_active) {
         res = enable_correct_layers_from_settings(inst, layer_filters, pCreateInfo->enabledLayerCount,
                                                   pCreateInfo->ppEnabledLayerNames, &inst->instance_layer_list,
                                                   &inst->app_activated_layer_list, &inst->expanded_activated_layer_list);
@@ -4413,15 +4791,17 @@
         goto out;
     }
 
+    enabled_layers_env = loader_getenv(ENABLED_LAYERS_ENV, inst);
+
     // Add any implicit layers first
-    res = loader_add_implicit_layers(inst, layer_filters, &inst->app_activated_layer_list, &inst->expanded_activated_layer_list,
-                                     instance_layers);
+    res = loader_add_implicit_layers(inst, enabled_layers_env, layer_filters, &inst->app_activated_layer_list,
+                                     &inst->expanded_activated_layer_list, instance_layers);
     if (res != VK_SUCCESS) {
         goto out;
     }
 
     // Add any layers specified via environment variable next
-    res = loader_add_environment_layers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, layer_filters, &inst->app_activated_layer_list,
+    res = loader_add_environment_layers(inst, enabled_layers_env, layer_filters, &inst->app_activated_layer_list,
                                         &inst->expanded_activated_layer_list, instance_layers);
     if (res != VK_SUCCESS) {
         goto out;
@@ -4433,6 +4813,10 @@
 
     warn_if_layers_are_older_than_application(inst);
 out:
+    if (enabled_layers_env != NULL) {
+        loader_free_getenv(enabled_layers_env, inst);
+    }
+
     return res;
 }
 
@@ -4471,9 +4855,14 @@
 void setup_logical_device_enabled_layer_extensions(const struct loader_instance *inst, struct loader_device *dev,
                                                    const struct loader_extension_list *icd_exts,
                                                    const VkDeviceCreateInfo *pCreateInfo) {
+    // no enabled extensions, early exit
+    if (pCreateInfo->ppEnabledExtensionNames == NULL) {
+        return;
+    }
     // Can only setup debug marker as debug utils is an instance extensions.
     for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; ++i) {
-        if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
+        if (pCreateInfo->ppEnabledExtensionNames[i] &&
+            !strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
             // Check if its supported by the driver
             for (uint32_t j = 0; j < icd_exts->count; ++j) {
                 if (!strcmp(icd_exts->list[j].extensionName, VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
@@ -4782,6 +5171,11 @@
 
             chain_info.u.pLayerInfo = &layer_instance_link_info[num_activated_layers];
 
+            res = fixup_library_binary_path(inst, &(layer_prop->lib_name), layer_prop->lib_handle, cur_gipa);
+            if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
+                return res;
+            }
+
             activated_layers[num_activated_layers].name = layer_prop->info.layerName;
             activated_layers[num_activated_layers].manifest = layer_prop->manifest_file_name;
             activated_layers[num_activated_layers].library = layer_prop->lib_name;
@@ -5250,7 +5644,8 @@
                        ppEnabledLayerNames[i]);
             return VK_ERROR_LAYER_NOT_PRESENT;
         }
-        if (inst->settings.settings_active && prop->settings_control_value != LOADER_SETTINGS_LAYER_CONTROL_ON &&
+        if (inst->settings.settings_active && inst->settings.layer_configurations_active &&
+            prop->settings_control_value != LOADER_SETTINGS_LAYER_CONTROL_ON &&
             prop->settings_control_value != LOADER_SETTINGS_LAYER_CONTROL_DEFAULT) {
             loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
                        "loader_validate_layers: Layer %d was explicitly prevented from being enabled by the loader settings file",
@@ -5267,6 +5662,7 @@
                                              const VkInstanceCreateInfo *pCreateInfo) {
     VkExtensionProperties *extension_prop;
     char *env_value;
+    char *enabled_layers_env = NULL;
     bool check_if_known = true;
     VkResult res = VK_SUCCESS;
 
@@ -5288,7 +5684,7 @@
         goto out;
     }
 
-    if (inst->settings.settings_active) {
+    if (inst->settings.settings_active && inst->settings.layer_configurations_active) {
         res = enable_correct_layers_from_settings(inst, layer_filters, pCreateInfo->enabledLayerCount,
                                                   pCreateInfo->ppEnabledLayerNames, instance_layers, &active_layers,
                                                   &expanded_layers);
@@ -5296,14 +5692,17 @@
             goto out;
         }
     } else {
+        enabled_layers_env = loader_getenv(ENABLED_LAYERS_ENV, inst);
+
         // Build the lists of active layers (including meta layers) and expanded layers (with meta layers resolved to their
         // components)
-        res = loader_add_implicit_layers(inst, layer_filters, &active_layers, &expanded_layers, instance_layers);
+        res =
+            loader_add_implicit_layers(inst, enabled_layers_env, layer_filters, &active_layers, &expanded_layers, instance_layers);
         if (res != VK_SUCCESS) {
             goto out;
         }
-        res = loader_add_environment_layers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, layer_filters, &active_layers,
-                                            &expanded_layers, instance_layers);
+        res = loader_add_environment_layers(inst, enabled_layers_env, layer_filters, &active_layers, &expanded_layers,
+                                            instance_layers);
         if (res != VK_SUCCESS) {
             goto out;
         }
@@ -5389,13 +5788,24 @@
 out:
     loader_destroy_pointer_layer_list(inst, &active_layers);
     loader_destroy_pointer_layer_list(inst, &expanded_layers);
+    if (enabled_layers_env != NULL) {
+        loader_free_getenv(enabled_layers_env, inst);
+    }
+
     return res;
 }
 
 VkResult loader_validate_device_extensions(struct loader_instance *this_instance,
                                            const struct loader_pointer_layer_list *activated_device_layers,
                                            const struct loader_extension_list *icd_exts, const VkDeviceCreateInfo *pCreateInfo) {
+    // Early out to prevent nullptr dereference
+    if (pCreateInfo->enabledExtensionCount == 0 || pCreateInfo->ppEnabledExtensionNames == NULL) {
+        return VK_SUCCESS;
+    }
     for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+        if (pCreateInfo->ppEnabledExtensionNames[i] == NULL) {
+            continue;
+        }
         VkStringErrorFlags result = vk_string_validate(MaxLoaderStringLength, pCreateInfo->ppEnabledExtensionNames[i]);
         if (result != VK_STRING_ERROR_NONE) {
             loader_log(this_instance, VULKAN_LOADER_ERROR_BIT, 0,
@@ -5438,10 +5848,10 @@
 // All named terminator_<Vulkan API name>
 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
                                                          const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
-    struct loader_icd_term *icd_term;
-    VkExtensionProperties *prop;
+    struct loader_icd_term *icd_term = NULL;
+    VkExtensionProperties *prop = NULL;
     char **filtered_extension_names = NULL;
-    VkInstanceCreateInfo icd_create_info;
+    VkInstanceCreateInfo icd_create_info = {0};
     VkResult res = VK_SUCCESS;
     bool one_icd_successful = false;
 
@@ -5578,18 +5988,10 @@
         // Determine if vkGetPhysicalDeviceProperties2 is available to this Instance
         // Also determine if VK_EXT_surface_maintenance1 is available on the ICD
         if (icd_term->scanned_icd->api_version >= VK_API_VERSION_1_1) {
-            icd_term->supports_get_dev_prop_2 = true;
+            icd_term->enabled_instance_extensions.khr_get_physical_device_properties2 = true;
         }
-        for (uint32_t j = 0; j < icd_create_info.enabledExtensionCount; j++) {
-            if (!strcmp(filtered_extension_names[j], VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
-                icd_term->supports_get_dev_prop_2 = true;
-                continue;
-            }
-            if (!strcmp(filtered_extension_names[j], VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME)) {
-                icd_term->supports_ext_surface_maintenance_1 = true;
-                continue;
-            }
-        }
+        fill_out_enabled_instance_extensions(icd_create_info.enabledExtensionCount, (const char *const *)filtered_extension_names,
+                                             &icd_term->enabled_instance_extensions);
 
         loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&icd_exts);
 
@@ -5637,7 +6039,7 @@
         }
 
         // Create an instance, substituting the version to 1.0 if necessary
-        VkApplicationInfo icd_app_info;
+        VkApplicationInfo icd_app_info = {0};
         const uint32_t api_variant = 0;
         const uint32_t api_version_1_0 = VK_API_VERSION_1_0;
         uint32_t icd_version_nopatch =
@@ -5654,6 +6056,26 @@
             icd_app_info.apiVersion = icd_version;
             icd_create_info.pApplicationInfo = &icd_app_info;
         }
+
+        // If the settings file has device_configurations, we need to raise the ApiVersion drivers use to 1.1 if the driver
+        // supports 1.1 or higher. This allows 1.0 apps to use the device_configurations without the app having to set its own
+        // ApiVersion to 1.1 on its own.
+        if (ptr_instance->settings.settings_active && ptr_instance->settings.device_configurations_active &&
+            ptr_instance->settings.device_configuration_count > 0 && icd_version >= VK_API_VERSION_1_1 &&
+            requested_version < VK_API_VERSION_1_1) {
+            if (NULL != pCreateInfo->pApplicationInfo) {
+                memcpy(&icd_app_info, pCreateInfo->pApplicationInfo, sizeof(VkApplicationInfo));
+            }
+            icd_app_info.apiVersion = VK_API_VERSION_1_1;
+            icd_create_info.pApplicationInfo = &icd_app_info;
+
+            loader_log(
+                ptr_instance, VULKAN_LOADER_INFO_BIT, 0,
+                "terminator_CreateInstance: Raising the VkApplicationInfo::apiVersion from 1.0 to 1.1 on driver \"%s\" so that "
+                "the loader settings file is able to use this driver in the device_configuration selection logic.",
+                icd_term->scanned_icd->lib_name);
+        }
+
         icd_result =
             ptr_instance->icd_tramp_list.scanned_list[i].CreateInstance(&icd_create_info, pAllocator, &(icd_term->instance));
         if (VK_ERROR_OUT_OF_HOST_MEMORY == icd_result) {
@@ -5712,18 +6134,18 @@
 
     // For vkGetPhysicalDeviceProperties2, at least one ICD needs to support the extension for the
     // instance to have it
-    if (ptr_instance->supports_get_dev_prop_2) {
+    if (ptr_instance->enabled_extensions.khr_get_physical_device_properties2) {
         bool at_least_one_supports = false;
         icd_term = ptr_instance->icd_terms;
         while (icd_term != NULL) {
-            if (icd_term->supports_get_dev_prop_2) {
+            if (icd_term->enabled_instance_extensions.khr_get_physical_device_properties2) {
                 at_least_one_supports = true;
                 break;
             }
             icd_term = icd_term->next;
         }
         if (!at_least_one_supports) {
-            ptr_instance->supports_get_dev_prop_2 = false;
+            ptr_instance->enabled_extensions.khr_get_physical_device_properties2 = false;
         }
     }
 
@@ -5761,9 +6183,8 @@
         // This is why we don't clear inside of these function calls.
         // The clearing should actually be handled by the overall memset of the pInstance structure in the
         // trampoline.
-        wsi_create_instance(ptr_instance, pCreateInfo);
-        check_for_enabled_debug_extensions(ptr_instance, pCreateInfo);
-        extensions_create_instance(ptr_instance, pCreateInfo);
+        fill_out_enabled_instance_extensions(pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames,
+                                             &ptr_instance->enabled_extensions);
     }
 
     return res;
@@ -5777,7 +6198,6 @@
 
     // Remove this instance from the list of instances:
     struct loader_instance *prev = NULL;
-    loader_platform_thread_lock_mutex(&loader_global_instance_list_lock);
     struct loader_instance *next = loader.instances;
     while (next != NULL) {
         if (next == ptr_instance) {
@@ -5791,7 +6211,6 @@
         prev = next;
         next = next->next;
     }
-    loader_platform_thread_unlock_mutex(&loader_global_instance_list_lock);
 
     struct loader_icd_term *icd_terms = ptr_instance->icd_terms;
     while (NULL != icd_terms) {
@@ -5907,7 +6326,13 @@
     }
 
     for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+        if (pCreateInfo->ppEnabledExtensionNames == NULL) {
+            continue;
+        }
         const char *extension_name = pCreateInfo->ppEnabledExtensionNames[i];
+        if (extension_name == NULL) {
+            continue;
+        }
         VkExtensionProperties *prop = get_extension_property(extension_name, &icd_exts);
         if (prop) {
             filtered_extension_names[localCreateInfo.enabledExtensionCount] = (char *)extension_name;
@@ -5922,7 +6347,7 @@
     // Before we continue, If KHX_device_group is the list of enabled and viable extensions, then we then need to look for the
     // corresponding VkDeviceGroupDeviceCreateInfo struct in the device list and replace all the physical device values (which
     // are really loader physical device terminator values) with the ICD versions.
-    // if (icd_term->this_instance->enabled_known_extensions.khr_device_group_creation == 1) {
+    // if (icd_term->this_instance->enabled_extensions.khr_device_group_creation == 1) {
     {
         VkBaseOutStructure *pNext = (VkBaseOutStructure *)localCreateInfo.pNext;
         VkBaseOutStructure *pPrev = (VkBaseOutStructure *)&localCreateInfo;
@@ -5987,7 +6412,7 @@
                                    icd_term->scanned_icd->lib_name);
 
                         // Verify that VK_KHR_get_physical_device_properties2 is enabled
-                        if (icd_term->this_instance->enabled_known_extensions.khr_get_physical_device_properties2) {
+                        if (icd_term->this_instance->enabled_extensions.khr_get_physical_device_properties2) {
                             localCreateInfo.pEnabledFeatures = &features->features;
                         }
                     }
@@ -6080,8 +6505,8 @@
             dev->should_ignore_device_commands_from_newer_version = true;
         }
     }
-    dev->layer_extensions.ext_debug_utils_enabled = icd_term->this_instance->enabled_known_extensions.ext_debug_utils;
-    dev->driver_extensions.ext_debug_utils_enabled = icd_term->this_instance->enabled_known_extensions.ext_debug_utils;
+    dev->layer_extensions.ext_debug_utils_enabled = icd_term->this_instance->enabled_extensions.ext_debug_utils;
+    dev->driver_extensions.ext_debug_utils_enabled = icd_term->this_instance->enabled_extensions.ext_debug_utils;
 
     VkPhysicalDeviceProperties properties;
     icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &properties);
@@ -6762,28 +7187,225 @@
         goto out;
     }
 
-    uint32_t copy_count = inst->phys_dev_count_term;
-    if (NULL != pPhysicalDevices) {
-        if (copy_count > *pPhysicalDeviceCount) {
-            copy_count = *pPhysicalDeviceCount;
-            loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
-                       "terminator_EnumeratePhysicalDevices : Trimming device count from %d to %d.", inst->phys_dev_count_term,
-                       copy_count);
-            res = VK_INCOMPLETE;
+    if (inst->settings.settings_active && inst->settings.device_configurations_active) {
+        // Use settings file device_configurations if present
+        if (NULL == pPhysicalDevices) {
+            // take the minimum of the settings configurations count and number of terminators
+            *pPhysicalDeviceCount = (inst->settings.device_configuration_count < inst->phys_dev_count_term)
+                                        ? inst->settings.device_configuration_count
+                                        : inst->phys_dev_count_term;
+        } else {
+            res = loader_apply_settings_device_configurations(inst, pPhysicalDeviceCount, pPhysicalDevices);
+        }
+    } else {
+        // Otherwise just copy the physical devices up normally and pass it up the chain
+        uint32_t copy_count = inst->phys_dev_count_term;
+        if (NULL != pPhysicalDevices) {
+            if (copy_count > *pPhysicalDeviceCount) {
+                copy_count = *pPhysicalDeviceCount;
+                loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+                           "terminator_EnumeratePhysicalDevices : Trimming device count from %d to %d.", inst->phys_dev_count_term,
+                           copy_count);
+                res = VK_INCOMPLETE;
+            }
+
+            for (uint32_t i = 0; i < copy_count; i++) {
+                pPhysicalDevices[i] = (VkPhysicalDevice)inst->phys_devs_term[i];
+            }
         }
 
-        for (uint32_t i = 0; i < copy_count; i++) {
-            pPhysicalDevices[i] = (VkPhysicalDevice)inst->phys_devs_term[i];
-        }
+        *pPhysicalDeviceCount = copy_count;
     }
 
-    *pPhysicalDeviceCount = copy_count;
-
 out:
 
     return res;
 }
 
+VkResult check_physical_device_extensions_for_driver_properties_extension(struct loader_physical_device_term *phys_dev_term,
+                                                                          bool *supports_driver_properties) {
+    *supports_driver_properties = false;
+    uint32_t extension_count = 0;
+    VkResult res = phys_dev_term->this_icd_term->dispatch.EnumerateDeviceExtensionProperties(phys_dev_term->phys_dev, NULL,
+                                                                                             &extension_count, NULL);
+    if (res != VK_SUCCESS || extension_count == 0) {
+        return VK_SUCCESS;
+    }
+    VkExtensionProperties *extension_data = loader_stack_alloc(sizeof(VkExtensionProperties) * extension_count);
+    if (NULL == extension_data) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+
+    res = phys_dev_term->this_icd_term->dispatch.EnumerateDeviceExtensionProperties(phys_dev_term->phys_dev, NULL, &extension_count,
+                                                                                    extension_data);
+    if (res != VK_SUCCESS) {
+        return VK_SUCCESS;
+    }
+    for (uint32_t j = 0; j < extension_count; j++) {
+        if (!strcmp(extension_data[j].extensionName, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) {
+            *supports_driver_properties = true;
+            return VK_SUCCESS;
+        }
+    }
+    return VK_SUCCESS;
+}
+
+// Helper struct containing the relevant details of a VkPhysicalDevice necessary for applying the loader settings device
+// configurations.
+typedef struct physical_device_configuration_details {
+    bool pd_was_added;
+    bool pd_supports_vulkan_11;
+    bool pd_supports_driver_properties;
+    VkPhysicalDeviceProperties properties;
+    VkPhysicalDeviceIDProperties device_id_properties;
+    VkPhysicalDeviceDriverProperties driver_properties;
+
+} physical_device_configuration_details;
+
+// Apply the device_configurations in the settings file to the output VkPhysicalDeviceList.
+// That means looking up each VkPhysicalDevice's deviceUUID, filtering using that, and putting them in the order of
+// device_configurations in the settings file.
+VkResult loader_apply_settings_device_configurations(struct loader_instance *inst, uint32_t *pPhysicalDeviceCount,
+                                                     VkPhysicalDevice *pPhysicalDevices) {
+    loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+               "Reordering the output of vkEnumeratePhysicalDevices to match the loader settings device configurations list");
+
+    physical_device_configuration_details *pd_details =
+        loader_stack_alloc(inst->phys_dev_count_term * sizeof(physical_device_configuration_details));
+    if (NULL == pd_details) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+    memset(pd_details, 0, inst->phys_dev_count_term * sizeof(physical_device_configuration_details));
+
+    for (uint32_t i = 0; i < inst->phys_dev_count_term; i++) {
+        struct loader_physical_device_term *phys_dev_term = inst->phys_devs_term[i];
+
+        phys_dev_term->this_icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &pd_details[i].properties);
+        if (pd_details[i].properties.apiVersion < VK_API_VERSION_1_1) {
+            // Device isn't eligible for sorting
+            continue;
+        }
+        pd_details[i].pd_supports_vulkan_11 = true;
+        if (pd_details[i].properties.apiVersion >= VK_API_VERSION_1_2) {
+            pd_details[i].pd_supports_driver_properties = true;
+        }
+
+        // If this physical device isn't 1.2, then we need to check if it supports VK_KHR_driver_properties
+        if (!pd_details[i].pd_supports_driver_properties) {
+            VkResult res = check_physical_device_extensions_for_driver_properties_extension(
+                phys_dev_term, &pd_details[i].pd_supports_driver_properties);
+            if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
+                return res;
+            }
+        }
+
+        pd_details[i].device_id_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
+        pd_details[i].driver_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
+        if (pd_details[i].pd_supports_driver_properties) {
+            pd_details[i].device_id_properties.pNext = (void *)&pd_details[i].driver_properties;
+        }
+
+        VkPhysicalDeviceProperties2 props2 = {0};
+        props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+        props2.pNext = (void *)&pd_details[i].device_id_properties;
+        if (phys_dev_term->this_icd_term->dispatch.GetPhysicalDeviceProperties2) {
+            phys_dev_term->this_icd_term->dispatch.GetPhysicalDeviceProperties2(phys_dev_term->phys_dev, &props2);
+        }
+    }
+
+    // Loop over the setting's device configurations, find each VkPhysicalDevice which matches the deviceUUID given, add to the
+    // pPhysicalDevices output list.
+    uint32_t written_output_index = 0;
+
+    for (uint32_t i = 0; i < inst->settings.device_configuration_count; i++) {
+        uint8_t *current_deviceUUID = inst->settings.device_configurations[i].deviceUUID;
+        uint8_t *current_driverUUID = inst->settings.device_configurations[i].driverUUID;
+        bool configuration_found = false;
+        for (uint32_t j = 0; j < inst->phys_dev_count_term; j++) {
+            // Don't compare deviceUUID's if they have nothing, since we require deviceUUID's to effectively sort them.
+            if (!pd_details[j].pd_supports_vulkan_11) {
+                continue;
+            }
+            if (memcmp(current_deviceUUID, pd_details[j].device_id_properties.deviceUUID, sizeof(uint8_t) * VK_UUID_SIZE) == 0 &&
+                memcmp(current_driverUUID, pd_details[j].device_id_properties.driverUUID, sizeof(uint8_t) * VK_UUID_SIZE) == 0 &&
+                inst->settings.device_configurations[i].driverVersion == pd_details[j].properties.driverVersion) {
+                configuration_found = true;
+                // Catch when there are more device_configurations than space available in the output
+                if (written_output_index >= *pPhysicalDeviceCount) {
+                    *pPhysicalDeviceCount = written_output_index;  // write out how many were written
+                    return VK_INCOMPLETE;
+                }
+                if (pd_details[j].pd_supports_driver_properties) {
+                    loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
+                               "pPhysicalDevices array index %d is set to \"%s\" (%s, version %d) ", written_output_index,
+                               pd_details[j].properties.deviceName, pd_details[i].driver_properties.driverName,
+                               pd_details[i].properties.driverVersion);
+                } else {
+                    loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
+                               "pPhysicalDevices array index %d is set to \"%s\" (driver version %d) ", written_output_index,
+                               pd_details[j].properties.deviceName, pd_details[i].properties.driverVersion);
+                }
+                pPhysicalDevices[written_output_index++] = (VkPhysicalDevice)inst->phys_devs_term[j];
+                pd_details[j].pd_was_added = true;
+                break;
+            }
+        }
+        if (!configuration_found) {
+            char device_uuid_str[UUID_STR_LEN] = {0};
+            loader_log_generate_uuid_string(current_deviceUUID, device_uuid_str);
+            char driver_uuid_str[UUID_STR_LEN] = {0};
+            loader_log_generate_uuid_string(current_deviceUUID, driver_uuid_str);
+
+            // Log that this configuration was missing.
+            if (inst->settings.device_configurations[i].deviceName[0] != '\0' &&
+                inst->settings.device_configurations[i].driverName[0] != '\0') {
+                loader_log(
+                    inst, VULKAN_LOADER_WARN_BIT, 0,
+                    "loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
+                    "appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceName: \"%s\", "
+                    "deviceUUID: %s, driverName: %s, driverUUID: %s, driverVersion: %d",
+                    inst->settings.device_configurations[i].deviceName, device_uuid_str,
+                    inst->settings.device_configurations[i].driverName, driver_uuid_str,
+                    inst->settings.device_configurations[i].driverVersion);
+            } else if (inst->settings.device_configurations[i].deviceName[0] != '\0') {
+                loader_log(
+                    inst, VULKAN_LOADER_WARN_BIT, 0,
+                    "loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
+                    "appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceName: \"%s\", "
+                    "deviceUUID: %s, driverUUID: %s, driverVersion: %d",
+                    inst->settings.device_configurations[i].deviceName, device_uuid_str, driver_uuid_str,
+                    inst->settings.device_configurations[i].driverVersion);
+            } else {
+                loader_log(
+                    inst, VULKAN_LOADER_WARN_BIT, 0,
+                    "loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
+                    "appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceUUID: "
+                    "%s, driverUUID: %s, driverVersion: %d",
+                    device_uuid_str, driver_uuid_str, inst->settings.device_configurations[i].driverVersion);
+            }
+        }
+    }
+
+    for (uint32_t j = 0; j < inst->phys_dev_count_term; j++) {
+        if (!pd_details[j].pd_was_added) {
+            loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+                       "VkPhysicalDevice \"%s\" did not appear in the settings file device configurations list, so was not added "
+                       "to the pPhysicalDevices array",
+                       pd_details[j].properties.deviceName);
+        }
+    }
+
+    if (written_output_index == 0) {
+        loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
+                   "loader_apply_settings_device_configurations: None of the settings file device configurations had "
+                   "deviceUUID's that corresponded to enumerated VkPhysicalDevices. Returning VK_ERROR_INITIALIZATION_FAILED");
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+
+    *pPhysicalDeviceCount = written_output_index;  // update with how many were written
+    return VK_SUCCESS;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
                                                                              const char *pLayerName, uint32_t *pPropertyCount,
                                                                              VkExtensionProperties *pProperties) {
@@ -7169,7 +7791,7 @@
         cur_icd_group_count = 0;
 
         // Get the function pointer to use to call into the ICD. This could be the core or KHR version
-        if (inst->enabled_known_extensions.khr_device_group_creation) {
+        if (inst->enabled_extensions.khr_device_group_creation) {
             fpEnumeratePhysicalDeviceGroups = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHR;
         } else {
             fpEnumeratePhysicalDeviceGroups = icd_term->dispatch.EnumeratePhysicalDeviceGroups;
@@ -7241,7 +7863,7 @@
             uint32_t count_this_time = total_count - cur_icd_group_count;
 
             // Get the function pointer to use to call into the ICD. This could be the core or KHR version
-            if (inst->enabled_known_extensions.khr_device_group_creation) {
+            if (inst->enabled_extensions.khr_device_group_creation) {
                 fpEnumeratePhysicalDeviceGroups = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHR;
             } else {
                 fpEnumeratePhysicalDeviceGroups = icd_term->dispatch.EnumeratePhysicalDeviceGroups;
@@ -7534,3 +8156,133 @@
     }
     return res;
 }
+
+VkResult get_device_driver_id(VkPhysicalDevice physicalDevice, VkDriverId *driverId) {
+    VkPhysicalDeviceDriverProperties physical_device_driver_props = {0};
+    physical_device_driver_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
+
+    VkPhysicalDeviceProperties2 props2 = {0};
+    props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+    props2.pNext = &physical_device_driver_props;
+
+    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+    const struct loader_instance *inst = icd_term->this_instance;
+
+    assert(inst != NULL);
+
+    // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+    PFN_vkGetPhysicalDeviceProperties2 fpGetPhysicalDeviceProperties2 = NULL;
+    if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
+        fpGetPhysicalDeviceProperties2 = icd_term->dispatch.GetPhysicalDeviceProperties2;
+    }
+    if (fpGetPhysicalDeviceProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
+        fpGetPhysicalDeviceProperties2 = icd_term->dispatch.GetPhysicalDeviceProperties2KHR;
+    }
+
+    if (fpGetPhysicalDeviceProperties2 == NULL) {
+        *driverId = 0;
+        return VK_ERROR_UNKNOWN;
+    }
+
+    fpGetPhysicalDeviceProperties2(phys_dev_term->phys_dev, &props2);
+
+    *driverId = physical_device_driver_props.driverID;
+    return VK_SUCCESS;
+}
+
+VkResult loader_filter_enumerated_physical_device(const struct loader_instance *inst,
+                                                  const struct loader_envvar_id_filter *device_id_filter,
+                                                  const struct loader_envvar_id_filter *vendor_id_filter,
+                                                  const struct loader_envvar_id_filter *driver_id_filter,
+                                                  const uint32_t in_PhysicalDeviceCount,
+                                                  const VkPhysicalDevice *in_pPhysicalDevices, uint32_t *out_pPhysicalDeviceCount,
+                                                  VkPhysicalDevice *out_pPhysicalDevices) {
+    uint32_t filtered_physical_device_count = 0;
+    for (uint32_t i = 0; i < in_PhysicalDeviceCount; i++) {
+        VkPhysicalDeviceProperties dev_props = {0};
+        inst->disp->layer_inst_disp.GetPhysicalDeviceProperties(in_pPhysicalDevices[i], &dev_props);
+
+        if ((0 != device_id_filter->count) && !check_id_matches_filter_environment_var(dev_props.deviceID, device_id_filter)) {
+            continue;
+        }
+
+        if ((0 != vendor_id_filter->count) && !check_id_matches_filter_environment_var(dev_props.vendorID, vendor_id_filter)) {
+            continue;
+        }
+
+        if (0 != driver_id_filter->count) {
+            VkDriverId driver_id;
+            VkResult res = get_device_driver_id(in_pPhysicalDevices[i], &driver_id);
+
+            if ((res != VK_SUCCESS) || !check_id_matches_filter_environment_var(driver_id, driver_id_filter)) {
+                continue;
+            }
+        }
+
+        if ((NULL != out_pPhysicalDevices) && (filtered_physical_device_count < *out_pPhysicalDeviceCount)) {
+            out_pPhysicalDevices[filtered_physical_device_count] = in_pPhysicalDevices[i];
+        }
+        filtered_physical_device_count++;
+    }
+
+    if ((NULL == out_pPhysicalDevices) || (filtered_physical_device_count < *out_pPhysicalDeviceCount)) {
+        *out_pPhysicalDeviceCount = filtered_physical_device_count;
+    }
+
+    return (*out_pPhysicalDeviceCount < filtered_physical_device_count) ? VK_INCOMPLETE : VK_SUCCESS;
+}
+
+VkResult loader_filter_enumerated_physical_device_groups(
+    const struct loader_instance *inst, const struct loader_envvar_id_filter *device_id_filter,
+    const struct loader_envvar_id_filter *vendor_id_filter, const struct loader_envvar_id_filter *driver_id_filter,
+    const uint32_t in_PhysicalDeviceGroupCount, const VkPhysicalDeviceGroupProperties *in_pPhysicalDeviceGroupProperties,
+    uint32_t *out_PhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *out_pPhysicalDeviceGroupProperties) {
+    uint32_t filtered_physical_device_group_count = 0;
+    for (uint32_t i = 0; i < in_PhysicalDeviceGroupCount; i++) {
+        const VkPhysicalDeviceGroupProperties *device_group = &in_pPhysicalDeviceGroupProperties[i];
+
+        bool skip_group = false;
+        for (uint32_t j = 0; j < device_group->physicalDeviceCount; j++) {
+            VkPhysicalDeviceProperties dev_props = {0};
+            inst->disp->layer_inst_disp.GetPhysicalDeviceProperties(device_group->physicalDevices[j], &dev_props);
+
+            if ((0 != device_id_filter->count) && !check_id_matches_filter_environment_var(dev_props.deviceID, device_id_filter)) {
+                skip_group = true;
+                break;
+            }
+
+            if ((0 != vendor_id_filter->count) && !check_id_matches_filter_environment_var(dev_props.vendorID, vendor_id_filter)) {
+                skip_group = true;
+                break;
+            }
+
+            if (0 != driver_id_filter->count) {
+                VkDriverId driver_id;
+                VkResult res = get_device_driver_id(device_group->physicalDevices[j], &driver_id);
+
+                if ((res != VK_SUCCESS) || !check_id_matches_filter_environment_var(driver_id, driver_id_filter)) {
+                    skip_group = true;
+                    break;
+                }
+            }
+        }
+
+        if (skip_group) {
+            continue;
+        }
+
+        if ((NULL != out_pPhysicalDeviceGroupProperties) &&
+            (filtered_physical_device_group_count < *out_PhysicalDeviceGroupCount)) {
+            out_pPhysicalDeviceGroupProperties[filtered_physical_device_group_count] = *device_group;
+        }
+
+        filtered_physical_device_group_count++;
+    }
+
+    if ((NULL == out_pPhysicalDeviceGroupProperties) || (filtered_physical_device_group_count < *out_PhysicalDeviceGroupCount)) {
+        *out_PhysicalDeviceGroupCount = filtered_physical_device_group_count;
+    }
+
+    return (*out_PhysicalDeviceGroupCount < filtered_physical_device_group_count) ? VK_INCOMPLETE : VK_SUCCESS;
+}
diff --git a/loader/loader.h b/loader/loader.h
index 3a56f94..b5dd099 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -40,6 +40,9 @@
 LOADER_PLATFORM_THREAD_ONCE_EXTERN_DEFINITION(once_init)
 
 static inline VkPhysicalDevice loader_unwrap_physical_device(VkPhysicalDevice physicalDevice) {
+    if (VK_NULL_HANDLE == physicalDevice) {
+        return VK_NULL_HANDLE;
+    }
     struct loader_physical_device_tramp *phys_dev = (struct loader_physical_device_tramp *)physicalDevice;
     if (PHYS_TRAMP_MAGIC_NUMBER != phys_dev->magic) {
         return VK_NULL_HANDLE;
@@ -86,7 +89,6 @@
 extern struct loader_struct loader;
 extern loader_platform_thread_mutex loader_lock;
 extern loader_platform_thread_mutex loader_preload_icd_lock;
-extern loader_platform_thread_mutex loader_global_instance_list_lock;
 
 bool compare_vk_extension_properties(const VkExtensionProperties *op1, const VkExtensionProperties *op2);
 
@@ -114,14 +116,23 @@
 // Allocate a loader_string_list with enough space for allocated_count strings inside of it
 VkResult create_string_list(const struct loader_instance *inst, uint32_t allocated_count, struct loader_string_list *string_list);
 // Resize if there isn't enough space, then add the string str to the end of the loader_string_list
-// This function takes ownership of the str passed in - but only when it succeeds
+// This function takes ownership of the str passed in
 VkResult append_str_to_string_list(const struct loader_instance *inst, struct loader_string_list *string_list, char *str);
-// Resize if there isn't enough space, then copy the string str to a new string the end of the loader_string_list
+// Resize if there isn't enough space, then add the string str to the start of the loader_string_list
+// This function takes ownership of the str passed in
+VkResult prepend_str_to_string_list(const struct loader_instance *inst, struct loader_string_list *string_list, char *str);
+// Copy the string str to a new string and append it to string_list, resizing string_list if there isn't enough space.
 // This function does not take ownership of the string, it merely copies it.
-// This function appends a null terminator to the string automatically
+// This function automatically appends a null terminator to the string being copied
 // The str_len parameter does not include the null terminator
 VkResult copy_str_to_string_list(const struct loader_instance *inst, struct loader_string_list *string_list, const char *str,
                                  size_t str_len);
+// Copy the string str to a new string and prepend it to string_list, resizing string_list if there isn't enough space.
+// This function does not take ownership of the string, it merely copies it.
+// This function automatically appends a null terminator to the string being copied
+// The str_len parameter does not include the null terminator
+VkResult copy_str_to_start_of_string_list(const struct loader_instance *inst, struct loader_string_list *string_list,
+                                          const char *str, size_t str_len);
 
 // Free any string inside of loader_string_list and then free the list itself
 void free_string_list(const struct loader_instance *inst, struct loader_string_list *string_list);
@@ -158,7 +169,8 @@
 VkResult loader_init_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info, size_t element_size);
 void loader_destroy_generic_list(const struct loader_instance *inst, struct loader_generic_list *list);
 void loader_destroy_pointer_layer_list(const struct loader_instance *inst, struct loader_pointer_layer_list *layer_list);
-void loader_delete_layer_list_and_properties(const struct loader_instance *inst, struct loader_layer_list *layer_list);
+TEST_FUNCTION_EXPORT void loader_delete_layer_list_and_properties(const struct loader_instance *inst,
+                                                                  struct loader_layer_list *layer_list);
 void loader_remove_layer_in_list(const struct loader_instance *inst, struct loader_layer_list *layer_list,
                                  uint32_t layer_to_remove);
 VkResult loader_init_scanned_icd_list(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list);
@@ -215,9 +227,15 @@
                                             VkPhysicalDeviceGroupProperties *groups);
 void unload_drivers_without_physical_devices(struct loader_instance *inst);
 
+VkResult loader_apply_settings_device_configurations(struct loader_instance *inst, uint32_t *pPhysicalDeviceCount,
+                                                     VkPhysicalDevice *pPhysicalDevices);
+
 VkStringErrorFlags vk_string_validate(const int max_length, const char *char_array);
 
 char *loader_get_next_path(char *path);
+
+VkResult add_if_manifest_file(const struct loader_instance *inst, const char *file_name, struct loader_string_list *out_files);
+VkResult prepend_if_manifest_file(const struct loader_instance *inst, const char *file_name, struct loader_string_list *out_files);
 VkResult add_data_files(const struct loader_instance *inst, int dir_fd, char *search_path, struct loader_string_list *out_files,
                         bool use_first_found_manifest);
 
@@ -227,6 +245,20 @@
 // Helper macros for determining if a version is valid or not
 bool loader_check_version_meets_required(loader_api_version required, loader_api_version version);
 
+VkResult loader_filter_enumerated_physical_device(const struct loader_instance *inst,
+                                                  const struct loader_envvar_id_filter *device_id_filter,
+                                                  const struct loader_envvar_id_filter *vendor_id_filter,
+                                                  const struct loader_envvar_id_filter *driver_id_filter,
+                                                  const uint32_t in_PhysicalDeviceCount,
+                                                  const VkPhysicalDevice *in_pPhysicalDevices, uint32_t *out_pPhysicalDeviceCount,
+                                                  VkPhysicalDevice *out_pPhysicalDevices);
+
+VkResult loader_filter_enumerated_physical_device_groups(
+    const struct loader_instance *inst, const struct loader_envvar_id_filter *device_id_filter,
+    const struct loader_envvar_id_filter *vendor_id_filter, const struct loader_envvar_id_filter *driver_id_filter,
+    const uint32_t in_PhysicalDeviceGroupCount, const VkPhysicalDeviceGroupProperties *in_pPhysicalDeviceGroupProperties,
+    uint32_t *out_PhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *out_pPhysicalDeviceGroupProperties);
+
 // Convenience macros for common versions
 #if !defined(LOADER_VERSION_1_0_0)
 #define LOADER_VERSION_1_0_0 loader_combine_version(1, 0, 0)
diff --git a/loader/loader.rc b/loader/loader.rc
index 04b2839..c3a6edf 100644
--- a/loader/loader.rc
+++ b/loader/loader.rc
@@ -1,7 +1,7 @@
 //
-// Copyright (c) 2014-2024 The Khronos Group Inc.
-// Copyright (c) 2014-2024 Valve Corporation
-// Copyright (c) 2014-2024 LunarG, Inc.
+// Copyright (c) 2014-2026 The Khronos Group Inc.
+// Copyright (c) 2014-2026 Valve Corporation
+// Copyright (c) 2014-2026 LunarG, Inc.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -22,10 +22,10 @@
 #include "winres.h"
 
 // All set through CMake
-#define VER_FILE_VERSION 1, 4, 304, 0
-#define VER_FILE_DESCRIPTION_STR "1.4.304.Dev Build"
+#define VER_FILE_VERSION 1, 4, 350, 0
+#define VER_FILE_DESCRIPTION_STR "1.4.350.Dev Build"
 #define VER_FILE_VERSION_STR "Vulkan Loader - Dev Build"
-#define VER_COPYRIGHT_STR "Copyright (C) 2015-2024"
+#define VER_COPYRIGHT_STR "Copyright (C) 2015-2026"
 
 VS_VERSION_INFO VERSIONINFO
  FILEVERSION VER_FILE_VERSION
diff --git a/loader/loader_common.h b/loader/loader_common.h
index c879ca1..45baa79 100644
--- a/loader/loader_common.h
+++ b/loader/loader_common.h
@@ -276,8 +276,8 @@
     struct loader_icd_term *next;
 
     PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS];
-    bool supports_get_dev_prop_2;
-    bool supports_ext_surface_maintenance_1;
+
+    struct loader_instance_extension_enable_list enabled_instance_extensions;
 
     uint32_t physical_device_count;
 
@@ -360,7 +360,7 @@
     VkInstance instance;  // layers/ICD instance returned to trampoline
 
     struct loader_extension_list ext_list;  // icds and loaders extensions
-    struct loader_instance_extension_enables enabled_known_extensions;
+    struct loader_instance_extension_enable_list enabled_extensions;
 
     // Indicates which indices in the array are in-use and which are free to be reused
     struct loader_used_object_list surfaces_list;
@@ -379,52 +379,7 @@
     loader_settings settings;
 
     bool portability_enumeration_enabled;
-    bool portability_enumeration_flag_bit_set;
-    bool portability_enumeration_extension_enabled;
 
-    bool wsi_surface_enabled;
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    bool wsi_win32_surface_enabled;
-#endif
-#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
-    bool wsi_wayland_surface_enabled;
-#endif
-#if defined(VK_USE_PLATFORM_XCB_KHR)
-    bool wsi_xcb_surface_enabled;
-#endif
-#if defined(VK_USE_PLATFORM_XLIB_KHR)
-    bool wsi_xlib_surface_enabled;
-#endif
-#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
-    bool wsi_directfb_surface_enabled;
-#endif
-#if defined(VK_USE_PLATFORM_ANDROID_KHR)
-    bool wsi_android_surface_enabled;
-#endif
-#if defined(VK_USE_PLATFORM_MACOS_MVK)
-    bool wsi_macos_surface_enabled;
-#endif
-#if defined(VK_USE_PLATFORM_IOS_MVK)
-    bool wsi_ios_surface_enabled;
-#endif
-#if defined(VK_USE_PLATFORM_GGP)
-    bool wsi_ggp_surface_enabled;
-#endif
-    bool wsi_headless_surface_enabled;
-#if defined(VK_USE_PLATFORM_METAL_EXT)
-    bool wsi_metal_surface_enabled;
-#endif
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    bool wsi_imagepipe_surface_enabled;
-#endif
-#if defined(VK_USE_PLATFORM_SCREEN_QNX)
-    bool wsi_screen_surface_enabled;
-#endif
-#if defined(VK_USE_PLATFORM_VI_NN)
-    bool wsi_vi_surface_enabled;
-#endif
-    bool wsi_display_enabled;
-    bool wsi_display_props2_enabled;
     bool create_terminator_invalid_extension;
     bool supports_get_dev_prop_2;
 };
@@ -566,3 +521,13 @@
     struct loader_envvar_disable_layers_filter disable_filter;
     struct loader_envvar_filter allow_filter;
 };
+
+struct loader_envvar_id_filter_value {
+    uint32_t begin;
+    uint32_t end;
+};
+
+struct loader_envvar_id_filter {
+    uint32_t count;
+    struct loader_envvar_id_filter_value filters[MAX_ADDITIONAL_FILTERS];
+};
diff --git a/loader/loader_environment.c b/loader/loader_environment.c
index 4f9133e..8dd8493 100644
--- a/loader/loader_environment.c
+++ b/loader/loader_environment.c
@@ -38,7 +38,7 @@
 // Environment variables
 #if COMMON_UNIX_PLATFORMS
 
-bool is_high_integrity() { return geteuid() != getuid() || getegid() != getgid(); }
+bool is_high_integrity(void) { return geteuid() != getuid() || getegid() != getgid(); }
 
 char *loader_getenv(const char *name, const struct loader_instance *inst) {
     if (NULL == name) return NULL;
@@ -448,20 +448,20 @@
 
 // Get the layer name(s) from the env_name environment variable. If layer is found in
 // search_list then add it to layer_list.  But only add it to layer_list if type_flags matches.
-VkResult loader_add_environment_layers(struct loader_instance *inst, const enum layer_type_flags type_flags,
+VkResult loader_add_environment_layers(struct loader_instance *inst, const char *enabled_layers_env,
                                        const struct loader_envvar_all_filters *filters,
                                        struct loader_pointer_layer_list *target_list,
                                        struct loader_pointer_layer_list *expanded_target_list,
                                        const struct loader_layer_list *source_list) {
     VkResult res = VK_SUCCESS;
-    char *layer_env = loader_getenv(ENABLED_LAYERS_ENV, inst);
+    const enum layer_type_flags type_flags = VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER;
 
     // If the layer environment variable is present (i.e. VK_INSTANCE_LAYERS), we will always add it to the layer list.
-    if (layer_env != NULL) {
-        size_t layer_env_len = strlen(layer_env) + 1;
+    if (enabled_layers_env != NULL) {
+        size_t layer_env_len = strlen(enabled_layers_env) + 1;
         char *name = loader_stack_alloc(layer_env_len);
         if (name != NULL) {
-            loader_strncpy(name, layer_env_len, layer_env, layer_env_len);
+            loader_strncpy(name, layer_env_len, enabled_layers_env, layer_env_len);
 
             loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0, "env var \'%s\' defined and adding layers \"%s\"",
                        ENABLED_LAYERS_ENV, name);
@@ -560,9 +560,58 @@
 
 out:
 
-    if (layer_env != NULL) {
-        loader_free_getenv(layer_env, inst);
+    return res;
+}
+
+void parse_id_filter_environment_var(const struct loader_instance *inst, const char *env_var_name,
+                                     struct loader_envvar_id_filter *filter_struct) {
+    memset(filter_struct, 0, sizeof(struct loader_envvar_id_filter));
+    char *parsing_string = NULL;
+    char *env_var_value = loader_secure_getenv(env_var_name, inst);
+    if (NULL == env_var_value) {
+        return;
+    }
+    const size_t env_var_len = strlen(env_var_value);
+    if (env_var_len == 0) {
+        goto out;
+    }
+    // Allocate a separate string since scan_for_next_comma modifies the original string
+    parsing_string = loader_stack_alloc(env_var_len + 1);
+    for (uint32_t iii = 0; iii < env_var_len; ++iii) {
+        parsing_string[iii] = (char)tolower(env_var_value[iii]);
+    }
+    parsing_string[env_var_len] = '\0';
+
+    filter_struct->count = 0;
+    char *context = NULL;
+    char *token = thread_safe_strtok(parsing_string, ",", &context);
+    while (NULL != token) {
+        struct loader_envvar_id_filter_value *filter_value = &filter_struct->filters[filter_struct->count];
+
+        char *pEnd;
+        filter_value->begin = (uint32_t)strtoul(token, &pEnd, 0);
+
+        if (*pEnd != '\0') {
+            pEnd++;
+            filter_value->end = (uint32_t)strtoul(pEnd, NULL, 0);
+        } else {
+            filter_value->end = filter_value->begin;
+        }
+
+        filter_struct->count++;
+        token = thread_safe_strtok(NULL, ",", &context);
     }
 
-    return res;
+out:
+
+    loader_free_getenv(env_var_value, inst);
+}
+
+bool check_id_matches_filter_environment_var(const uint32_t id, const struct loader_envvar_id_filter *filter_struct) {
+    for (uint32_t i = 0; i < filter_struct->count; i++) {
+        if ((filter_struct->filters[i].begin <= id) && (id <= filter_struct->filters[i].end)) {
+            return true;
+        }
+    }
+    return false;
 }
diff --git a/loader/loader_environment.h b/loader/loader_environment.h
index 15474a3..ddbc29f 100644
--- a/loader/loader_environment.h
+++ b/loader/loader_environment.h
@@ -37,7 +37,7 @@
 
 #if defined(WIN32) || COMMON_UNIX_PLATFORMS
 
-bool is_high_integrity();
+bool is_high_integrity(void);
 
 char *loader_secure_getenv(const char *name, const struct loader_instance *inst);
 
@@ -49,8 +49,12 @@
                                                      struct loader_envvar_disable_layers_filter *disable_struct);
 VkResult parse_layer_environment_var_filters(const struct loader_instance *inst, struct loader_envvar_all_filters *layer_filters);
 bool check_name_matches_filter_environment_var(const char *name, const struct loader_envvar_filter *filter_struct);
-VkResult loader_add_environment_layers(struct loader_instance *inst, const enum layer_type_flags type_flags,
+VkResult loader_add_environment_layers(struct loader_instance *inst, const char *enabled_layers_env,
                                        const struct loader_envvar_all_filters *filters,
                                        struct loader_pointer_layer_list *target_list,
                                        struct loader_pointer_layer_list *expanded_target_list,
                                        const struct loader_layer_list *source_list);
+
+void parse_id_filter_environment_var(const struct loader_instance *inst, const char *env_var_name,
+                                     struct loader_envvar_id_filter *filter_struct);
+bool check_id_matches_filter_environment_var(const uint32_t id, const struct loader_envvar_id_filter *filter_struct);
diff --git a/loader/loader_json.c b/loader/loader_json.c
index 42d18b4..0bb6060 100644
--- a/loader/loader_json.c
+++ b/loader/loader_json.c
@@ -147,7 +147,7 @@
 }
 #endif
 
-VkResult loader_get_json(const struct loader_instance *inst, int dir_fd, const char *filename, cJSON **json) {
+TEST_FUNCTION_EXPORT VkResult loader_get_json(const struct loader_instance *inst, int dir_fd, const char *filename, cJSON **json) {
     char *json_buf = NULL;
     VkResult res = VK_SUCCESS;
 
diff --git a/loader/loader_json.h b/loader/loader_json.h
index 42971d7..d25b852 100644
--- a/loader/loader_json.h
+++ b/loader/loader_json.h
@@ -38,7 +38,7 @@
 //
 // @return -  A pointer to a cJSON object representing the JSON parse tree.
 //            This returned buffer should be freed by caller.
-VkResult loader_get_json(const struct loader_instance *inst, int dir_fd, const char *filename, cJSON **json);
+TEST_FUNCTION_EXPORT VkResult loader_get_json(const struct loader_instance *inst, int dir_fd, const char *filename, cJSON **json);
 
 // Given a cJSON object, find the string associated with the key and puts an pre-allocated string into out_string.
 // Length is given by out_str_len, and this function truncates the string with a null terminator if it the provided space isn't
diff --git a/loader/loader_windows.c b/loader/loader_windows.c
index f73659c..310a905 100644
--- a/loader/loader_windows.c
+++ b/loader/loader_windows.c
@@ -102,7 +102,6 @@
             // Only initialize necessary sync primitives
             loader_platform_thread_create_mutex(&loader_lock);
             loader_platform_thread_create_mutex(&loader_preload_icd_lock);
-            loader_platform_thread_create_mutex(&loader_global_instance_list_lock);
             init_global_loader_settings();
             break;
         case DLL_PROCESS_DETACH:
@@ -788,7 +787,7 @@
     }
 
     // Now, parse the paths and add any manifest files found in them.
-    vk_result = add_data_files(inst, search_path, out_files, false);
+    vk_result = add_data_files(inst, search_path, out_files);
 
 out:
 
@@ -817,12 +816,13 @@
 
     // Get the actual physical devices
     do {
-        next_icd_phys_devs->physical_devices = loader_instance_heap_realloc(
-            inst, next_icd_phys_devs->physical_devices, next_icd_phys_devs->device_count * sizeof(VkPhysicalDevice),
-            count * sizeof(VkPhysicalDevice), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
-        if (next_icd_phys_devs->physical_devices == NULL) {
+        void *new_ptr = loader_instance_heap_realloc(inst, next_icd_phys_devs->physical_devices,
+                                                     next_icd_phys_devs->device_count * sizeof(VkPhysicalDevice),
+                                                     count * sizeof(VkPhysicalDevice), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+        if (new_ptr == NULL) {
             return VK_ERROR_OUT_OF_HOST_MEMORY;
         }
+        next_icd_phys_devs->physical_devices = new_ptr;
         next_icd_phys_devs->device_count = count;
     } while ((res = icd_term->scanned_icd->EnumerateAdapterPhysicalDevices(icd_term->instance, luid, &count,
                                                                            next_icd_phys_devs->physical_devices)) == VK_INCOMPLETE);
@@ -978,13 +978,14 @@
 
             if (icd_phys_devs_array_size <= *icd_phys_devs_array_count) {
                 uint32_t old_size = icd_phys_devs_array_size * sizeof(struct loader_icd_physical_devices);
-                *icd_phys_devs_array = loader_instance_heap_realloc(inst, *icd_phys_devs_array, old_size, 2 * old_size,
-                                                                    VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+                void *new_ptr = loader_instance_heap_realloc(inst, *icd_phys_devs_array, old_size, 2 * old_size,
+                                                             VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
                 if (*icd_phys_devs_array == NULL) {
                     adapter->lpVtbl->Release(adapter);
                     res = VK_ERROR_OUT_OF_HOST_MEMORY;
                     goto out;
                 }
+                *icd_phys_devs_array = new_ptr;
                 icd_phys_devs_array_size *= 2;
             }
             (*icd_phys_devs_array)[*icd_phys_devs_array_count].device_count = 0;
@@ -1112,7 +1113,7 @@
 
     UINT32 numPackages = 0, bufferLength = 0;
     // This literal string identifies the Microsoft-published OpenCL, OpenGL, and Vulkan Compatibility Pack, which contains
-    // OpenGLOn12, OpenCLOn12, and VulkanOn12 (aka Dozen) mappinglayers
+    // OpenGLOn12, OpenCLOn12, and VulkanOn12 (aka Dozen) mapping layers
     PCWSTR familyName = L"Microsoft.D3DMappingLayers_8wekyb3d8bbwe";
     if (ERROR_INSUFFICIENT_BUFFER != fpGetPackagesByPackageFamily(familyName, &numPackages, NULL, &bufferLength, NULL) ||
         numPackages == 0 || bufferLength == 0) {
diff --git a/loader/log.c b/loader/log.c
index 2501c63..78589a4 100644
--- a/loader/log.c
+++ b/loader/log.c
@@ -88,55 +88,47 @@
 
 void loader_set_global_debug_level(uint32_t new_loader_debug) { g_loader_debug = new_loader_debug; }
 
-void generate_debug_flag_str(VkFlags msg_type, size_t cmd_line_size, char *cmd_line_msg, size_t *num_used) {
+void generate_debug_flag_str(VkFlags msg_type, size_t cmd_line_size, char *cmd_line_msg) {
     cmd_line_msg[0] = '\0';
 
-// Helper macro which strncat's the given string literal, then updates num_used & cmd_line_end
-// Assumes that we haven't used the entire buffer - must manually check this when adding new filter types
-// We concat at the end of cmd_line_msg, so that strncat isn't a victim of Schlemiel the Painter
-// We write to the end - 1 of cmd_line_msg, as the end is actually a null terminator
-#define STRNCAT_TO_BUFFER(string_literal_to_cat)                                                                               \
-    loader_strncat(cmd_line_msg + *num_used, cmd_line_size - *num_used, string_literal_to_cat, sizeof(string_literal_to_cat)); \
-    *num_used += sizeof(string_literal_to_cat) - 1;  // subtract one to remove the null terminator in the string literal
-
     if ((msg_type & VULKAN_LOADER_ERROR_BIT) != 0) {
-        STRNCAT_TO_BUFFER("ERROR");
+        loader_strncat(cmd_line_msg, cmd_line_size, "ERROR", sizeof("ERROR"));
     }
     if ((msg_type & VULKAN_LOADER_WARN_BIT) != 0) {
-        if (*num_used > 1) {
-            STRNCAT_TO_BUFFER(" | ");
+        if (strlen(cmd_line_msg) > 0) {
+            loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
         }
-        STRNCAT_TO_BUFFER("WARNING");
+        loader_strncat(cmd_line_msg, cmd_line_size, "WARNING", sizeof("WARNING"));
     }
     if ((msg_type & VULKAN_LOADER_INFO_BIT) != 0) {
-        if (*num_used > 1) {
-            STRNCAT_TO_BUFFER(" | ");
+        if (strlen(cmd_line_msg) > 0) {
+            loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
         }
-        STRNCAT_TO_BUFFER("INFO");
+        loader_strncat(cmd_line_msg, cmd_line_size, "INFO", sizeof("INFO"));
     }
     if ((msg_type & VULKAN_LOADER_DEBUG_BIT) != 0) {
-        if (*num_used > 1) {
-            STRNCAT_TO_BUFFER(" | ");
+        if (strlen(cmd_line_msg) > 0) {
+            loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
         }
-        STRNCAT_TO_BUFFER("DEBUG");
+        loader_strncat(cmd_line_msg, cmd_line_size, "DEBUG", sizeof("DEBUG"));
     }
     if ((msg_type & VULKAN_LOADER_PERF_BIT) != 0) {
-        if (*num_used > 1) {
-            STRNCAT_TO_BUFFER(" | ");
+        if (strlen(cmd_line_msg) > 0) {
+            loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
         }
-        STRNCAT_TO_BUFFER("PERF");
+        loader_strncat(cmd_line_msg, cmd_line_size, "PERF", sizeof("PERF"));
     }
     if ((msg_type & VULKAN_LOADER_DRIVER_BIT) != 0) {
-        if (*num_used > 1) {
-            STRNCAT_TO_BUFFER(" | ");
+        if (strlen(cmd_line_msg) > 0) {
+            loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
         }
-        STRNCAT_TO_BUFFER("DRIVER");
+        loader_strncat(cmd_line_msg, cmd_line_size, "DRIVER", sizeof("DRIVER"));
     }
     if ((msg_type & VULKAN_LOADER_LAYER_BIT) != 0) {
-        if (*num_used > 1) {
-            STRNCAT_TO_BUFFER(" | ");
+        if (strlen(cmd_line_msg) > 0) {
+            loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
         }
-        STRNCAT_TO_BUFFER("LAYER");
+        loader_strncat(cmd_line_msg, cmd_line_size, "LAYER", sizeof("LAYER"));
     }
 
 #undef STRNCAT_TO_BUFFER
@@ -219,22 +211,51 @@
 
     // Only need enough space to create the filter description header for log messages
     // Also use the same header for all output
-    char cmd_line_msg[64];
+    char cmd_line_msg[64] = {0};
     size_t cmd_line_size = sizeof(cmd_line_msg);
-    size_t num_used = 0;
 
-    generate_debug_flag_str(msg_type, cmd_line_size, cmd_line_msg, &num_used);
+    loader_strncat(cmd_line_msg, cmd_line_size, "[Vulkan Loader] ", sizeof("[Vulkan Loader] "));
 
-    // Appends a : to the end of the debug flags used
-    loader_strncat(cmd_line_msg + num_used, cmd_line_size - num_used, ": ", sizeof(": "));
-    num_used += sizeof(": ") - 1;
+    bool need_separator = false;
+    if ((msg_type & VULKAN_LOADER_ERROR_BIT) != 0) {
+        loader_strncat(cmd_line_msg, cmd_line_size, "ERROR", sizeof("ERROR"));
+        need_separator = true;
+    } else if ((msg_type & VULKAN_LOADER_WARN_BIT) != 0) {
+        loader_strncat(cmd_line_msg, cmd_line_size, "WARNING", sizeof("WARNING"));
+        need_separator = true;
+    } else if ((msg_type & VULKAN_LOADER_INFO_BIT) != 0) {
+        loader_strncat(cmd_line_msg, cmd_line_size, "INFO", sizeof("INFO"));
+        need_separator = true;
+    } else if ((msg_type & VULKAN_LOADER_DEBUG_BIT) != 0) {
+        loader_strncat(cmd_line_msg, cmd_line_size, "DEBUG", sizeof("DEBUG"));
+        need_separator = true;
+    }
 
-    // Justifies the output to at least 19 spaces
-    if (num_used < 19) {
-        const char space_buffer[] = "                   ";
-        // Only write (19 - num_used) spaces
-        loader_strncat(cmd_line_msg + num_used, cmd_line_size - num_used, space_buffer, sizeof(space_buffer) - 1 - num_used);
-        num_used += sizeof(space_buffer) - 1 - num_used;
+    if ((msg_type & VULKAN_LOADER_PERF_BIT) != 0) {
+        if (need_separator) {
+            loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
+        }
+        loader_strncat(cmd_line_msg, cmd_line_size, "PERF", sizeof("PERF"));
+    } else if ((msg_type & VULKAN_LOADER_DRIVER_BIT) != 0) {
+        if (need_separator) {
+            loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
+        }
+        loader_strncat(cmd_line_msg, cmd_line_size, "DRIVER", sizeof("DRIVER"));
+    } else if ((msg_type & VULKAN_LOADER_LAYER_BIT) != 0) {
+        if (need_separator) {
+            loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
+        }
+        loader_strncat(cmd_line_msg, cmd_line_size, "LAYER", sizeof("LAYER"));
+    }
+
+    loader_strncat(cmd_line_msg, cmd_line_size, ": ", sizeof(": "));
+    size_t num_used = strlen(cmd_line_msg);
+
+    // Justifies the output to at least 29 spaces
+    if (num_used < 32) {
+        const char space_buffer[] = "                                ";
+        // Only write (32 - num_used) spaces
+        loader_strncat(cmd_line_msg, cmd_line_size, space_buffer, sizeof(space_buffer) - 1 - num_used);
     }
     // Assert that we didn't write more than what is available in cmd_line_msg
     assert(cmd_line_size > num_used);
@@ -253,3 +274,10 @@
                                            const char *func_name) {
     loader_log(inst, msg_type, msg_code, "Function %s not supported for this physical device", func_name);
 }
+
+void loader_log_generate_uuid_string(const uint8_t uuid[16], char output[UUID_STR_LEN]) {
+    assert(uuid && output);
+    snprintf(output, UUID_STR_LEN, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", uuid[0], uuid[1],
+             uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13],
+             uuid[14], uuid[15]);
+}
diff --git a/loader/log.h b/loader/log.h
index cb544f4..22cb251 100644
--- a/loader/log.h
+++ b/loader/log.h
@@ -58,9 +58,8 @@
 // Sets the global debug level - used by global settings files
 void loader_set_global_debug_level(uint32_t new_loader_debug);
 
-// Writes a stringified version of enum vulkan_loader_debug_flags into cmd_line_msg, and writes the number of characters written in
-// num_used
-void generate_debug_flag_str(VkFlags msg_type, size_t cmd_line_size, char *cmd_line_msg, size_t *num_used);
+// Writes a stringified version of enum vulkan_loader_debug_flags into a char array cmd_line_msg of length cmd_line_size
+void generate_debug_flag_str(VkFlags msg_type, size_t cmd_line_size, char *cmd_line_msg);
 
 // The asm declaration prevents name mangling which is necessary for macOS
 #if defined(MODIFY_UNKNOWN_FUNCTION_DECLS)
@@ -89,6 +88,10 @@
 
 #undef ASM_NAME
 
+#define UUID_STR_LEN 37  // always 32 digits, 4 dashes, and 1 null terminator
+
+void loader_log_generate_uuid_string(const uint8_t uuid[16], char output[UUID_STR_LEN]);
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
diff --git a/loader/settings.c b/loader/settings.c
index 53cfad5..7160ff7 100644
--- a/loader/settings.c
+++ b/loader/settings.c
@@ -44,13 +44,35 @@
     memset(layer_configuration, 0, sizeof(loader_settings_layer_configuration));
 }
 
+void free_driver_configuration(const struct loader_instance* inst, loader_settings_driver_configuration* driver_configuration) {
+    loader_instance_heap_free(inst, driver_configuration->path);
+    memset(driver_configuration, 0, sizeof(loader_settings_driver_configuration));
+}
+
+void free_device_configuration(const struct loader_instance* inst, loader_settings_device_configuration* device_configuration) {
+    (void)inst;
+    memset(device_configuration, 0, sizeof(loader_settings_device_configuration));
+}
+
 void free_loader_settings(const struct loader_instance* inst, loader_settings* settings) {
     if (NULL != settings->layer_configurations) {
         for (uint32_t i = 0; i < settings->layer_configuration_count; i++) {
             free_layer_configuration(inst, &settings->layer_configurations[i]);
         }
+        loader_instance_heap_free(inst, settings->layer_configurations);
     }
-    loader_instance_heap_free(inst, settings->layer_configurations);
+    if (NULL != settings->additional_drivers) {
+        for (uint32_t i = 0; i < settings->additional_driver_count; i++) {
+            free_driver_configuration(inst, &settings->additional_drivers[i]);
+        }
+        loader_instance_heap_free(inst, settings->additional_drivers);
+    }
+    if (NULL != settings->device_configurations) {
+        for (uint32_t i = 0; i < settings->device_configuration_count; i++) {
+            free_device_configuration(inst, &settings->device_configurations[i]);
+        }
+        loader_instance_heap_free(inst, settings->device_configurations);
+    }
     loader_instance_heap_free(inst, settings->settings_file_path);
     memset(settings, 0, sizeof(loader_settings));
 }
@@ -161,12 +183,14 @@
     VkResult res = VK_SUCCESS;
 
     cJSON* layer_configurations = loader_cJSON_GetObjectItem(settings_object, "layers");
+    // If the layers object isn't present, return early with success to allow the settings file to still apply
     if (NULL == layer_configurations) {
-        return VK_ERROR_INITIALIZATION_FAILED;
+        return VK_SUCCESS;
     }
 
     uint32_t layer_configurations_count = loader_cJSON_GetArraySize(layer_configurations);
     if (layer_configurations_count == 0) {
+        loader_settings->layer_configurations_active = true;
         return VK_SUCCESS;
     }
 
@@ -191,6 +215,7 @@
             goto out;
         }
     }
+    loader_settings->layer_configurations_active = true;
 out:
     if (res != VK_SUCCESS) {
         if (loader_settings->layer_configurations) {
@@ -206,44 +231,354 @@
     return res;
 }
 
-VkResult check_if_settings_path_exists(const struct loader_instance* inst, char* base, char* suffix, char** settings_file_path) {
-    if (NULL == base || NULL == suffix) {
-        return VK_ERROR_INITIALIZATION_FAILED;
+VkResult parse_additional_driver(const struct loader_instance* inst, cJSON* additional_driver_json,
+                                 loader_settings_driver_configuration* additional_driver) {
+    VkResult res = VK_SUCCESS;
+    res = loader_parse_json_string(additional_driver_json, "path", &(additional_driver->path));
+    if (res != VK_SUCCESS) {
+        goto out;
     }
-    size_t base_len = strlen(base);
-    size_t suffix_len = strlen(suffix);
-    size_t path_len = base_len + suffix_len + 1;
-    *settings_file_path = loader_instance_heap_calloc(inst, path_len, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
-    if (NULL == *settings_file_path) {
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+out:
+    if (res != VK_SUCCESS) {
+        free_driver_configuration(inst, additional_driver);
     }
-    loader_strncpy(*settings_file_path, path_len, base, base_len);
-    loader_strncat(*settings_file_path, path_len, suffix, suffix_len);
+    return res;
+}
 
-    if (!loader_platform_file_exists(*settings_file_path)) {
-        loader_instance_heap_free(inst, *settings_file_path);
-        *settings_file_path = NULL;
+VkResult parse_additional_drivers(const struct loader_instance* inst, cJSON* settings_object, loader_settings* loader_settings) {
+    VkResult res = VK_SUCCESS;
+
+    cJSON* additional_drivers_use_exclusively_json =
+        loader_cJSON_GetObjectItem(settings_object, "additional_drivers_use_exclusively");
+    if (additional_drivers_use_exclusively_json && additional_drivers_use_exclusively_json->type == cJSON_True) {
+        loader_settings->additional_drivers_use_exclusively = true;
+    }
+
+    cJSON* additional_drivers_json = loader_cJSON_GetObjectItem(settings_object, "additional_drivers");
+    if (NULL == additional_drivers_json) {
+        return VK_SUCCESS;
+    }
+
+    uint32_t additional_driver_count = loader_cJSON_GetArraySize(additional_drivers_json);
+    if (additional_driver_count == 0) {
+        return VK_SUCCESS;
+    }
+
+    loader_settings->additional_driver_count = additional_driver_count;
+
+    loader_settings->additional_drivers = loader_instance_heap_calloc(
+        inst, sizeof(loader_settings_layer_configuration) * additional_driver_count, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    if (NULL == loader_settings->additional_drivers) {
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
+    }
+
+    cJSON* driver = NULL;
+    size_t i = 0;
+    cJSON_ArrayForEach(driver, additional_drivers_json) {
+        if (driver->type != cJSON_Object) {
+            res = VK_ERROR_INITIALIZATION_FAILED;
+            goto out;
+        }
+        res = parse_additional_driver(inst, driver, &(loader_settings->additional_drivers[i++]));
+        if (VK_SUCCESS != res) {
+            goto out;
+        }
+    }
+out:
+    if (res != VK_SUCCESS) {
+        if (loader_settings->additional_drivers) {
+            for (size_t index = 0; index < loader_settings->additional_driver_count; index++) {
+                free_driver_configuration(inst, &(loader_settings->additional_drivers[index]));
+            }
+            loader_settings->additional_driver_count = 0;
+            loader_instance_heap_free(inst, loader_settings->additional_drivers);
+            loader_settings->additional_drivers = NULL;
+        }
+    }
+    return res;
+}
+
+VkResult parse_uuid_array(cJSON* device_configuration_json, const char* uuid_name, uint8_t uuid[16]) {
+    cJSON* uuid_array = loader_cJSON_GetObjectItem(device_configuration_json, uuid_name);
+    if (NULL == uuid_array) {
         return VK_ERROR_INITIALIZATION_FAILED;
     }
+
+    if (uuid_array->type != cJSON_Array) {
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+    if (VK_UUID_SIZE != loader_cJSON_GetArraySize(uuid_array)) {
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+
+    cJSON* uuid_field = NULL;
+    size_t i = 0;
+    cJSON_ArrayForEach(uuid_field, uuid_array) {
+        if (i >= VK_UUID_SIZE) {
+            break;
+        }
+        if (uuid_field->type != cJSON_Number) {
+            return VK_ERROR_INITIALIZATION_FAILED;
+        }
+        if (uuid_field->valueint < 0 || uuid_field->valueint > 255) {
+            return VK_ERROR_INITIALIZATION_FAILED;
+        }
+
+        uuid[i] = (uint8_t)uuid_field->valueint;
+        i++;
+    }
     return VK_SUCCESS;
 }
+
+VkResult parse_device_configuration(const struct loader_instance* inst, cJSON* device_configuration_json,
+                                    loader_settings_device_configuration* device_configuration) {
+    (void)inst;
+    VkResult res = VK_SUCCESS;
+
+    res = parse_uuid_array(device_configuration_json, "deviceUUID", device_configuration->deviceUUID);
+    if (VK_SUCCESS != res) {
+        goto out;
+    }
+
+    res = parse_uuid_array(device_configuration_json, "driverUUID", device_configuration->driverUUID);
+    if (VK_SUCCESS != res) {
+        goto out;
+    }
+
+    cJSON* driverVersion_json = loader_cJSON_GetObjectItem(device_configuration_json, "driverVersion");
+    if (NULL == driverVersion_json || driverVersion_json->type != cJSON_Number) {
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+    device_configuration->driverVersion = driverVersion_json->valueint;
+
+    VkResult deviceNameRes = loader_parse_json_string_to_existing_str(
+        device_configuration_json, "deviceName", VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, device_configuration->deviceName);
+    if (VK_ERROR_OUT_OF_HOST_MEMORY == deviceNameRes) {
+        res = deviceNameRes;
+        goto out;
+    }
+
+    VkResult driverNameRes = loader_parse_json_string_to_existing_str(
+        device_configuration_json, "driverName", VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, device_configuration->driverName);
+    if (VK_ERROR_OUT_OF_HOST_MEMORY == driverNameRes) {
+        res = driverNameRes;
+        goto out;
+    }
+out:
+    if (res != VK_SUCCESS) {
+        memset(device_configuration, 0, sizeof(loader_settings_device_configuration));
+    }
+    return res;
+}
+
+VkResult parse_device_configurations(const struct loader_instance* inst, cJSON* settings_object, loader_settings* loader_settings) {
+    VkResult res = VK_SUCCESS;
+
+    cJSON* device_configurations = loader_cJSON_GetObjectItem(settings_object, "device_configurations");
+    if (NULL == device_configurations) {
+        return VK_SUCCESS;
+    }
+
+    uint32_t device_configuration_count = loader_cJSON_GetArraySize(device_configurations);
+    if (device_configuration_count == 0) {
+        loader_settings->device_configurations_active = true;
+        return VK_SUCCESS;
+    }
+
+    loader_settings->device_configuration_count = device_configuration_count;
+
+    loader_settings->device_configurations = loader_instance_heap_calloc(
+        inst, sizeof(loader_settings_device_configuration) * device_configuration_count, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    if (NULL == loader_settings->device_configurations) {
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
+    }
+
+    cJSON* device = NULL;
+    size_t i = 0;
+    cJSON_ArrayForEach(device, device_configurations) {
+        if (device->type != cJSON_Object) {
+            res = VK_ERROR_INITIALIZATION_FAILED;
+            goto out;
+        }
+        res = parse_device_configuration(inst, device, &(loader_settings->device_configurations[i]));
+        if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
+            goto out;
+        } else if (res != VK_SUCCESS) {
+            continue;
+        }
+        i++;
+    }
+    loader_settings->device_configurations_active = true;
+out:
+    if (res != VK_SUCCESS) {
+        if (loader_settings->device_configurations) {
+            for (size_t index = 0; index < loader_settings->device_configuration_count; index++) {
+                free_device_configuration(inst, &(loader_settings->device_configurations[index]));
+            }
+            loader_settings->device_configuration_count = 0;
+            loader_instance_heap_free(inst, loader_settings->device_configurations);
+            loader_settings->device_configurations = NULL;
+        }
+    }
+    return res;
+}
+
+#if COMMON_UNIX_PLATFORMS
+// Given a base and suffix path, determine if a file at that location exists, and if it is return success.
+// Since base may contain multiple paths separated by PATH_SEPARATOR, we must extract each segment and check segment + suffix
+// individually
+VkResult check_if_settings_path_exists(const struct loader_instance* inst, const char* base, const char* suffix,
+                                       char** settings_file_path) {
+    if (NULL == base || NULL == suffix) {
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+
+    size_t base_len = strlen(base);
+    size_t suffix_len = strlen(suffix);
+
+    uint32_t start = 0;
+    uint32_t stop = 0;
+    while (base[start] != '\0' && start < base_len && stop < base_len) {
+        start = stop;
+        stop = start + 1;
+        while (base[stop] != PATH_SEPARATOR && base[stop] != '\0' && stop < base_len) {
+            stop++;
+        }
+
+        size_t segment_len = (stop - start);
+        if (segment_len <= 1) {
+            // segment is *just* a PATH_SEPARATOR, skip it
+            continue;
+        }
+        size_t path_len = segment_len + suffix_len + 1;
+        *settings_file_path = loader_instance_heap_calloc(inst, path_len, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+        if (NULL == *settings_file_path) {
+            return VK_ERROR_OUT_OF_HOST_MEMORY;
+        }
+        loader_strncpy(*settings_file_path, path_len, base + start, segment_len);
+        loader_strncat(*settings_file_path, path_len, suffix, suffix_len);
+
+        if (loader_platform_file_exists(*settings_file_path)) {
+            return VK_SUCCESS;
+        }
+        loader_instance_heap_free(inst, *settings_file_path);
+        *settings_file_path = NULL;
+    }
+
+    return VK_ERROR_INITIALIZATION_FAILED;
+}
+
+// Follow the logic of read_data_files_in_search_paths but only look for "/vulkan/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME
 VkResult get_unix_settings_path(const struct loader_instance* inst, char** settings_file_path) {
-    VkResult res =
-        check_if_settings_path_exists(inst, loader_secure_getenv("HOME", inst),
-                                      "/.local/share/vulkan/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path);
+    // First, get XDG env-vars we use. Don't need to worry about free'ing because on linux getenv is non-allocating
+    char* xdg_config_home = loader_secure_getenv("XDG_CONFIG_HOME", inst);
+    char* xdg_config_dirs = loader_secure_getenv("XDG_CONFIG_DIRS", inst);
+    char* xdg_data_home = loader_secure_getenv("XDG_DATA_HOME", inst);
+    char* xdg_data_dirs = loader_secure_getenv("XDG_DATA_DIRS", inst);
+
+    // Use fallback directories for xdg_config_dirs and xdg_data_dirs if they are NULL.
+#if !defined(__Fuchsia__) && !defined(__QNX__)
+    if (NULL == xdg_config_dirs || '\0' == xdg_config_dirs[0]) {
+        xdg_config_dirs = FALLBACK_CONFIG_DIRS;
+    }
+#endif
+
+#if !defined(__Fuchsia__) && !defined(__QNX__)
+    if (NULL == xdg_data_dirs || '\0' == xdg_data_dirs[0]) {
+        xdg_data_dirs = FALLBACK_DATA_DIRS;
+    }
+#endif
+
+    VkResult res = check_if_settings_path_exists(
+        inst, xdg_config_home, "/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path);
     if (res == VK_SUCCESS) {
         return res;
     }
-    // If HOME isn't set, fallback to XDG_DATA_HOME
-    res = check_if_settings_path_exists(inst, loader_secure_getenv("XDG_DATA_HOME", inst),
-                                        "/vulkan/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path);
+
+    res = check_if_settings_path_exists(inst, xdg_data_home, "/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME,
+                                        settings_file_path);
     if (res == VK_SUCCESS) {
         return res;
     }
-    // if XDG_DATA_HOME isn't set, fallback to /etc.
-    // note that the settings_fil_path_suffix stays the same since its the same layout as for XDG_DATA_HOME
-    return check_if_settings_path_exists(inst, "/etc", "/vulkan/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME,
-                                         settings_file_path);
+
+    // Check home if either xdg_config_home or xdg_data_home wasn't set
+    char* home = loader_secure_getenv("HOME", inst);
+    if (home != NULL) {
+        if (NULL == xdg_config_home || '\0' == xdg_config_home[0]) {
+            res = check_if_settings_path_exists(
+                inst, home, "/.config/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path);
+            if (res == VK_SUCCESS) {
+                return res;
+            }
+        }
+        if (NULL == xdg_data_home || '\0' == xdg_data_home[0]) {
+            res = check_if_settings_path_exists(
+                inst, home, "/.local/share/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path);
+            if (res == VK_SUCCESS) {
+                return res;
+            }
+        }
+    }
+
+    res = check_if_settings_path_exists(inst, xdg_config_dirs, "/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME,
+                                        settings_file_path);
+    if (res == VK_SUCCESS) {
+        return res;
+    }
+
+    res = check_if_settings_path_exists(inst, SYSCONFDIR, "/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME,
+                                        settings_file_path);
+    if (res == VK_SUCCESS) {
+        return res;
+    }
+#if defined(EXTRASYSCONFDIR)
+
+    res = check_if_settings_path_exists(inst, EXTRASYSCONFDIR, "/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME,
+                                        settings_file_path);
+    if (res == VK_SUCCESS) {
+        return res;
+    }
+#endif
+    res = check_if_settings_path_exists(inst, xdg_data_dirs, "/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME,
+                                        settings_file_path);
+    if (res == VK_SUCCESS) {
+        return res;
+    }
+
+    return VK_ERROR_INITIALIZATION_FAILED;
+}
+#endif
+
+bool check_if_layer_configurations_are_equal(loader_settings_layer_configuration* a, loader_settings_layer_configuration* b) {
+    if (!a->name || !b->name || 0 != strcmp(a->name, b->name)) {
+        return false;
+    }
+    if (!a->path || !b->path || 0 != strcmp(a->path, b->path)) {
+        return false;
+    }
+    return a->control == b->control && a->treat_as_implicit_manifest == b->treat_as_implicit_manifest;
+}
+
+bool check_if_driver_configurations_are_equal(loader_settings_driver_configuration* a, loader_settings_driver_configuration* b) {
+    if (!a->path || !b->path || 0 != strcmp(a->path, b->path)) {
+        return false;
+    }
+    return true;
+}
+
+bool check_if_device_configurations_are_equal(loader_settings_device_configuration* a, loader_settings_device_configuration* b) {
+    for (uint32_t i = 0; i < VK_UUID_SIZE; i++) {
+        if (a->deviceUUID[i] != b->deviceUUID[i]) return false;
+    }
+    for (uint32_t i = 0; i < VK_UUID_SIZE; i++) {
+        if (a->driverUUID[i] != b->driverUUID[i]) return false;
+    }
+    if (a->driverVersion != b->driverVersion) return false;
+    if (0 != strcmp(a->deviceName, b->deviceName)) return false;
+    if (0 != strcmp(a->driverName, b->driverName)) return false;
+    return true;
 }
 
 bool check_if_settings_are_equal(loader_settings* a, loader_settings* b) {
@@ -253,20 +588,21 @@
     are_equal &= a->settings_active == b->settings_active;
     are_equal &= a->has_unordered_layer_location == b->has_unordered_layer_location;
     are_equal &= a->debug_level == b->debug_level;
+    are_equal &= a->layer_configurations_active == b->layer_configurations_active;
     are_equal &= a->layer_configuration_count == b->layer_configuration_count;
+    are_equal &= a->additional_drivers_use_exclusively == b->additional_drivers_use_exclusively;
+    are_equal &= a->additional_driver_count == b->additional_driver_count;
+    are_equal &= a->device_configurations_active == b->device_configurations_active;
+    are_equal &= a->device_configuration_count == b->device_configuration_count;
     if (!are_equal) return false;
     for (uint32_t i = 0; i < a->layer_configuration_count && i < b->layer_configuration_count; i++) {
-        if (a->layer_configurations[i].name && b->layer_configurations[i].name) {
-            are_equal &= 0 == strcmp(a->layer_configurations[i].name, b->layer_configurations[i].name);
-        } else {
-            are_equal = false;
-        }
-        if (a->layer_configurations[i].path && b->layer_configurations[i].path) {
-            are_equal &= 0 == strcmp(a->layer_configurations[i].path, b->layer_configurations[i].path);
-        } else {
-            are_equal = false;
-        }
-        are_equal &= a->layer_configurations[i].control == b->layer_configurations[i].control;
+        are_equal &= check_if_layer_configurations_are_equal(&a->layer_configurations[i], &b->layer_configurations[i]);
+    }
+    for (uint32_t i = 0; i < a->additional_driver_count && i < b->additional_driver_count; i++) {
+        are_equal &= check_if_driver_configurations_are_equal(&a->additional_drivers[i], &b->additional_drivers[i]);
+    }
+    for (uint32_t i = 0; i < a->device_configuration_count && i < b->device_configuration_count; i++) {
+        are_equal &= check_if_device_configurations_are_equal(&a->device_configurations[i], &b->device_configurations[i]);
     }
     return are_equal;
 }
@@ -278,28 +614,59 @@
     loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "Using layer configurations found in loader settings from %s",
                settings->settings_file_path);
 
-    char cmd_line_msg[64];
+    char cmd_line_msg[64] = {0};
     size_t cmd_line_size = sizeof(cmd_line_msg);
-    size_t num_used = 0;
 
     cmd_line_msg[0] = '\0';
 
-    generate_debug_flag_str(settings->debug_level, cmd_line_size, cmd_line_msg, &num_used);
-    if (num_used > 0) {
+    generate_debug_flag_str(settings->debug_level, cmd_line_size, cmd_line_msg);
+    if (strlen(cmd_line_msg)) {
         loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Loader Settings Filters for Logging to Standard Error: %s", cmd_line_msg);
     }
-
-    loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Layer Configurations count = %d", settings->layer_configuration_count);
-    for (uint32_t i = 0; i < settings->layer_configuration_count; i++) {
-        loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "---- Layer Configuration [%d] ----", i);
-        if (settings->layer_configurations[i].control != LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION) {
-            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Name: %s", settings->layer_configurations[i].name);
-            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Path: %s", settings->layer_configurations[i].path);
-            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Layer Type: %s",
-                       settings->layer_configurations[i].treat_as_implicit_manifest ? "Implicit" : "Explicit");
+    if (settings->layer_configurations_active) {
+        loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Layer Configurations count = %d", settings->layer_configuration_count);
+        for (uint32_t i = 0; i < settings->layer_configuration_count; i++) {
+            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "---- Layer Configuration [%d] ----", i);
+            if (settings->layer_configurations[i].control != LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION) {
+                loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Name: %s", settings->layer_configurations[i].name);
+                loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Path: %s", settings->layer_configurations[i].path);
+                loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Layer Type: %s",
+                           settings->layer_configurations[i].treat_as_implicit_manifest ? "Implicit" : "Explicit");
+            }
+            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Control: %s",
+                       loader_settings_layer_control_to_string(settings->layer_configurations[i].control));
         }
-        loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Control: %s",
-                   loader_settings_layer_control_to_string(settings->layer_configurations[i].control));
+    }
+    if (settings->additional_driver_count > 0) {
+        loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "----");
+        loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Use Additional Drivers Exclusively = %s",
+                   settings->additional_drivers_use_exclusively ? "true" : "false");
+        loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Additional Driver Configurations count = %d",
+                   settings->additional_driver_count);
+        for (uint32_t i = 0; i < settings->additional_driver_count; i++) {
+            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "---- Driver Configuration [%d] ----", i);
+            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Path: %s", settings->additional_drivers[i].path);
+        }
+    }
+    if (settings->device_configurations_active) {
+        loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "----");
+        loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Device Configurations count = %d", settings->device_configuration_count);
+        for (uint32_t i = 0; i < settings->device_configuration_count; i++) {
+            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "---- Device Configuration [%d] ----", i);
+            char device_uuid_str[UUID_STR_LEN] = {0};
+            loader_log_generate_uuid_string(settings->device_configurations[i].deviceUUID, device_uuid_str);
+            char driver_uuid_str[UUID_STR_LEN] = {0};
+            loader_log_generate_uuid_string(settings->device_configurations[i].driverUUID, driver_uuid_str);
+            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "deviceUUID: %s", device_uuid_str);
+            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "driverUUID: %s", driver_uuid_str);
+            loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "driverVersion: %d", settings->device_configurations[i].driverVersion);
+            if ('\0' != settings->device_configurations[i].deviceName[0]) {
+                loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "deviceName: %s", settings->device_configurations[i].deviceName);
+            }
+            if ('\0' != settings->device_configurations[i].driverName[0]) {
+                loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "driverName: %s", settings->device_configurations[i].driverName);
+            }
+        }
     }
     loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "---------------------------------");
 }
@@ -358,7 +725,7 @@
         memcpy(&settings_iter_parent, settings_array, sizeof(cJSON));
     } else if (NULL != single_settings_object) {
         settings_iter_parent.child = single_settings_object;
-    } else if (settings_array == NULL && single_settings_object) {
+    } else {
         loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
                    "Loader settings file from %s missing required settings objects: Either one of the \"settings\" or "
                    "\"settings_array\" objects must be present - no loader settings will be active",
@@ -427,8 +794,10 @@
     cJSON* stderr_filter = loader_cJSON_GetObjectItem(settings_to_use, "stderr_log");
     if (NULL != stderr_filter) {
         struct loader_string_list stderr_log = {0};
-        res = loader_parse_json_array_of_strings(inst, settings_to_use, "stderr_log", &stderr_log);
-        if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
+        VkResult stderr_log_result = VK_SUCCESS;
+        stderr_log_result = loader_parse_json_array_of_strings(inst, settings_to_use, "stderr_log", &stderr_log);
+        if (VK_ERROR_OUT_OF_HOST_MEMORY == stderr_log_result) {
+            res = VK_ERROR_OUT_OF_HOST_MEMORY;
             goto out;
         }
         loader_settings->debug_level = parse_log_filters_from_strings(&stderr_log);
@@ -442,22 +811,23 @@
         cJSON_ArrayForEach(log_element, logs_to_use) {
             // bool is_valid = true;
             struct loader_string_list log_destinations = {0};
-            res = loader_parse_json_array_of_strings(inst, log_element, "destinations", &log_destinations);
-            if (res != VK_SUCCESS) {
+            VkResult parse_dest_res = loader_parse_json_array_of_strings(inst, log_element, "destinations", &log_destinations);
+            if (parse_dest_res != VK_SUCCESS) {
                 // is_valid = false;
             }
             free_string_list(inst, &log_destinations);
             struct loader_string_list log_filters = {0};
-            res = loader_parse_json_array_of_strings(inst, log_element, "filters", &log_filters);
-            if (res != VK_SUCCESS) {
+            VkResult parse_filters_res = loader_parse_json_array_of_strings(inst, log_element, "filters", &log_filters);
+            if (parse_filters_res != VK_SUCCESS) {
                 // is_valid = false;
             }
             free_string_list(inst, &log_filters);
         }
     }
 
-    res = parse_layer_configurations(inst, settings_to_use, loader_settings);
-    if (res != VK_SUCCESS) {
+    VkResult layer_configurations_res = parse_layer_configurations(inst, settings_to_use, loader_settings);
+    if (VK_ERROR_OUT_OF_HOST_MEMORY == layer_configurations_res) {
+        res = layer_configurations_res;
         goto out;
     }
 
@@ -470,9 +840,29 @@
         }
     }
 
-    loader_settings->settings_file_path = settings_file_path;
-    settings_file_path = NULL;
-    loader_settings->settings_active = true;
+    VkResult additional_drivers_res = parse_additional_drivers(inst, settings_to_use, loader_settings);
+    if (VK_ERROR_OUT_OF_HOST_MEMORY == additional_drivers_res) {
+        res = additional_drivers_res;
+        goto out;
+    }
+
+    VkResult device_configurations_res = parse_device_configurations(inst, settings_to_use, loader_settings);
+    if (VK_ERROR_OUT_OF_HOST_MEMORY == device_configurations_res) {
+        res = device_configurations_res;
+        goto out;
+    }
+
+    // Only consider the settings active if there is at least one "setting" active.
+    // Those are either logging, layers, additional_drivers, or device_configurations.
+    if (loader_settings->debug_level != 0 || loader_settings->layer_configurations_active ||
+        loader_settings->additional_driver_count != 0 || loader_settings->device_configurations_active) {
+        loader_settings->settings_file_path = settings_file_path;
+        settings_file_path = NULL;
+        loader_settings->settings_active = true;
+    } else {
+        loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+                   "vk_loader_settings.json file found at \"%s\" but did not contain any valid settings.", settings_file_path);
+    }
 out:
     if (NULL != json) {
         loader_cJSON_Delete(json);
@@ -484,17 +874,16 @@
     return res;
 }
 
-VkResult update_global_loader_settings(void) {
+TEST_FUNCTION_EXPORT VkResult update_global_loader_settings(void) {
     loader_settings settings = {0};
     VkResult res = get_loader_settings(NULL, &settings);
     loader_platform_thread_lock_mutex(&global_loader_settings_lock);
 
-    free_loader_settings(NULL, &global_loader_settings);
     if (res == VK_SUCCESS) {
         if (!check_if_settings_are_equal(&settings, &global_loader_settings)) {
             log_settings(NULL, &settings);
         }
-
+        free_loader_settings(NULL, &global_loader_settings);
         memcpy(&global_loader_settings, &settings, sizeof(loader_settings));
         if (global_loader_settings.settings_active && global_loader_settings.debug_level > 0) {
             loader_set_global_debug_level(global_loader_settings.debug_level);
@@ -538,14 +927,14 @@
     }
 }
 
-VkResult get_settings_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
-                             bool* should_search_for_other_layers) {
+TEST_FUNCTION_EXPORT VkResult get_settings_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
+                                                  bool* should_search_for_other_layers) {
     VkResult res = VK_SUCCESS;
     *should_search_for_other_layers = true;  // default to true
 
     const loader_settings* settings = get_current_settings_and_lock(inst);
 
-    if (NULL == settings || !settings->settings_active) {
+    if (NULL == settings || !settings->settings_active || !settings->layer_configurations_active) {
         goto out;
     }
 
@@ -602,7 +991,7 @@
         }
 
         // Makes it possible to know if a new layer was added or not, since the only return value is VkResult
-        size_t count_before_adding = settings_layers->count;
+        uint32_t count_before_adding = settings_layers->count;
 
         local_res =
             loader_add_layer_properties(inst, settings_layers, json, layer_config->treat_as_implicit_manifest, layer_config->path);
@@ -617,28 +1006,33 @@
             continue;
         }
 
-        struct loader_layer_properties* newly_added_layer = &settings_layers->list[settings_layers->count - 1];
-        newly_added_layer->settings_control_value = layer_config->control;
-        // If the manifest file found has a name that differs from the one in the settings, remove this layer from
-        // consideration
-        bool should_remove = false;
-        if (strncmp(newly_added_layer->info.layerName, layer_config->name, VK_MAX_EXTENSION_NAME_SIZE) != 0) {
-            should_remove = true;
-            loader_remove_layer_in_list(inst, settings_layers, settings_layers->count - 1);
-        }
-        // Make sure the layer isn't already in the list
-        for (uint32_t j = 0; settings_layers->count > 0 && j < settings_layers->count - 1; j++) {
-            if (0 ==
-                strncmp(settings_layers->list[j].info.layerName, newly_added_layer->info.layerName, VK_MAX_EXTENSION_NAME_SIZE)) {
-                if (0 == (newly_added_layer->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER) &&
-                    strcmp(settings_layers->list[j].lib_name, newly_added_layer->lib_name) == 0) {
-                    should_remove = true;
-                    break;
+        for (uint32_t j = count_before_adding; j < settings_layers->count; j++) {
+            struct loader_layer_properties* newly_added_layer = &settings_layers->list[j];
+            newly_added_layer->settings_control_value = layer_config->control;
+            // If the manifest file found has a name that differs from the one in the settings, remove this layer from
+            // consideration
+            if (strncmp(newly_added_layer->info.layerName, layer_config->name, VK_MAX_EXTENSION_NAME_SIZE) != 0) {
+                loader_remove_layer_in_list(inst, settings_layers, j);
+                j--;
+                continue;
+            }
+            bool should_remove = false;
+            // Make sure the layer isn't already in the list
+            for (uint32_t k = 0; k < j; k++) {
+                if (0 == strncmp(settings_layers->list[k].info.layerName, newly_added_layer->info.layerName,
+                                 VK_MAX_EXTENSION_NAME_SIZE)) {
+                    if (0 == (newly_added_layer->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER) &&
+                        settings_layers->list[k].lib_name != NULL && newly_added_layer->lib_name != NULL &&
+                        strcmp(settings_layers->list[k].lib_name, newly_added_layer->lib_name) == 0) {
+                        should_remove = true;
+                        break;
+                    }
                 }
             }
-        }
-        if (should_remove) {
-            loader_remove_layer_in_list(inst, settings_layers, settings_layers->count - 1);
+            if (should_remove) {
+                loader_remove_layer_in_list(inst, settings_layers, j);
+                j--;
+            }
         }
     }
 
@@ -653,7 +1047,10 @@
 // Skip comparing to UNORDERED_LAYER_LOCATION
 // If layer_property is a regular layer, check if the lib_path is the same.
 // Make sure that the lib_name pointers are non-null before calling strcmp.
-bool check_if_layer_is_in_list(struct loader_layer_list* layer_list, struct loader_layer_properties* layer_property) {
+// consider_lib_path - true if comparison should include the library_path in distinguishing layers. Used to prevent duplicates
+// between settings file provided layers and default found layers
+bool check_if_layer_is_in_list(struct loader_layer_list* layer_list, struct loader_layer_properties* layer_property,
+                               bool consider_lib_path) {
     // If the layer is a meta layer, just check against the name
     for (uint32_t i = 0; i < layer_list->count; i++) {
         if (0 == strncmp(layer_list->list[i].info.layerName, layer_property->info.layerName, VK_MAX_EXTENSION_NAME_SIZE)) {
@@ -663,6 +1060,9 @@
             if (VK_LAYER_TYPE_FLAG_META_LAYER == (layer_property->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
                 return true;
             }
+            if (!consider_lib_path) {
+                return true;
+            }
             if (layer_list->list[i].lib_name && layer_property->lib_name) {
                 return strcmp(layer_list->list[i].lib_name, layer_property->lib_name) == 0;
             }
@@ -711,7 +1111,7 @@
 
     // Insert the settings layers into output_layers up to unordered_layer_index
     for (uint32_t i = 0; i < unordered_layer_location_index; i++) {
-        if (!check_if_layer_is_in_list(output_layers, &settings_layers->list[i])) {
+        if (!check_if_layer_is_in_list(output_layers, &settings_layers->list[i], true)) {
             res = loader_append_layer_property(inst, output_layers, &settings_layers->list[i]);
             if (VK_SUCCESS != res) {
                 goto out;
@@ -721,8 +1121,8 @@
 
     for (uint32_t i = 0; i < regular_layers->count; i++) {
         // Check if its already been put in the output_layers list as well as the remaining settings_layers
-        bool regular_layer_is_ordered = check_if_layer_is_in_list(output_layers, &regular_layers->list[i]) ||
-                                        check_if_layer_is_in_list(settings_layers, &regular_layers->list[i]);
+        bool regular_layer_is_ordered = check_if_layer_is_in_list(output_layers, &regular_layers->list[i], false) ||
+                                        check_if_layer_is_in_list(settings_layers, &regular_layers->list[i], false);
         // If it isn't found, add it
         if (!regular_layer_is_ordered) {
             res = loader_append_layer_property(inst, output_layers, &regular_layers->list[i]);
@@ -738,9 +1138,11 @@
     // Insert the rest of the settings layers into combined_layers from  unordered_layer_index to the end
     // start at one after the unordered_layer_index
     for (uint32_t i = unordered_layer_location_index + 1; i < settings_layers->count; i++) {
-        res = loader_append_layer_property(inst, output_layers, &settings_layers->list[i]);
-        if (VK_SUCCESS != res) {
-            goto out;
+        if (!check_if_layer_is_in_list(output_layers, &settings_layers->list[i], true)) {
+            res = loader_append_layer_property(inst, output_layers, &settings_layers->list[i]);
+            if (VK_SUCCESS != res) {
+                goto out;
+            }
         }
     }
 
@@ -865,3 +1267,39 @@
 out:
     return res;
 }
+
+VkResult loader_settings_get_additional_driver_files(const struct loader_instance* inst, struct loader_string_list* out_files) {
+    VkResult res = VK_SUCCESS;
+
+    const loader_settings* settings = get_current_settings_and_lock(inst);
+
+    if (NULL == settings || !settings->settings_active) {
+        goto out;
+    }
+
+    if (settings->additional_drivers_use_exclusively) {
+        free_string_list(inst, out_files);
+    }
+
+    for (uint32_t i = 0; i < settings->additional_driver_count; i++) {
+        res = prepend_if_manifest_file(inst, settings->additional_drivers[i].path, out_files);
+    }
+
+out:
+    release_current_settings_lock(inst);
+    return res;
+}
+
+bool loader_settings_should_use_driver_environment_variables(const struct loader_instance* inst) {
+    bool should_use = true;
+    const loader_settings* settings = get_current_settings_and_lock(inst);
+    if (NULL == settings || !settings->settings_active) {
+        goto out;
+    }
+    if (settings->device_configurations_active) {
+        should_use = false;
+    }
+out:
+    release_current_settings_lock(inst);
+    return should_use;
+}
diff --git a/loader/settings.h b/loader/settings.h
index 0383bb5..a46feff 100644
--- a/loader/settings.h
+++ b/loader/settings.h
@@ -30,9 +30,11 @@
 #include "vulkan/vulkan_core.h"
 
 #include "log.h"
+#include "vk_loader_platform.h"
 
 struct loader_instance;
 struct loader_layer_list;
+struct loader_string_list;
 struct loader_pointer_layer_list;
 struct loader_envvar_all_filters;
 typedef struct log_configuration log_configuration;
@@ -60,14 +62,35 @@
 
 } loader_settings_layer_configuration;
 
+typedef struct loader_settings_driver_configuration {
+    char* path;
+} loader_settings_driver_configuration;
+
+typedef struct loader_settings_device_configuration {
+    uint8_t deviceUUID[VK_UUID_SIZE];
+    uint8_t driverUUID[VK_UUID_SIZE];
+    uint32_t driverVersion;
+    char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
+    char driverName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
+} loader_settings_device_configuration;
+
 typedef struct loader_settings {
     bool settings_active;
     bool has_unordered_layer_location;
     enum vulkan_loader_debug_flags debug_level;
 
+    bool layer_configurations_active;
     uint32_t layer_configuration_count;
     loader_settings_layer_configuration* layer_configurations;
 
+    bool additional_drivers_use_exclusively;
+    uint32_t additional_driver_count;
+    loader_settings_driver_configuration* additional_drivers;
+
+    bool device_configurations_active;
+    uint32_t device_configuration_count;
+    loader_settings_device_configuration* device_configurations;
+
     char* settings_file_path;
 } loader_settings;
 
@@ -83,7 +106,7 @@
 void log_settings(const struct loader_instance* inst, loader_settings* settings);
 
 // Every global function needs to call this at startup to insure that
-VkResult update_global_loader_settings(void);
+TEST_FUNCTION_EXPORT VkResult update_global_loader_settings(void);
 
 // Needs to be called during startup -
 void init_global_loader_settings(void);
@@ -94,8 +117,8 @@
 
 // Query the current settings (either global or per-instance) and return the list of layers contained within.
 // should_search_for_other_layers tells the caller if the settings file should be used exclusively for layer searching or not
-VkResult get_settings_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
-                             bool* should_search_for_other_layers);
+TEST_FUNCTION_EXPORT VkResult get_settings_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
+                                                  bool* should_search_for_other_layers);
 
 // Take the provided list of settings_layers and add in the layers from regular search paths
 // Only adds layers that aren't already present in the settings_layers and in the location of the
@@ -111,3 +134,11 @@
                                              const struct loader_layer_list* instance_layers,
                                              struct loader_pointer_layer_list* target_layer_list,
                                              struct loader_pointer_layer_list* activated_layer_list);
+
+// Add any drivers that the loader settings file contains to the out_files list. If the additional_drivers_use_exclusively field is
+// true, clear the out_files list before adding any additional drivers
+VkResult loader_settings_get_additional_driver_files(const struct loader_instance* inst, struct loader_string_list* out_files);
+
+// Check if there are any device_configurations. If so, we don't want to allow environment variables from selecting or ignoring
+// drivers. This is because the VkPhysicalDevices corresponding to a driver_configurations might not be present otherwise.
+bool loader_settings_should_use_driver_environment_variables(const struct loader_instance* inst);
diff --git a/loader/terminator.c b/loader/terminator.c
index 26f8f5c..1f5364c 100644
--- a/loader/terminator.c
+++ b/loader/terminator.c
@@ -140,7 +140,7 @@
     if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
         fpGetPhysicalDeviceFeatures2 = icd_term->dispatch.GetPhysicalDeviceFeatures2;
     }
-    if (fpGetPhysicalDeviceFeatures2 == NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (fpGetPhysicalDeviceFeatures2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         fpGetPhysicalDeviceFeatures2 = icd_term->dispatch.GetPhysicalDeviceFeatures2KHR;
     }
 
@@ -198,7 +198,7 @@
     if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
         fpGetPhysicalDeviceProperties2 = icd_term->dispatch.GetPhysicalDeviceProperties2;
     }
-    if (fpGetPhysicalDeviceProperties2 == NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (fpGetPhysicalDeviceProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         fpGetPhysicalDeviceProperties2 = icd_term->dispatch.GetPhysicalDeviceProperties2KHR;
     }
 
@@ -223,7 +223,7 @@
                     VkPhysicalDeviceIDPropertiesKHR *id_properties = (VkPhysicalDeviceIDPropertiesKHR *)pNext;
 
                     // Verify that "VK_KHR_external_memory_capabilities" is enabled
-                    if (icd_term->this_instance->enabled_known_extensions.khr_external_memory_capabilities) {
+                    if (icd_term->this_instance->enabled_extensions.khr_external_memory_capabilities) {
                         loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
                                    "vkGetPhysicalDeviceProperties2: Emulation cannot generate unique IDs for struct "
                                    "VkPhysicalDeviceIDProperties - setting IDs to zero instead");
@@ -263,7 +263,7 @@
     if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
         fpGetPhysicalDeviceFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceFormatProperties2;
     }
-    if (fpGetPhysicalDeviceFormatProperties2 == NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (fpGetPhysicalDeviceFormatProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         fpGetPhysicalDeviceFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceFormatProperties2KHR;
     }
 
@@ -301,7 +301,7 @@
     if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
         fpGetPhysicalDeviceImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2;
     }
-    if (fpGetPhysicalDeviceImageFormatProperties2 == NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (fpGetPhysicalDeviceImageFormatProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         fpGetPhysicalDeviceImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2KHR;
     }
 
@@ -341,7 +341,7 @@
     if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
         fpGetPhysicalDeviceQueueFamilyProperties2 = icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2;
     }
-    if (fpGetPhysicalDeviceQueueFamilyProperties2 == NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (fpGetPhysicalDeviceQueueFamilyProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         fpGetPhysicalDeviceQueueFamilyProperties2 = icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2KHR;
     }
 
@@ -399,7 +399,7 @@
     if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
         fpGetPhysicalDeviceMemoryProperties2 = icd_term->dispatch.GetPhysicalDeviceMemoryProperties2;
     }
-    if (fpGetPhysicalDeviceMemoryProperties2 == NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (fpGetPhysicalDeviceMemoryProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         fpGetPhysicalDeviceMemoryProperties2 = icd_term->dispatch.GetPhysicalDeviceMemoryProperties2KHR;
     }
 
@@ -437,8 +437,7 @@
     if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
         fpGetPhysicalDeviceSparseImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2;
     }
-    if (fpGetPhysicalDeviceSparseImageFormatProperties2 == NULL &&
-        inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (fpGetPhysicalDeviceSparseImageFormatProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         fpGetPhysicalDeviceSparseImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2KHR;
     }
 
@@ -507,7 +506,7 @@
     if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
         fpGetPhysicalDeviceExternalBufferProperties = icd_term->dispatch.GetPhysicalDeviceExternalBufferProperties;
     }
-    if (fpGetPhysicalDeviceExternalBufferProperties == NULL && inst->enabled_known_extensions.khr_external_memory_capabilities) {
+    if (fpGetPhysicalDeviceExternalBufferProperties == NULL && inst->enabled_extensions.khr_external_memory_capabilities) {
         fpGetPhysicalDeviceExternalBufferProperties = icd_term->dispatch.GetPhysicalDeviceExternalBufferPropertiesKHR;
     }
 
@@ -550,8 +549,7 @@
     if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
         fpGetPhysicalDeviceExternalSemaphoreProperties = icd_term->dispatch.GetPhysicalDeviceExternalSemaphoreProperties;
     }
-    if (fpGetPhysicalDeviceExternalSemaphoreProperties == NULL &&
-        inst->enabled_known_extensions.khr_external_semaphore_capabilities) {
+    if (fpGetPhysicalDeviceExternalSemaphoreProperties == NULL && inst->enabled_extensions.khr_external_semaphore_capabilities) {
         fpGetPhysicalDeviceExternalSemaphoreProperties = icd_term->dispatch.GetPhysicalDeviceExternalSemaphorePropertiesKHR;
     }
 
@@ -597,7 +595,7 @@
     if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
         fpGetPhysicalDeviceExternalFenceProperties = icd_term->dispatch.GetPhysicalDeviceExternalFenceProperties;
     }
-    if (fpGetPhysicalDeviceExternalFenceProperties == NULL && inst->enabled_known_extensions.khr_external_fence_capabilities) {
+    if (fpGetPhysicalDeviceExternalFenceProperties == NULL && inst->enabled_extensions.khr_external_fence_capabilities) {
         fpGetPhysicalDeviceExternalFenceProperties = icd_term->dispatch.GetPhysicalDeviceExternalFencePropertiesKHR;
     }
 
diff --git a/loader/trampoline.c b/loader/trampoline.c
index 143aca4..0f37311 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -36,6 +36,7 @@
 #include "loader_environment.h"
 #include "log.h"
 #include "settings.h"
+#include "stack_allocation.h"
 #include "vk_loader_extensions.h"
 #include "vk_loader_platform.h"
 #include "wsi.h"
@@ -483,6 +484,8 @@
     VkInstance created_instance = VK_NULL_HANDLE;
     VkResult res = VK_ERROR_INITIALIZATION_FAILED;
     VkInstanceCreateInfo ici = {0};
+    bool portability_enumeration_flag_bit_set = false;
+    bool portability_enumeration_extension_enabled = false;
     struct loader_envvar_all_filters layer_filters = {0};
 
     LOADER_PLATFORM_THREAD_ONCE(&once_init, loader_initialize);
@@ -561,18 +564,19 @@
 
     // Check the VkInstanceCreateInfoFlags wether to allow the portability enumeration flag
     if ((pCreateInfo->flags & VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR) == 1) {
-        ptr_instance->portability_enumeration_flag_bit_set = true;
+        portability_enumeration_flag_bit_set = true;
     }
-    // Make sure the extension has been enabled
+    // Make sure the portability extension extension has been enabled before enabling portability driver enumeration
     if (pCreateInfo->ppEnabledExtensionNames) {
         for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
             if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME) == 0) {
-                ptr_instance->portability_enumeration_extension_enabled = true;
-                if (ptr_instance->portability_enumeration_flag_bit_set) {
+                portability_enumeration_extension_enabled = true;
+                if (portability_enumeration_flag_bit_set) {
                     ptr_instance->portability_enumeration_enabled = true;
                     loader_log(ptr_instance, VULKAN_LOADER_INFO_BIT, 0,
                                "Portability enumeration bit was set, enumerating portability drivers.");
                 }
+                break;
             }
         }
     }
@@ -622,14 +626,13 @@
     if (ptr_instance->icd_tramp_list.count == 0) {
         // No drivers found
         if (skipped_portability_drivers) {
-            if (ptr_instance->portability_enumeration_extension_enabled && !ptr_instance->portability_enumeration_flag_bit_set) {
+            if (portability_enumeration_extension_enabled && !portability_enumeration_flag_bit_set) {
                 loader_log(ptr_instance, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
                            "vkCreateInstance: Found drivers that contain devices which support the portability subset, but "
                            "the instance does not enumerate portability drivers! Applications that wish to enumerate portability "
                            "drivers must set the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit in the VkInstanceCreateInfo "
                            "flags.");
-            } else if (ptr_instance->portability_enumeration_flag_bit_set &&
-                       !ptr_instance->portability_enumeration_extension_enabled) {
+            } else if (portability_enumeration_flag_bit_set && !portability_enumeration_extension_enabled) {
                 loader_log(ptr_instance, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
                            "VkInstanceCreateInfo: If flags has the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit set, the "
                            "list of enabled extensions in ppEnabledExtensionNames must contain VK_KHR_portability_enumeration "
@@ -670,10 +673,8 @@
     }
     memcpy(&ptr_instance->disp->layer_inst_disp, &instance_disp, sizeof(instance_disp));
 
-    loader_platform_thread_lock_mutex(&loader_global_instance_list_lock);
     ptr_instance->next = loader.instances;
     loader.instances = ptr_instance;
-    loader_platform_thread_unlock_mutex(&loader_global_instance_list_lock);
 
     // Activate any layers on instance chain
     res = loader_enable_instance_layers(ptr_instance, &ici, &ptr_instance->instance_layer_list, &layer_filters);
@@ -691,9 +692,8 @@
         // are enabled than what's down in the terminator.
         // This is why we don't clear inside of these function calls.
         // The clearing should actually be handled by the overall memset of the pInstance structure above.
-        wsi_create_instance(ptr_instance, &ici);
-        check_for_enabled_debug_extensions(ptr_instance, &ici);
-        extensions_create_instance(ptr_instance, &ici);
+        fill_out_enabled_instance_extensions(ici.enabledExtensionCount, ici.ppEnabledExtensionNames,
+                                             &ptr_instance->enabled_extensions);
 
         *pInstance = (VkInstance)ptr_instance;
 
@@ -712,12 +712,10 @@
 
     if (NULL != ptr_instance) {
         if (res != VK_SUCCESS) {
-            loader_platform_thread_lock_mutex(&loader_global_instance_list_lock);
             // error path, should clean everything up
             if (loader.instances == ptr_instance) {
                 loader.instances = ptr_instance->next;
             }
-            loader_platform_thread_unlock_mutex(&loader_global_instance_list_lock);
 
             free_loader_settings(ptr_instance, &ptr_instance->settings);
 
@@ -733,7 +731,6 @@
             loader_destroy_pointer_layer_list(ptr_instance, &ptr_instance->app_activated_layer_list);
 
             loader_delete_layer_list_and_properties(ptr_instance, &ptr_instance->instance_layer_list);
-            loader_clear_scanned_icd_list(ptr_instance, &ptr_instance->icd_tramp_list);
             loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->ext_list);
 
             // Free any icd_terms that were created.
@@ -753,6 +750,7 @@
                 loader_icd_destroy(ptr_instance, icd_term, pAllocator);
             }
 
+            loader_clear_scanned_icd_list(ptr_instance, &ptr_instance->icd_tramp_list);
             free_string_list(ptr_instance, &ptr_instance->enabled_layer_names);
 
             loader_instance_heap_free(ptr_instance, ptr_instance);
@@ -851,8 +849,34 @@
         goto out;
     }
 
+    struct loader_envvar_id_filter device_id_filter;
+    struct loader_envvar_id_filter vendor_id_filter;
+    struct loader_envvar_id_filter driver_id_filter;
+
+    parse_id_filter_environment_var(inst, VK_DEVICE_ID_FILTER_ENV_VAR, &device_id_filter);
+    parse_id_filter_environment_var(inst, VK_VENDOR_ID_FILTER_ENV_VAR, &vendor_id_filter);
+    parse_id_filter_environment_var(inst, VK_DRIVER_ID_FILTER_ENV_VAR, &driver_id_filter);
+
     // Call down the chain to get the physical device info
-    res = inst->disp->layer_inst_disp.EnumeratePhysicalDevices(inst->instance, pPhysicalDeviceCount, pPhysicalDevices);
+    if ((0 == device_id_filter.count) && (0 == vendor_id_filter.count) && (0 == driver_id_filter.count)) {
+        res = inst->disp->layer_inst_disp.EnumeratePhysicalDevices(inst->instance, pPhysicalDeviceCount, pPhysicalDevices);
+    } else {
+        uint32_t physical_device_count = 0;
+        res = inst->disp->layer_inst_disp.EnumeratePhysicalDevices(inst->instance, &physical_device_count, NULL);
+        if (res != VK_SUCCESS) {
+            goto out;
+        }
+
+        VkPhysicalDevice *physical_devices = loader_stack_alloc(physical_device_count * sizeof(VkPhysicalDevice));
+        res = inst->disp->layer_inst_disp.EnumeratePhysicalDevices(inst->instance, &physical_device_count, physical_devices);
+        if (res != VK_SUCCESS) {
+            goto out;
+        }
+
+        res = loader_filter_enumerated_physical_device(inst, &device_id_filter, &vendor_id_filter, &driver_id_filter,
+                                                       physical_device_count, physical_devices, pPhysicalDeviceCount,
+                                                       pPhysicalDevices);
+    }
 
     if (NULL != pPhysicalDevices && (VK_SUCCESS == res || VK_INCOMPLETE == res)) {
         // Wrap the PhysDev object for loader usage, return wrapped objects
@@ -2585,9 +2609,40 @@
         goto out;
     }
 
+    struct loader_envvar_id_filter device_id_filter;
+    struct loader_envvar_id_filter vendor_id_filter;
+    struct loader_envvar_id_filter driver_id_filter;
+
+    parse_id_filter_environment_var(inst, VK_DEVICE_ID_FILTER_ENV_VAR, &device_id_filter);
+    parse_id_filter_environment_var(inst, VK_VENDOR_ID_FILTER_ENV_VAR, &vendor_id_filter);
+    parse_id_filter_environment_var(inst, VK_DRIVER_ID_FILTER_ENV_VAR, &driver_id_filter);
+
     // Call down the chain to get the physical device group info.
-    res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroups(inst->instance, pPhysicalDeviceGroupCount,
-                                                                    pPhysicalDeviceGroupProperties);
+    if ((0 == device_id_filter.count) && (0 == vendor_id_filter.count) && (0 == driver_id_filter.count)) {
+        res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroups(inst->instance, pPhysicalDeviceGroupCount,
+                                                                        pPhysicalDeviceGroupProperties);
+    } else {
+        uint32_t physical_device_group_count = 0;
+        res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroups(inst->instance, &physical_device_group_count, NULL);
+        if (res != VK_SUCCESS) {
+            goto out;
+        }
+
+        VkPhysicalDeviceGroupProperties *physical_device_group_properties =
+            loader_stack_alloc(physical_device_group_count * sizeof(VkPhysicalDeviceGroupProperties));
+        memset(physical_device_group_properties, 0, physical_device_group_count * sizeof(VkPhysicalDeviceGroupProperties));
+
+        res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroups(inst->instance, &physical_device_group_count,
+                                                                        physical_device_group_properties);
+        if (res != VK_SUCCESS) {
+            goto out;
+        }
+
+        res = loader_filter_enumerated_physical_device_groups(inst, &device_id_filter, &vendor_id_filter, &driver_id_filter,
+                                                              physical_device_group_count, physical_device_group_properties,
+                                                              pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
+    }
+
     if (NULL != pPhysicalDeviceGroupProperties && (VK_SUCCESS == res || VK_INCOMPLETE == res)) {
         // Wrap the PhysDev object for loader usage, return wrapped objects
         VkResult update_res = setup_loader_tramp_phys_dev_groups(inst, *pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
@@ -2614,7 +2669,7 @@
     const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
     const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
 
-    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (inst != NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         disp->GetPhysicalDeviceFeatures2KHR(unwrapped_phys_dev, pFeatures);
     } else {
         disp->GetPhysicalDeviceFeatures2(unwrapped_phys_dev, pFeatures);
@@ -2633,7 +2688,7 @@
     const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
     const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
 
-    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (inst != NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         disp->GetPhysicalDeviceProperties2KHR(unwrapped_phys_dev, pProperties);
     } else {
         disp->GetPhysicalDeviceProperties2(unwrapped_phys_dev, pProperties);
@@ -2652,7 +2707,7 @@
     const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
     const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
 
-    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (inst != NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         disp->GetPhysicalDeviceFormatProperties2KHR(unwrapped_phys_dev, format, pFormatProperties);
     } else {
         disp->GetPhysicalDeviceFormatProperties2(unwrapped_phys_dev, format, pFormatProperties);
@@ -2672,7 +2727,7 @@
     const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
     const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
 
-    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (inst != NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         return disp->GetPhysicalDeviceImageFormatProperties2KHR(unwrapped_phys_dev, pImageFormatInfo, pImageFormatProperties);
     } else {
         return disp->GetPhysicalDeviceImageFormatProperties2(unwrapped_phys_dev, pImageFormatInfo, pImageFormatProperties);
@@ -2691,7 +2746,7 @@
     const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
     const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
 
-    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (inst != NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         disp->GetPhysicalDeviceQueueFamilyProperties2KHR(unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties);
     } else {
         disp->GetPhysicalDeviceQueueFamilyProperties2(unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties);
@@ -2710,7 +2765,7 @@
     const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
     const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
 
-    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (inst != NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         disp->GetPhysicalDeviceMemoryProperties2KHR(unwrapped_phys_dev, pMemoryProperties);
     } else {
         disp->GetPhysicalDeviceMemoryProperties2(unwrapped_phys_dev, pMemoryProperties);
@@ -2730,7 +2785,7 @@
     const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
     const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
 
-    if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+    if (inst != NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
         disp->GetPhysicalDeviceSparseImageFormatProperties2KHR(unwrapped_phys_dev, pFormatInfo, pPropertyCount, pProperties);
     } else {
         disp->GetPhysicalDeviceSparseImageFormatProperties2(unwrapped_phys_dev, pFormatInfo, pPropertyCount, pProperties);
@@ -2750,7 +2805,7 @@
     const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
     const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
 
-    if (inst != NULL && inst->enabled_known_extensions.khr_external_memory_capabilities) {
+    if (inst != NULL && inst->enabled_extensions.khr_external_memory_capabilities) {
         disp->GetPhysicalDeviceExternalBufferPropertiesKHR(unwrapped_phys_dev, pExternalBufferInfo, pExternalBufferProperties);
     } else {
         disp->GetPhysicalDeviceExternalBufferProperties(unwrapped_phys_dev, pExternalBufferInfo, pExternalBufferProperties);
@@ -2770,7 +2825,7 @@
     const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
     const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
 
-    if (inst != NULL && inst->enabled_known_extensions.khr_external_semaphore_capabilities) {
+    if (inst != NULL && inst->enabled_extensions.khr_external_semaphore_capabilities) {
         disp->GetPhysicalDeviceExternalSemaphorePropertiesKHR(unwrapped_phys_dev, pExternalSemaphoreInfo,
                                                               pExternalSemaphoreProperties);
     } else {
@@ -2792,7 +2847,7 @@
     const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
     const struct loader_instance *inst = ((struct loader_physical_device_tramp *)physicalDevice)->this_instance;
 
-    if (inst != NULL && inst->enabled_known_extensions.khr_external_fence_capabilities) {
+    if (inst != NULL && inst->enabled_extensions.khr_external_fence_capabilities) {
         disp->GetPhysicalDeviceExternalFencePropertiesKHR(unwrapped_phys_dev, pExternalFenceInfo, pExternalFenceProperties);
     } else {
         disp->GetPhysicalDeviceExternalFenceProperties(unwrapped_phys_dev, pExternalFenceInfo, pExternalFenceProperties);
diff --git a/loader/unknown_ext_chain_gas_x86.S b/loader/unknown_ext_chain_gas_x86.S
index 5ee0205..2a9bb81 100644
--- a/loader/unknown_ext_chain_gas_x86.S
+++ b/loader/unknown_ext_chain_gas_x86.S
@@ -88,11 +88,16 @@
 .else
 
 .macro PhysDevExtTramp num
+#if defined(_WIN32)
+.global "_vkPhysDevExtTramp\num\()@4"
+"_vkPhysDevExtTramp\num\()@4":
+#else
 .global vkPhysDevExtTramp\num
 #if defined(__ELF__)
 .hidden vkPhysDevExtTramp\num
 #endif
 vkPhysDevExtTramp\num:
+#endif
     _CET_ENDBR
     mov     eax, [esp + 4]                              # Load the wrapped VkPhysicalDevice into eax
     mov     ecx, [eax + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] # Load the unwrapped VkPhysicalDevice into ecx
@@ -102,11 +107,16 @@
 .endm
 
 .macro PhysDevExtTermin num
+#if defined(_WIN32)
+.global "_vkPhysDevExtTermin\num\()@4"
+"_vkPhysDevExtTermin\num\()@4":
+#else
 .global vkPhysDevExtTermin\num
 #if defined(__ELF__)
 .hidden vkPhysDevExtTermin\num
 #endif
 vkPhysDevExtTermin\num:
+#endif
     _CET_ENDBR
     mov     ecx, [esp + 4]                                                      # Move the wrapped VkPhysicalDevice into ecx
     mov     eax, [ecx + ICD_TERM_OFFSET_PHYS_DEV_TERM]                          # Store the loader_icd_term* in eax
@@ -121,18 +131,27 @@
     push    0                                                                     # Push zero (third arg)
     push    VULKAN_LOADER_ERROR_BIT                                               # Push the error logging bit (second arg)
     push    eax                                                                   # Push the loader_instance (first arg)
+#if defined(_WIN32)
+    call    _loader_log_asm_function_not_supported                                # Log the error message before we crash
+#else
     call    loader_log_asm_function_not_supported                                 # Log the error message before we crash
+#endif
     add     esp, 20                                                               # Clean up the args
     mov     eax, 0
     jmp     eax                                                         # Crash intentionally by jumping to address zero
 .endm
 
 .macro DevExtTramp num
+#if defined(_WIN32)
+.global "_vkdev_ext\num\()@4"
+"_vkdev_ext\num\()@4":
+#else
 .global vkdev_ext\num
 #if defined(__ELF__)
 .hidden vkdev_ext\num
 #endif
 vkdev_ext\num:
+#endif
     _CET_ENDBR
     mov     eax, dword ptr [esp + 4]                                            # Dereference the handle to get the dispatch table
     mov     eax, dword ptr [eax]                                                # Dereference the chain_device to get the loader_dispatch
diff --git a/loader/vk_loader_platform.h b/loader/vk_loader_platform.h
index 4188ec9..1be59fd 100644
--- a/loader/vk_loader_platform.h
+++ b/loader/vk_loader_platform.h
@@ -44,7 +44,7 @@
 
 // Set of platforms with a common set of functionality which is queried throughout the program
 #if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNX__) || defined(__FreeBSD__) || \
-    defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__)
+    defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__) || defined(__CYGWIN__)
 #define COMMON_UNIX_PLATFORMS 1
 #else
 #define COMMON_UNIX_PLATFORMS 0
@@ -91,6 +91,17 @@
 #define LOADER_EXPORT
 #endif
 
+// For testing purposes, we want to expose some functions not normally callable on the library
+#if defined(SHOULD_EXPORT_TEST_FUNCTIONS)
+#if defined(_WIN32)
+#define TEST_FUNCTION_EXPORT __declspec(dllexport)
+#else
+#define TEST_FUNCTION_EXPORT LOADER_EXPORT
+#endif
+#else
+#define TEST_FUNCTION_EXPORT
+#endif
+
 #define MAX_STRING_SIZE 1024
 
 // This is defined in vk_layer.h, but if there's problems we need to create the define
@@ -121,6 +132,10 @@
 #define VK_IMPLICIT_LAYER_PATH_ENV_VAR "VK_IMPLICIT_LAYER_PATH"
 #define VK_ADDITIONAL_IMPLICIT_LAYER_PATH_ENV_VAR "VK_ADD_IMPLICIT_LAYER_PATH"
 
+#define VK_DEVICE_ID_FILTER_ENV_VAR "VK_LOADER_DEVICE_ID_FILTER"
+#define VK_VENDOR_ID_FILTER_ENV_VAR "VK_LOADER_VENDOR_ID_FILTER"
+#define VK_DRIVER_ID_FILTER_ENV_VAR "VK_LOADER_DRIVER_ID_FILTER"
+
 // Override layer information
 #define VK_OVERRIDE_LAYER_NAME "VK_LAYER_LUNARG_override"
 
@@ -289,7 +304,7 @@
 
 // loader_platform_executable_path finds application path + name.
 // Path cannot be longer than 1024, returns NULL if it is greater than that.
-#if defined(__linux__) || defined(__GNU__)
+#if defined(__linux__) || defined(__GNU__) || defined(__CYGWIN__)
 static inline char *loader_platform_executable_path(char *buffer, size_t size) {
     ssize_t count = readlink("/proc/self/exe", buffer, size);
     if (count == -1) return NULL;
@@ -440,7 +455,12 @@
 }
 
 // Thread mutex:
-static inline void loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) { pthread_mutex_init(pMutex, NULL); }
+static inline void loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) {
+    pthread_mutexattr_t attr;
+    pthread_mutexattr_init(&attr);
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init(pMutex, &attr);
+}
 static inline void loader_platform_thread_lock_mutex(loader_platform_thread_mutex *pMutex) { pthread_mutex_lock(pMutex); }
 static inline void loader_platform_thread_unlock_mutex(loader_platform_thread_mutex *pMutex) { pthread_mutex_unlock(pMutex); }
 static inline void loader_platform_thread_delete_mutex(loader_platform_thread_mutex *pMutex) { pthread_mutex_destroy(pMutex); }
diff --git a/loader/wsi.c b/loader/wsi.c
index d04b7b3..cffd14b 100644
--- a/loader/wsi.c
+++ b/loader/wsi.c
@@ -39,103 +39,226 @@
 // the ICDs.
 #define ICD_VER_SUPPORTS_ICD_SURFACE_KHR 3
 
-void wsi_create_instance(struct loader_instance *loader_inst, const VkInstanceCreateInfo *pCreateInfo) {
-    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_surface_enabled = true;
-            continue;
-        }
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_win32_surface_enabled = true;
-            continue;
-        }
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_wayland_surface_enabled = true;
-            continue;
-        }
-#endif  // VK_USE_PLATFORM_WAYLAND_KHR
-#if defined(VK_USE_PLATFORM_XCB_KHR)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_xcb_surface_enabled = true;
-            continue;
-        }
-#endif  // VK_USE_PLATFORM_XCB_KHR
-#if defined(VK_USE_PLATFORM_XLIB_KHR)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_xlib_surface_enabled = true;
-            continue;
-        }
-#endif  // VK_USE_PLATFORM_XLIB_KHR
-#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_directfb_surface_enabled = true;
-            continue;
-        }
-#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
+struct loader_struct_type_info {
+    VkStructureType stype;
+    size_t size;
+};
+
+// This function unwraps the application-provided surface handle into the ICD-specific surface handle
+// corresponding to the specified physical device. If the ICD-specific surface handle does not exist
+// yet, then this function also creates of the ICD-specific surface object. This enables lazy creation
+// of ICD-specific surface objects and therefore avoids creating surfaces for ICDs that may not be able
+// to or should not create the specific type of surface (one example is the VK_KHR_display extension
+// where the VkDisplayModeKHR handles the surfaces are created from are physical-device-specific
+// non-dispatchable handles and therefore they should not be passed down to a foreign ICD).
+VkResult wsi_unwrap_icd_surface(struct loader_icd_term *icd_term, VkSurfaceKHR *surface) {
+    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(*surface);
+
 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_android_surface_enabled = true;
-            continue;
-        }
+    if (icd_surface->base.platform == VK_ICD_WSI_PLATFORM_ANDROID) {
+        // Android does not use ICD-created surfaces
+        // NOTE: This may be incorrect and in fact the legacy code could result in out-of-bounds
+        // accesses to VkIcdSurface::surface_index in case of Android, but we preserved the legacy
+        // behavior (while also eliminating the chance for out-of-bounds accesses).
+        return VK_SUCCESS;
+    }
 #endif  // VK_USE_PLATFORM_ANDROID_KHR
 #if defined(VK_USE_PLATFORM_MACOS_MVK)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_MVK_MACOS_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_macos_surface_enabled = true;
-            continue;
-        }
-#endif  // VK_USE_PLATFORM_MACOS_MVK
-#if defined(VK_USE_PLATFORM_IOS_MVK)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_MVK_IOS_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_ios_surface_enabled = true;
-            continue;
-        }
-#endif  // VK_USE_PLATFORM_IOS_MVK
-#if defined(VK_USE_PLATFORM_GGP)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_ggp_surface_enabled = true;
-            continue;
-        }
-#endif  // VK_USE_PLATFORM_GGP
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_imagepipe_surface_enabled = true;
-            continue;
-        }
-#endif  // VK_USE_PLATFORM_FUCHSIA
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_headless_surface_enabled = true;
-            continue;
-        }
-#if defined(VK_USE_PLATFORM_METAL_EXT)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_METAL_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_metal_surface_enabled = true;
-            continue;
-        }
-#endif
-#if defined(VK_USE_PLATFORM_SCREEN_QNX)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_QNX_SCREEN_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_screen_surface_enabled = true;
-            continue;
-        }
-#endif  // VK_USE_PLATFORM_SCREEN_QNX
-#if defined(VK_USE_PLATFORM_VI_NN)
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NN_VI_SURFACE_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_vi_surface_enabled = true;
-            continue;
-        }
-#endif  // VK_USE_PLATFORM_VI_NN
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_display_enabled = true;
-            continue;
-        }
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME) == 0) {
-            loader_inst->wsi_display_props2_enabled = true;
-            continue;
-        }
+    if (icd_surface->base.platform == VK_ICD_WSI_PLATFORM_IOS) {
+        // iOS does not use ICD-created surfaces (matching legacy behavior)
+        // NOTE: This may be incorrect and in fact the legacy code could result in out-of-bounds
+        // accesses to VkIcdSurface::surface_index in case of Android, but we preserved the legacy
+        // behavior (while also eliminating the chance for out-of-bounds accesses).
+        return VK_SUCCESS;
     }
+#endif  // VK_USE_PLATFORM_MACOS_MVK
+
+    if (NULL == icd_term->surface_list.list ||
+        icd_term->surface_list.capacity <= icd_surface->surface_index * sizeof(VkSurfaceKHR)) {
+        // This surface handle is not one that was created by the loader, therefore we simply return
+        // the input surface handle unmodified. This matches legacy behavior.
+        return VK_SUCCESS;
+    }
+
+    VkResult result = VK_SUCCESS;
+    if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+        VkAllocationCallbacks *pAllocator = icd_surface->callbacks_valid ? &icd_surface->callbacks : NULL;
+        if (VK_NULL_HANDLE == icd_term->surface_list.list[icd_surface->surface_index]) {
+            // If the surface does not exist yet for the target ICD, then create it lazily
+            switch (icd_surface->base.platform) {
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+                case VK_ICD_WSI_PLATFORM_WAYLAND:
+                    if (NULL != icd_term->dispatch.CreateWaylandSurfaceKHR &&
+                        icd_term->enabled_instance_extensions.khr_wayland_surface) {
+                        result = icd_term->dispatch.CreateWaylandSurfaceKHR(
+                            icd_term->instance, (const VkWaylandSurfaceCreateInfoKHR *)icd_surface->create_info, pAllocator,
+                            &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+#endif  // VK_USE_PLATFORM_WAYLAND_KHR
+
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+                case VK_ICD_WSI_PLATFORM_WIN32:
+                    if (NULL != icd_term->dispatch.CreateWin32SurfaceKHR &&
+                        icd_term->enabled_instance_extensions.khr_win32_surface) {
+                        result = icd_term->dispatch.CreateWin32SurfaceKHR(
+                            icd_term->instance, (const VkWin32SurfaceCreateInfoKHR *)icd_surface->create_info, pAllocator,
+                            &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+                case VK_ICD_WSI_PLATFORM_XCB:
+                    if (NULL != icd_term->dispatch.CreateXcbSurfaceKHR && icd_term->enabled_instance_extensions.khr_xcb_surface) {
+                        result = icd_term->dispatch.CreateXcbSurfaceKHR(
+                            icd_term->instance, (const VkXcbSurfaceCreateInfoKHR *)icd_surface->create_info, pAllocator,
+                            &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+#endif  // VK_USE_PLATFORM_XCB_KHR
+
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+                case VK_ICD_WSI_PLATFORM_XLIB:
+                    if (NULL != icd_term->dispatch.CreateXlibSurfaceKHR && icd_term->enabled_instance_extensions.khr_xlib_surface) {
+                        result = icd_term->dispatch.CreateXlibSurfaceKHR(
+                            icd_term->instance, (const VkXlibSurfaceCreateInfoKHR *)icd_surface->create_info, pAllocator,
+                            &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+#endif  // VK_USE_PLATFORM_XLIB_KHR
+
+#if defined(VK_USE_PLATFORM_MACOS_MVK)
+                case VK_ICD_WSI_PLATFORM_MACOS:
+                    if (NULL != icd_term->dispatch.CreateMacOSSurfaceMVK &&
+                        icd_term->enabled_instance_extensions.mvk_macos_surface) {
+                        result = icd_term->dispatch.CreateMacOSSurfaceMVK(
+                            icd_term->instance, (const VkMacOSSurfaceCreateInfoMVK *)icd_surface->create_info, pAllocator,
+                            &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+#endif  // VK_USE_PLATFORM_MACOS_MVK
+
+                case VK_ICD_WSI_PLATFORM_DISPLAY:
+                    if (NULL != icd_term->dispatch.CreateDisplayPlaneSurfaceKHR &&
+                        icd_term->enabled_instance_extensions.khr_display) {
+                        result = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(
+                            icd_term->instance, (const VkDisplaySurfaceCreateInfoKHR *)icd_surface->create_info, pAllocator,
+                            &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+
+                case VK_ICD_WSI_PLATFORM_HEADLESS:
+                    if (NULL != icd_term->dispatch.CreateHeadlessSurfaceEXT &&
+                        icd_term->enabled_instance_extensions.ext_headless_surface) {
+                        result = icd_term->dispatch.CreateHeadlessSurfaceEXT(
+                            icd_term->instance, (const VkHeadlessSurfaceCreateInfoEXT *)icd_surface->create_info, pAllocator,
+                            &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+                case VK_ICD_WSI_PLATFORM_METAL:
+                    if (NULL != icd_term->dispatch.CreateMetalSurfaceEXT &&
+                        icd_term->enabled_instance_extensions.ext_metal_surface) {
+                        result = icd_term->dispatch.CreateMetalSurfaceEXT(
+                            icd_term->instance, (const VkMetalSurfaceCreateInfoEXT *)icd_surface->create_info, pAllocator,
+                            &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+#endif  // VK_USE_PLATFORM_METAL_EXT
+
+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+                case VK_ICD_WSI_PLATFORM_DIRECTFB:
+                    if (NULL != icd_term->dispatch.CreateDirectFBSurfaceEXT &&
+                        icd_term->enabled_instance_extensions.ext_directfb_surface) {
+                        result = icd_term->dispatch.CreateDirectFBSurfaceEXT(
+                            icd_term->instance, (const VkDirectFBSurfaceCreateInfoEXT *)icd_surface->create_info, pAllocator,
+                            &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
+
+#if defined(VK_USE_PLATFORM_VI_NN)
+                case VK_ICD_WSI_PLATFORM_VI:
+                    if (NULL != icd_term->dispatch.CreateViSurfaceNN && icd_term->enabled_instance_extensions.nn_vi_surface) {
+                        result = icd_term->dispatch.CreateViSurfaceNN(
+                            icd_term->instance, (const VkViSurfaceCreateInfoNN *)icd_surface->create_info, pAllocator,
+                            &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+#endif  // VK_USE_PLATFORM_VI_NN
+
+#if defined(VK_USE_PLATFORM_GGP)
+                case VK_ICD_WSI_PLATFORM_GGP:
+                    if (NULL != icd_term->dispatch.CreateStreamDescriptorSurfaceGGP &&
+                        icd_term->enabled_instance_extensions.ggp_stream_descriptor_surface) {
+                        result = icd_term->dispatch.CreateStreamDescriptorSurfaceGGP(
+                            icd_term->instance, (const VkStreamDescriptorSurfaceCreateInfoGGP *)icd_surface->create_info,
+                            pAllocator, &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+#endif  // VK_USE_PLATFORM_GGP
+
+#if defined(VK_USE_PLATFORM_SCREEN_QNX)
+                case VK_ICD_WSI_PLATFORM_SCREEN:
+                    if (NULL != icd_term->dispatch.CreateScreenSurfaceQNX &&
+                        icd_term->enabled_instance_extensions.qnx_screen_surface) {
+                        result = icd_term->dispatch.CreateScreenSurfaceQNX(
+                            icd_term->instance, (const VkScreenSurfaceCreateInfoQNX *)icd_surface->create_info, pAllocator,
+                            &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+#endif  // VK_USE_PLATFORM_SCREEN_QNX
+
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+                case VK_ICD_WSI_PLATFORM_FUCHSIA:
+                    if (NULL != icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA &&
+                        icd_term->enabled_instance_extensions.fuchsia_imagepipe_surface) {
+                        result = icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA(
+                            icd_term->instance, (const VkImagePipeSurfaceCreateInfoFUCHSIA *)icd_surface->create_info, pAllocator,
+                            &icd_term->surface_list.list[icd_surface->surface_index]);
+                    } else {
+                        result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    }
+                    break;
+#endif  // VK_USE_PLATFORM_FUCHSIA
+
+                default:
+                    // Not supported
+                    result = VK_ERROR_EXTENSION_NOT_PRESENT;
+                    break;
+            }
+        }
+
+        *surface = icd_term->surface_list.list[icd_surface->surface_index];
+    }
+
+    return result;
 }
 
 // Linux WSI surface extensions are not always compiled into the loader. (Assume
@@ -189,19 +312,25 @@
     VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface);
     if (NULL != icd_surface) {
         for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-            if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-                if (NULL != icd_term->dispatch.DestroySurfaceKHR && icd_term->surface_list.list[icd_surface->surface_index]) {
-                    icd_term->dispatch.DestroySurfaceKHR(icd_term->instance,
-                                                         icd_term->surface_list.list[icd_surface->surface_index], pAllocator);
-                    icd_term->surface_list.list[icd_surface->surface_index] = (VkSurfaceKHR)(uintptr_t)NULL;
-                }
+            if (icd_term->enabled_instance_extensions.khr_surface &&
+                icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR &&
+                NULL != icd_term->dispatch.DestroySurfaceKHR && icd_term->surface_list.list[icd_surface->surface_index]) {
+                icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_term->surface_list.list[icd_surface->surface_index],
+                                                     pAllocator);
+                icd_term->surface_list.list[icd_surface->surface_index] = (VkSurfaceKHR)(uintptr_t)NULL;
+
             } else {
                 // The real_icd_surface for any ICD not supporting the
                 // proper interface version should be NULL.  If not, then
                 // we have a problem.
-                assert((VkSurfaceKHR)(uintptr_t)NULL == icd_term->surface_list.list[icd_surface->surface_index]);
+                assert(!(icd_term->enabled_instance_extensions.khr_surface &&
+                         icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) ||
+                       (VkSurfaceKHR)(uintptr_t)NULL == icd_term->surface_list.list[icd_surface->surface_index]);
             }
         }
+        if (NULL != icd_surface->create_info) {
+            loader_instance_heap_free(loader_inst, icd_surface->create_info);
+        }
         loader_release_object_from_list(&loader_inst->surfaces_list, icd_surface->surface_index);
         loader_instance_heap_free(loader_inst, (void *)(uintptr_t)surface);
     }
@@ -232,7 +361,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not executed!");
         return VK_SUCCESS;
@@ -253,12 +382,11 @@
         return VK_SUCCESS;
     }
 
-    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
-    if (NULL != icd_term->surface_list.list &&
-        icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-        icd_term->surface_list.list[icd_surface->surface_index]) {
-        return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR(
-            phys_dev_term->phys_dev, queueFamilyIndex, icd_term->surface_list.list[icd_surface->surface_index], pSupported);
+    VkResult res = wsi_unwrap_icd_surface(icd_term, &surface);
+    if (res != VK_SUCCESS) {
+        // set pSupported to false as this driver doesn't support WSI functionality
+        *pSupported = false;
+        return VK_SUCCESS;
     }
 
     return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, surface, pSupported);
@@ -288,7 +416,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceCapabilitiesKHR not executed!");
         return VK_SUCCESS;
@@ -308,13 +436,9 @@
         return VK_SUCCESS;
     }
 
-    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
-    if (NULL != phys_dev_term->this_icd_term->surface_list.list &&
-        phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-        phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) {
-        return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(
-            phys_dev_term->phys_dev, phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index],
-            pSurfaceCapabilities);
+    VkResult res = wsi_unwrap_icd_surface(icd_term, &surface);
+    if (res != VK_SUCCESS) {
+        return res;
     }
 
     return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface, pSurfaceCapabilities);
@@ -346,7 +470,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not executed!");
         return VK_SUCCESS;
@@ -362,17 +486,15 @@
         // Zero out the format count as this driver doesn't support WSI functionality
         *pSurfaceFormatCount = 0;
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
-                   "ICD for selected physical device does not export vkGetPhysicalDeviceSurfaceCapabilitiesKHR!");
+                   "ICD for selected physical device does not export vkGetPhysicalDeviceSurfaceFormatsKHR!");
         return VK_SUCCESS;
     }
 
-    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
-    if (NULL != phys_dev_term->this_icd_term->surface_list.list &&
-        phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-        phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) {
-        return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(
-            phys_dev_term->phys_dev, phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index],
-            pSurfaceFormatCount, pSurfaceFormats);
+    if (VK_NULL_HANDLE != surface) {
+        VkResult res = wsi_unwrap_icd_surface(icd_term, &surface);
+        if (res != VK_SUCCESS) {
+            return res;
+        }
     }
 
     return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
@@ -405,7 +527,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR not executed!");
         return VK_SUCCESS;
@@ -425,13 +547,11 @@
         return VK_SUCCESS;
     }
 
-    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
-    if (NULL != phys_dev_term->this_icd_term->surface_list.list &&
-        phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-        phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) {
-        return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(
-            phys_dev_term->phys_dev, phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index], pPresentModeCount,
-            pPresentModes);
+    if (VK_NULL_HANDLE != surface) {
+        VkResult res = wsi_unwrap_icd_surface(icd_term, &surface);
+        if (res != VK_SUCCESS) {
+            return res;
+        }
     }
 
     return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(phys_dev_term->phys_dev, surface, pPresentModeCount,
@@ -484,22 +604,14 @@
                    "extension enabled?");
         return VK_SUCCESS;
     }
-    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfo->surface;
-    if (NULL != icd_term->surface_list.list &&
-        icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-        icd_term->surface_list.list[icd_surface->surface_index]) {
-        // We found the ICD, and there is an ICD KHR surface
-        // associated with it, so copy the CreateInfo struct
-        // and point it at the ICD's surface.
-        VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR));
-        if (NULL == pCreateCopy) {
-            return VK_ERROR_OUT_OF_HOST_MEMORY;
-        }
-        memcpy(pCreateCopy, pCreateInfo, sizeof(VkSwapchainCreateInfoKHR));
-        pCreateCopy->surface = icd_term->surface_list.list[icd_surface->surface_index];
-        return dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR(device, pCreateCopy, pAllocator, pSwapchain);
+
+    VkSwapchainCreateInfoKHR create_info_copy = *pCreateInfo;
+    VkResult res = wsi_unwrap_icd_surface(icd_term, &create_info_copy.surface);
+    if (res != VK_SUCCESS) {
+        return res;
     }
-    return dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
+
+    return dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR(device, &create_info_copy, pAllocator, pSwapchain);
 }
 
 // This is the trampoline entrypoint for DestroySwapchainKHR
@@ -549,8 +661,8 @@
     return disp->QueuePresentKHR(queue, pPresentInfo);
 }
 
-VkResult allocate_icd_surface_struct(struct loader_instance *instance, const VkAllocationCallbacks *pAllocator,
-                                     VkIcdSurface **out_icd_surface) {
+VkResult allocate_icd_surface_struct(struct loader_instance *instance, size_t base_size, size_t platform_size,
+                                     const VkAllocationCallbacks *pAllocator, VkIcdSurface **out_icd_surface) {
     uint32_t next_index = 0;
     VkIcdSurface *icd_surface = NULL;
     VkResult res = loader_get_next_available_entry(instance, &instance->surfaces_list, &next_index, pAllocator);
@@ -559,17 +671,23 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    icd_surface = loader_instance_heap_alloc(instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+    icd_surface = loader_instance_heap_calloc(instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
     if (icd_surface == NULL) {
         res = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
     }
     // Setup the new sizes and offsets so we can grow the structures in the
     // future without having problems
+    icd_surface->base_size = (uint32_t)base_size;
+    icd_surface->platform_size = (uint32_t)platform_size;
+    icd_surface->non_platform_offset = (uint32_t)((uint8_t *)(&icd_surface->base_size) - (uint8_t *)icd_surface);
+    icd_surface->entire_size = sizeof(VkIcdSurface);
     icd_surface->surface_index = next_index;
+    icd_surface->create_info = NULL;
 
     for (struct loader_icd_term *icd_term = instance->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+        if (icd_term->enabled_instance_extensions.khr_surface &&
+            icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
             if (icd_term->surface_list.list == NULL) {
                 res =
                     loader_init_generic_list(instance, (struct loader_generic_list *)&icd_term->surface_list, sizeof(VkSurfaceKHR));
@@ -594,11 +712,67 @@
     return res;
 }
 
+VkResult copy_surface_create_info(struct loader_instance *loader_inst, VkIcdSurface *icd_surface, const void *create_info,
+                                  size_t struct_type_info_count, const struct loader_struct_type_info *struct_type_info,
+                                  const char *base_struct_name, const VkAllocationCallbacks *pAllocator) {
+    size_t create_info_total_size = 0;
+    const void *pnext = create_info;
+    while (NULL != pnext) {
+        VkBaseInStructure base = {0};
+        memcpy(&base, pnext, sizeof(VkBaseInStructure));
+        bool known_struct = false;
+        for (size_t i = 0; i < struct_type_info_count; ++i) {
+            if (base.sType == struct_type_info[i].stype) {
+                create_info_total_size += loader_aligned_size(struct_type_info[i].size);
+                pnext = base.pNext;
+                known_struct = true;
+                break;
+            }
+        }
+        if (!known_struct) {
+            loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "Unsupported extension structure in %s pNext chain.",
+                       base_struct_name);
+            return VK_ERROR_EXTENSION_NOT_PRESENT;
+        }
+    }
+
+    icd_surface->create_info = loader_instance_heap_alloc(loader_inst, create_info_total_size, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+    if (NULL == icd_surface->create_info) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+
+    uint8_t *dst = (uint8_t *)icd_surface->create_info;
+    VkBaseInStructure *prev_struct = NULL;
+    pnext = create_info;
+    while (NULL != pnext) {
+        VkBaseInStructure base = {0};
+        memcpy(&base, pnext, sizeof(VkBaseInStructure));
+        for (size_t i = 0; i < struct_type_info_count; ++i) {
+            if (base.sType == struct_type_info[i].stype) {
+                memcpy(dst, pnext, struct_type_info[i].size);
+                if (NULL != prev_struct) {
+                    prev_struct->pNext = (const VkBaseInStructure *)dst;
+                }
+                prev_struct = (VkBaseInStructure *)dst;
+                dst += loader_aligned_size(struct_type_info[i].size);
+                pnext = base.pNext;
+                break;
+            }
+        }
+    }
+    if (pAllocator) {
+        icd_surface->callbacks_valid = true;
+        icd_surface->callbacks = *pAllocator;
+    }
+
+    return VK_SUCCESS;
+}
+
 void cleanup_surface_creation(struct loader_instance *loader_inst, VkResult result, VkIcdSurface *icd_surface,
                               const VkAllocationCallbacks *pAllocator) {
     if (VK_SUCCESS != result && NULL != icd_surface) {
         for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-            if (NULL != icd_term->surface_list.list &&
+            if (icd_term->enabled_instance_extensions.khr_surface && NULL != icd_term->surface_list.list &&
                 icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
                 icd_term->surface_list.list[icd_surface->surface_index] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
                 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_term->surface_list.list[icd_surface->surface_index],
@@ -612,6 +786,9 @@
                 loader_inst->surfaces_list.list[icd_surface->surface_index].allocation_callbacks = *pAllocator;
             }
         }
+        if (NULL != icd_surface->create_info) {
+            loader_instance_heap_free(loader_inst, icd_surface->create_info);
+        }
         loader_instance_heap_free(loader_inst, icd_surface);
     }
 }
@@ -645,7 +822,7 @@
     *pSurface = VK_NULL_HANDLE;
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_win32_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_win32_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_win32_surface extension not enabled. vkCreateWin32SurfaceKHR not executed!");
         result = VK_ERROR_EXTENSION_NOT_PRESENT;
@@ -653,22 +830,23 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->win_surf.base), sizeof(icd_surface->win_surf), pAllocator,
+                                         &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateWin32SurfaceKHR) {
-                result = icd_term->dispatch.CreateWin32SurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
-                                                                  &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->win_surf.base.platform = VK_ICD_WSI_PLATFORM_WIN32;
+    icd_surface->win_surf.hinstance = pCreateInfo->hinstance;
+    icd_surface->win_surf.hwnd = pCreateInfo->hwnd;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, sizeof(VkWin32SurfaceCreateInfoKHR)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkWin32SurfaceCreateInfoKHR", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
 
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
@@ -703,7 +881,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_win32_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_win32_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_win32_surface extension not enabled. vkGetPhysicalDeviceWin32PresentationSupportKHR not executed!");
         return VK_FALSE;
@@ -746,7 +924,7 @@
 
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_wayland_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_wayland_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_wayland_surface extension not enabled. vkCreateWaylandSurfaceKHR not executed!");
         result = VK_ERROR_EXTENSION_NOT_PRESENT;
@@ -754,22 +932,23 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->wayland_surf.base), sizeof(icd_surface->wayland_surf),
+                                         pAllocator, &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateWaylandSurfaceKHR) {
-                result = icd_term->dispatch.CreateWaylandSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
-                                                                    &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->wayland_surf.base.platform = VK_ICD_WSI_PLATFORM_WAYLAND;
+    icd_surface->wayland_surf.display = pCreateInfo->display;
+    icd_surface->wayland_surf.surface = pCreateInfo->surface;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, sizeof(VkWaylandSurfaceCreateInfoKHR)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkWaylandSurfaceCreateInfoKHR", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
 
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
@@ -807,7 +986,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_wayland_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_wayland_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_wayland_surface extension not enabled. vkGetPhysicalDeviceWaylandPresentationSupportKHR not executed!");
         return VK_FALSE;
@@ -851,7 +1030,7 @@
 
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_xcb_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_xcb_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_xcb_surface extension not enabled. vkCreateXcbSurfaceKHR not executed!");
         result = VK_ERROR_EXTENSION_NOT_PRESENT;
@@ -859,22 +1038,23 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->xcb_surf.base), sizeof(icd_surface->xcb_surf), pAllocator,
+                                         &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateXcbSurfaceKHR) {
-                result = icd_term->dispatch.CreateXcbSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
-                                                                &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->xcb_surf.base.platform = VK_ICD_WSI_PLATFORM_XCB;
+    icd_surface->xcb_surf.connection = pCreateInfo->connection;
+    icd_surface->xcb_surf.window = pCreateInfo->window;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, sizeof(VkXcbSurfaceCreateInfoKHR)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkXcbSurfaceCreateInfoKHR", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
 
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
@@ -914,7 +1094,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_xcb_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_xcb_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_xcb_surface extension not enabled. vkGetPhysicalDeviceXcbPresentationSupportKHR not executed!");
         return VK_FALSE;
@@ -959,7 +1139,7 @@
 
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_xlib_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_xlib_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_xlib_surface extension not enabled. vkCreateXlibSurfaceKHR not executed!");
         result = VK_ERROR_EXTENSION_NOT_PRESENT;
@@ -967,22 +1147,23 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->xlib_surf.base), sizeof(icd_surface->xlib_surf),
+                                         pAllocator, &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateXlibSurfaceKHR) {
-                result = icd_term->dispatch.CreateXlibSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
-                                                                 &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->xlib_surf.base.platform = VK_ICD_WSI_PLATFORM_XLIB;
+    icd_surface->xlib_surf.dpy = pCreateInfo->dpy;
+    icd_surface->xlib_surf.window = pCreateInfo->window;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, sizeof(VkXlibSurfaceCreateInfoKHR)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkXlibSurfaceCreateInfoKHR", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
 
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
@@ -1020,7 +1201,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_xlib_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_xlib_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_xlib_surface extension not enabled. vkGetPhysicalDeviceXlibPresentationSupportKHR not executed!");
         return VK_FALSE;
@@ -1066,7 +1247,7 @@
 
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_directfb_surface_enabled) {
+    if (!loader_inst->enabled_extensions.ext_directfb_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_EXT_directfb_surface extension not enabled. vkCreateDirectFBSurfaceEXT not executed!");
         result = VK_ERROR_EXTENSION_NOT_PRESENT;
@@ -1074,22 +1255,23 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->directfb_surf.base), sizeof(icd_surface->directfb_surf),
+                                         pAllocator, &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateDirectFBSurfaceEXT) {
-                result = icd_term->dispatch.CreateDirectFBSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
-                                                                     &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->directfb_surf.base.platform = VK_ICD_WSI_PLATFORM_DIRECTFB;
+    icd_surface->directfb_surf.dfb = pCreateInfo->dfb;
+    icd_surface->directfb_surf.surface = pCreateInfo->surface;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT, sizeof(VkDirectFBSurfaceCreateInfoEXT)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkDirectFBSurfaceCreateInfoEXT", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
 
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
@@ -1127,7 +1309,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_directfb_surface_enabled) {
+    if (!loader_inst->enabled_extensions.ext_directfb_surface) {
         loader_log(
             loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
             "VK_EXT_directfb_surface extension not enabled. vkGetPhysicalDeviceDirectFBPresentationSupportKHR not executed!");
@@ -1170,7 +1352,7 @@
                                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_display_enabled) {
+    if (!loader_inst->enabled_extensions.khr_display) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_display extension not enabled. vkCreateAndroidSurfaceKHR not executed!");
         return VK_ERROR_EXTENSION_NOT_PRESENT;
@@ -1218,7 +1400,7 @@
 
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_headless_surface_enabled) {
+    if (!loader_inst->enabled_extensions.ext_headless_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_EXT_headless_surface extension not enabled.  "
                    "vkCreateHeadlessSurfaceEXT not executed!");
@@ -1226,22 +1408,21 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->headless_surf.base), sizeof(icd_surface->headless_surf),
+                                         pAllocator, &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateHeadlessSurfaceEXT) {
-                result = icd_term->dispatch.CreateHeadlessSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
-                                                                     &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->headless_surf.base.platform = VK_ICD_WSI_PLATFORM_HEADLESS;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT, sizeof(VkHeadlessSurfaceCreateInfoEXT)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkHeadlessSurfaceCreateInfoEXT", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
 
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
@@ -1307,7 +1488,7 @@
 
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_macos_surface_enabled) {
+    if (!loader_inst->enabled_extensions.mvk_macos_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_MVK_macos_surface extension not enabled. vkCreateMacOSSurfaceMVK not executed!");
         result = VK_ERROR_EXTENSION_NOT_PRESENT;
@@ -1315,22 +1496,22 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->macos_surf.base), sizeof(icd_surface->macos_surf),
+                                         pAllocator, &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateMacOSSurfaceMVK) {
-                result = icd_term->dispatch.CreateMacOSSurfaceMVK(icd_term->instance, pCreateInfo, pAllocator,
-                                                                  &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->macos_surf.base.platform = VK_ICD_WSI_PLATFORM_MACOS;
+    icd_surface->macos_surf.pView = pCreateInfo->pView;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK, sizeof(VkMacOSSurfaceCreateInfoMVK)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkMacOSSurfaceCreateInfoMVK", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
 
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
@@ -1369,7 +1550,7 @@
 
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_ios_surface_enabled) {
+    if (!loader_inst->enabled_extensions.mvk_ios_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_MVK_ios_surface extension not enabled. vkCreateIOSSurfaceMVK not executed!");
         return VK_ERROR_EXTENSION_NOT_PRESENT;
@@ -1421,7 +1602,7 @@
 
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_ggp_surface_enabled) {
+    if (!loader_inst->enabled_extensions.wsi_ggp_surface_enabled) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_GGP_stream_descriptor_surface extension not enabled. vkCreateStreamDescriptorSurfaceGGP not executed!");
         result = VK_ERROR_EXTENSION_NOT_PRESENT;
@@ -1429,22 +1610,22 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->ggp_surf.base), sizeof(icd_surface->ggp_surf), pAllocator,
+                                         &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateStreamDescriptorSurfaceGGP) {
-                result = icd_term->dispatch.CreateStreamDescriptorSurfaceGGP(
-                    icd_term->instance, pCreateInfo, pAllocator, &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->ggp_surf.base.platform = VK_ICD_WSI_PLATFORM_GGP;
+    icd_surface->ggp_surf.streamDescriptor = pCreateInfo->streamDescriptor;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP, sizeof(VkStreamDescriptorSurfaceCreateInfoGGP)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkStreamDescriptorSurfaceCreateInfoGGP", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
 
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
@@ -1481,29 +1662,30 @@
 
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_metal_surface_enabled) {
+    if (!loader_inst->enabled_extensions.ext_metal_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_EXT_metal_surface extension not enabled. vkCreateMetalSurfaceEXT will not be executed.");
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->metal_surf.base), sizeof(icd_surface->metal_surf),
+                                         pAllocator, &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateMetalSurfaceEXT) {
-                result = icd_term->dispatch.CreateMetalSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
-                                                                  &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->metal_surf.base.platform = VK_ICD_WSI_PLATFORM_METAL;
+    icd_surface->metal_surf.pLayer = pCreateInfo->pLayer;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT, sizeof(VkMetalSurfaceCreateInfoEXT)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkMetalSurfaceCreateInfoEXT", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
+
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
 
 out:
@@ -1541,7 +1723,7 @@
 
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_screen_surface_enabled) {
+    if (!loader_inst->enabled_extensions.qnx_screen_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_QNX_screen_surface extension not enabled. vkCreateScreenSurfaceQNX not executed!");
         result = VK_ERROR_EXTENSION_NOT_PRESENT;
@@ -1549,22 +1731,23 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->screen_surf.base), sizeof(icd_surface->screen_surf),
+                                         pAllocator, &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateScreenSurfaceQNX) {
-                result = icd_term->dispatch.CreateScreenSurfaceQNX(icd_term->instance, pCreateInfo, pAllocator,
-                                                                   &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->screen_surf.base.platform = VK_ICD_WSI_PLATFORM_SCREEN;
+    icd_surface->screen_surf.context = pCreateInfo->context;
+    icd_surface->screen_surf.window = pCreateInfo->window;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX, sizeof(VkScreenSurfaceCreateInfoQNX)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkScreenSurfaceCreateInfoQNX", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
 
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
@@ -1602,7 +1785,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_screen_surface_enabled) {
+    if (!loader_inst->enabled_extensions.qnx_screen_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_QNX_screen_surface extension not enabled. vkGetPhysicalDeviceScreenPresentationSupportQNX not executed!");
         return VK_FALSE;
@@ -1644,7 +1827,7 @@
 
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_vi_surface_enabled) {
+    if (!loader_inst->enabled_extensions.nn_vi_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_NN_vi_surface extension not enabled. vkCreateViSurfaceNN not executed!");
         result = VK_ERROR_EXTENSION_NOT_PRESENT;
@@ -1652,22 +1835,22 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->vi_surf.base), sizeof(icd_surface->vi_surf), pAllocator,
+                                         &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateViSurfaceNN) {
-                result = icd_term->dispatch.CreateViSurfaceNN(icd_term->instance, pCreateInfo, pAllocator,
-                                                              &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->vi_surf.base.platform = VK_ICD_WSI_PLATFORM_VI;
+    icd_surface->vi_surf.window = pCreateInfo->window;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN, sizeof(VkViSurfaceCreateInfoNN)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkViSurfaceCreateInfoNN", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
 
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
@@ -1705,7 +1888,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_display_enabled) {
+    if (!loader_inst->enabled_extensions.khr_display) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPropertiesKHR not executed!");
         return VK_SUCCESS;
@@ -1746,7 +1929,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_display_enabled) {
+    if (!loader_inst->enabled_extensions.khr_display) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPlanePropertiesKHR not executed!");
         return VK_SUCCESS;
@@ -1787,7 +1970,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_display_enabled) {
+    if (!loader_inst->enabled_extensions.khr_display) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_display extension not enabled. vkGetDisplayPlaneSupportedDisplaysKHR not executed!");
         return VK_SUCCESS;
@@ -1829,7 +2012,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_display_enabled) {
+    if (!loader_inst->enabled_extensions.khr_display) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_display extension not enabled. vkGetDisplayModePropertiesKHR not executed!");
         return VK_SUCCESS;
@@ -1872,7 +2055,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_display_enabled) {
+    if (!loader_inst->enabled_extensions.khr_display) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_display extension not enabled. vkCreateDisplayModeKHR not executed!");
         return VK_ERROR_EXTENSION_NOT_PRESENT;
@@ -1911,7 +2094,7 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    if (!loader_inst->wsi_display_enabled) {
+    if (!loader_inst->enabled_extensions.khr_display) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_display extension not enabled. vkGetDisplayPlaneCapabilitiesKHR not executed!");
         return VK_SUCCESS;
@@ -1954,30 +2137,37 @@
 
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_display_enabled) {
+    if (!loader_inst->enabled_extensions.khr_display) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
-                   "VK_KHR_surface extension not enabled. vkCreateDisplayPlaneSurfaceKHR not executed!");
+                   "VK_KHR_display extension not enabled. vkCreateDisplayPlaneSurfaceKHR not executed!");
         result = VK_ERROR_EXTENSION_NOT_PRESENT;
         goto out;
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->display_surf.base), sizeof(icd_surface->display_surf),
+                                         pAllocator, &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateDisplayPlaneSurfaceKHR) {
-                result = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
-                                                                         &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->display_surf.base.platform = VK_ICD_WSI_PLATFORM_DISPLAY;
+    icd_surface->display_surf.displayMode = pCreateInfo->displayMode;
+    icd_surface->display_surf.planeIndex = pCreateInfo->planeIndex;
+    icd_surface->display_surf.planeStackIndex = pCreateInfo->planeStackIndex;
+    icd_surface->display_surf.transform = pCreateInfo->transform;
+    icd_surface->display_surf.globalAlpha = pCreateInfo->globalAlpha;
+    icd_surface->display_surf.alphaMode = pCreateInfo->alphaMode;
+    icd_surface->display_surf.imageExtent = pCreateInfo->imageExtent;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR, sizeof(VkDisplaySurfaceCreateInfoKHR)},
+        {VK_STRUCTURE_TYPE_DISPLAY_SURFACE_STEREO_CREATE_INFO_NV, sizeof(VkDisplaySurfaceStereoCreateInfoNV)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkDisplaySurfaceCreateInfoKHR", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
 
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
@@ -2036,10 +2226,9 @@
     }
     memcpy(pCreateCopy, pCreateInfos, sizeof(VkSwapchainCreateInfoKHR) * swapchainCount);
     for (uint32_t sc = 0; sc < swapchainCount; sc++) {
-        VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateCopy[sc].surface;
-        if (icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-            icd_term->surface_list.list[icd_surface->surface_index]) {
-            pCreateCopy[sc].surface = icd_term->surface_list.list[icd_surface->surface_index];
+        VkResult res = wsi_unwrap_icd_surface(icd_term, &pCreateCopy[sc].surface);
+        if (res != VK_SUCCESS) {
+            return res;
         }
     }
     return dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateCopy,
@@ -2087,13 +2276,12 @@
                    "extensions enabled when using Vulkan 1.0?");
         return VK_SUCCESS;
     }
-    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
-    if (NULL != icd_term->surface_list.list &&
-        icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-        icd_term->surface_list.list[icd_surface->surface_index]) {
-        return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR(
-            device, icd_term->surface_list.list[icd_surface->surface_index], pModes);
+
+    VkResult res = wsi_unwrap_icd_surface(icd_term, &surface);
+    if (res != VK_SUCCESS) {
+        return res;
     }
+
     return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
 }
 
@@ -2126,13 +2314,12 @@
         }
         return VK_SUCCESS;
     }
-    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface);
-    if (NULL != icd_term->surface_list.list &&
-        icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-        icd_term->surface_list.list[icd_surface->surface_index]) {
-        return icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR(
-            phys_dev_term->phys_dev, icd_term->surface_list.list[icd_surface->surface_index], pRectCount, pRects);
+
+    VkResult res = wsi_unwrap_icd_surface(icd_term, &surface);
+    if (res != VK_SUCCESS) {
+        return res;
     }
+
     return icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR(phys_dev_term->phys_dev, surface, pRectCount, pRects);
 }
 
@@ -2389,7 +2576,7 @@
     *pSurface = VK_NULL_HANDLE;
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *loader_inst = loader_get_instance(instance);
-    if (!loader_inst->wsi_imagepipe_surface_enabled) {
+    if (!loader_inst->enabled_extensions.fuchsia_imagepipe_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_FUCHSIA_imagepipe_surface extension not enabled.  "
                    "vkCreateImagePipeSurfaceFUCHSIA not executed!");
@@ -2398,22 +2585,21 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    result = allocate_icd_surface_struct(loader_inst, pAllocator, &icd_surface);
+    result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->imagepipe_surf.base), sizeof(icd_surface->imagepipe_surf),
+                                         pAllocator, &icd_surface);
     if (VK_SUCCESS != result) {
         goto out;
     }
 
-    // Loop through each ICD and determine if they need to create a surface
-    for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
-        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-            if (NULL != icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA) {
-                result = icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA(icd_term->instance, pCreateInfo, pAllocator,
-                                                                          &icd_term->surface_list.list[icd_surface->surface_index]);
-                if (VK_SUCCESS != result) {
-                    goto out;
-                }
-            }
-        }
+    icd_surface->imagepipe_surf.base.platform = VK_ICD_WSI_PLATFORM_FUCHSIA;
+
+    const struct loader_struct_type_info ci_types[] = {
+        {VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA, sizeof(VkImagePipeSurfaceCreateInfoFUCHSIA)},
+    };
+    result = copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types,
+                                      "VkImagePipeSurfaceCreateInfoFUCHSIA", pAllocator);
+    if (VK_SUCCESS != result) {
+        goto out;
     }
 
     *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
@@ -2440,54 +2626,54 @@
     return disp->GetPhysicalDeviceSurfaceCapabilities2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceCapabilities);
 }
 
-void emulate_VK_EXT_surface_maintenance1(struct loader_icd_term *icd_term, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
+void emulate_VK_KHR_surface_maintenance1(const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
                                          VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
-    // Because VK_EXT_surface_maintenance1 is an instance extension, applications will use it to query info on drivers which do
+    // Because VK_KHR_surface_maintenance1 is an instance extension, applications will use it to query info on drivers which do
     // not support the extension. Thus we need to emulate the driver filling out the structs in that case.
-    if (!icd_term->supports_ext_surface_maintenance_1) {
-        VkPresentModeKHR present_mode = VK_PRESENT_MODE_MAX_ENUM_KHR;
-        const void *void_pNext = pSurfaceInfo->pNext;
-        while (void_pNext) {
-            VkBaseOutStructure out_structure = {0};
-            memcpy(&out_structure, void_pNext, sizeof(VkBaseOutStructure));
-            if (out_structure.sType == VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_EXT) {
-                VkSurfacePresentModeEXT *surface_present_mode = (VkSurfacePresentModeEXT *)void_pNext;
-                present_mode = surface_present_mode->presentMode;
-            }
-            void_pNext = out_structure.pNext;
+    VkPresentModeKHR present_mode = VK_PRESENT_MODE_MAX_ENUM_KHR;
+    const void *void_pNext = pSurfaceInfo->pNext;
+    while (void_pNext) {
+        VkBaseOutStructure out_structure = {0};
+        memcpy(&out_structure, void_pNext, sizeof(VkBaseOutStructure));
+        if (out_structure.sType == VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_KHR) {
+            VkSurfacePresentModeKHR *surface_present_mode = (VkSurfacePresentModeKHR *)void_pNext;
+            present_mode = surface_present_mode->presentMode;
         }
-        // If no VkSurfacePresentModeEXT was present, return
-        if (present_mode == VK_PRESENT_MODE_MAX_ENUM_KHR) {
-            return;
-        }
+        void_pNext = out_structure.pNext;
+    }
+    // If no VkSurfacePresentModeKHR was present, return
+    if (present_mode == VK_PRESENT_MODE_MAX_ENUM_KHR) {
+        return;
+    }
 
-        void_pNext = pSurfaceCapabilities->pNext;
-        while (void_pNext) {
-            VkBaseOutStructure out_structure = {0};
-            memcpy(&out_structure, void_pNext, sizeof(VkBaseOutStructure));
-            if (out_structure.sType == VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_EXT) {
-                VkSurfacePresentModeCompatibilityEXT *surface_present_mode_compatibility =
-                    (VkSurfacePresentModeCompatibilityEXT *)void_pNext;
-                if (surface_present_mode_compatibility->pPresentModes) {
+    void_pNext = pSurfaceCapabilities->pNext;
+    while (void_pNext) {
+        VkBaseOutStructure out_structure = {0};
+        memcpy(&out_structure, void_pNext, sizeof(VkBaseOutStructure));
+        if (out_structure.sType == VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_KHR) {
+            VkSurfacePresentModeCompatibilityKHR *surface_present_mode_compatibility =
+                (VkSurfacePresentModeCompatibilityKHR *)void_pNext;
+            if (surface_present_mode_compatibility->pPresentModes) {
+                if (surface_present_mode_compatibility->presentModeCount != 0) {
                     surface_present_mode_compatibility->pPresentModes[0] = present_mode;
+                    surface_present_mode_compatibility->presentModeCount = 1;
                 }
+            } else {
                 surface_present_mode_compatibility->presentModeCount = 1;
-
-            } else if (out_structure.sType == VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT) {
-                // Because there is no way to fill out the information faithfully, set scaled max/min image extent to the
-                // surface capabilities max/min extent and the rest to zero.
-                VkSurfacePresentScalingCapabilitiesEXT *surface_present_scaling_capabilities =
-                    (VkSurfacePresentScalingCapabilitiesEXT *)void_pNext;
-                surface_present_scaling_capabilities->supportedPresentScaling = 0;
-                surface_present_scaling_capabilities->supportedPresentGravityX = 0;
-                surface_present_scaling_capabilities->supportedPresentGravityY = 0;
-                surface_present_scaling_capabilities->maxScaledImageExtent =
-                    pSurfaceCapabilities->surfaceCapabilities.maxImageExtent;
-                surface_present_scaling_capabilities->minScaledImageExtent =
-                    pSurfaceCapabilities->surfaceCapabilities.minImageExtent;
             }
-            void_pNext = out_structure.pNext;
+
+        } else if (out_structure.sType == VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_KHR) {
+            // Because there is no way to fill out the information faithfully, set scaled max/min image extent to the
+            // surface capabilities max/min extent and the rest to zero.
+            VkSurfacePresentScalingCapabilitiesKHR *surface_present_scaling_capabilities =
+                (VkSurfacePresentScalingCapabilitiesKHR *)void_pNext;
+            surface_present_scaling_capabilities->supportedPresentScaling = 0;
+            surface_present_scaling_capabilities->supportedPresentGravityX = 0;
+            surface_present_scaling_capabilities->supportedPresentGravityY = 0;
+            surface_present_scaling_capabilities->maxScaledImageExtent = pSurfaceCapabilities->surfaceCapabilities.maxImageExtent;
+            surface_present_scaling_capabilities->minScaledImageExtent = pSurfaceCapabilities->surfaceCapabilities.minImageExtent;
         }
+        void_pNext = out_structure.pNext;
     }
 }
 
@@ -2497,14 +2683,21 @@
     struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
-    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface;
 
-    if (!loader_inst->wsi_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceCapabilities2KHR not executed!");
         return VK_SUCCESS;
     }
 
+    VkSurfaceKHR surface = pSurfaceInfo->surface;
+    if (VK_NULL_HANDLE != pSurfaceInfo->surface) {
+        VkResult res = wsi_unwrap_icd_surface(icd_term, &surface);
+        if (res != VK_SUCCESS) {
+            return res;
+        }
+    }
+
     if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR != NULL) {
         void *pNext = pSurfaceCapabilities->pNext;
         while (pNext != NULL) {
@@ -2519,25 +2712,18 @@
             pNext = pNext_out_structure.pNext;
         }
 
-        VkResult res = VK_SUCCESS;
-
         // Pass the call to the driver, possibly unwrapping the ICD surface
-        if (NULL != icd_term->surface_list.list &&
-            icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-            icd_term->surface_list.list[icd_surface->surface_index]) {
-            VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
-            info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index];
-            res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, &info_copy,
-                                                                              pSurfaceCapabilities);
-        } else {
-            res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
-                                                                              pSurfaceCapabilities);
-        }
+        VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
+        info_copy.surface = surface;
+
+        VkResult res =
+            icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceCapabilities);
 
         // Because VK_EXT_surface_maintenance1 is an instance extension, applications will use it to query info on drivers which do
         // not support the extension. Thus we need to emulate the driver filling out the structs in that case.
-        if (!icd_term->supports_ext_surface_maintenance_1) {
-            emulate_VK_EXT_surface_maintenance1(icd_term, pSurfaceInfo, pSurfaceCapabilities);
+        if (!icd_term->enabled_instance_extensions.khr_surface_maintenance1 &&
+            !icd_term->enabled_instance_extensions.ext_surface_maintenance1) {
+            emulate_VK_KHR_surface_maintenance1(pSurfaceInfo, pSurfaceCapabilities);
         }
 
         return res;
@@ -2549,12 +2735,6 @@
                    icd_term->scanned_icd->lib_name);
 
         // Write to the VkSurfaceCapabilities2KHR struct
-        VkSurfaceKHR surface = pSurfaceInfo->surface;
-        if (NULL != icd_term->surface_list.list &&
-            icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-            icd_term->surface_list.list[icd_surface->surface_index]) {
-            surface = icd_term->surface_list.list[icd_surface->surface_index];
-        }
 
         // If the icd doesn't support VK_KHR_surface, then there are no capabilities
         if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR) {
@@ -2566,7 +2746,10 @@
         VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface,
                                                                                   &pSurfaceCapabilities->surfaceCapabilities);
 
-        emulate_VK_EXT_surface_maintenance1(icd_term, pSurfaceInfo, pSurfaceCapabilities);
+        if (!icd_term->enabled_instance_extensions.khr_surface_maintenance1 &&
+            !icd_term->enabled_instance_extensions.ext_surface_maintenance1) {
+            emulate_VK_KHR_surface_maintenance1(pSurfaceInfo, pSurfaceCapabilities);
+        }
         return res;
     }
 }
@@ -2594,27 +2777,27 @@
     struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
     struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
 
-    if (!loader_inst->wsi_surface_enabled) {
+    if (!loader_inst->enabled_extensions.khr_surface) {
         loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
                    "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceFormats2KHR not executed!");
         return VK_SUCCESS;
     }
 
-    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
+    VkSurfaceKHR surface = pSurfaceInfo->surface;
+    if (VK_NULL_HANDLE != pSurfaceInfo->surface) {
+        VkResult res = wsi_unwrap_icd_surface(icd_term, &surface);
+        if (res != VK_SUCCESS) {
+            return res;
+        }
+    }
 
     if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) {
         // Pass the call to the driver, possibly unwrapping the ICD surface
-        if (NULL != icd_term->surface_list.list &&
-            icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-            icd_term->surface_list.list[icd_surface->surface_index]) {
-            VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
-            info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index];
-            return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceFormatCount,
-                                                                          pSurfaceFormats);
-        } else {
-            return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
-                                                                          pSurfaceFormatCount, pSurfaceFormats);
-        }
+        VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
+        info_copy.surface = surface;
+
+        return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceFormatCount,
+                                                                      pSurfaceFormats);
     } else {
         // Emulate the call
         loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
@@ -2627,13 +2810,6 @@
                        "- this struct will be ignored");
         }
 
-        VkSurfaceKHR surface = pSurfaceInfo->surface;
-        if (NULL != icd_term->surface_list.list &&
-            icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
-            icd_term->surface_list.list[icd_surface->surface_index]) {
-            surface = icd_term->surface_list.list[icd_surface->surface_index];
-        }
-
         // If the icd doesn't support VK_KHR_surface, then there are no formats
         if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR) {
             if (pSurfaceFormatCount) {
@@ -2674,49 +2850,49 @@
 
     // Functions for the VK_KHR_surface extension:
     if (!strcmp("vkDestroySurfaceKHR", name)) {
-        *addr = loader_inst->wsi_surface_enabled ? (void *)vkDestroySurfaceKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_surface ? (void *)vkDestroySurfaceKHR : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name)) {
-        *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceSupportKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_surface ? (void *)vkGetPhysicalDeviceSurfaceSupportKHR : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name)) {
-        *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilitiesKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_surface ? (void *)vkGetPhysicalDeviceSurfaceCapabilitiesKHR : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name)) {
-        *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormatsKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_surface ? (void *)vkGetPhysicalDeviceSurfaceFormatsKHR : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name)) {
-        *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfacePresentModesKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_surface ? (void *)vkGetPhysicalDeviceSurfacePresentModesKHR : NULL;
         return true;
     }
 
     if (!strcmp("vkGetDeviceGroupPresentCapabilitiesKHR", name)) {
-        *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetDeviceGroupPresentCapabilitiesKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_surface ? (void *)vkGetDeviceGroupPresentCapabilitiesKHR : NULL;
         return true;
     }
 
     if (!strcmp("vkGetDeviceGroupSurfacePresentModesKHR", name)) {
-        *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetDeviceGroupSurfacePresentModesKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_surface ? (void *)vkGetDeviceGroupSurfacePresentModesKHR : NULL;
         return true;
     }
 
     if (!strcmp("vkGetPhysicalDevicePresentRectanglesKHR", name)) {
-        *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDevicePresentRectanglesKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_surface ? (void *)vkGetPhysicalDevicePresentRectanglesKHR : NULL;
         return true;
     }
 
     // Functions for VK_KHR_get_surface_capabilities2 extension:
     if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilities2KHR", name)) {
-        *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilities2KHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_surface ? (void *)vkGetPhysicalDeviceSurfaceCapabilities2KHR : NULL;
         return true;
     }
 
     if (!strcmp("vkGetPhysicalDeviceSurfaceFormats2KHR", name)) {
-        *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormats2KHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_surface ? (void *)vkGetPhysicalDeviceSurfaceFormats2KHR : NULL;
         return true;
     }
 
@@ -2755,11 +2931,11 @@
 
     // Functions for the VK_KHR_win32_surface extension:
     if (!strcmp("vkCreateWin32SurfaceKHR", name)) {
-        *addr = loader_inst->wsi_win32_surface_enabled ? (void *)vkCreateWin32SurfaceKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_win32_surface ? (void *)vkCreateWin32SurfaceKHR : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", name)) {
-        *addr = loader_inst->wsi_win32_surface_enabled ? (void *)vkGetPhysicalDeviceWin32PresentationSupportKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_win32_surface ? (void *)vkGetPhysicalDeviceWin32PresentationSupportKHR : NULL;
         return true;
     }
 #endif  // VK_USE_PLATFORM_WIN32_KHR
@@ -2767,11 +2943,12 @@
 
     // Functions for the VK_KHR_wayland_surface extension:
     if (!strcmp("vkCreateWaylandSurfaceKHR", name)) {
-        *addr = loader_inst->wsi_wayland_surface_enabled ? (void *)vkCreateWaylandSurfaceKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_wayland_surface ? (void *)vkCreateWaylandSurfaceKHR : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", name)) {
-        *addr = loader_inst->wsi_wayland_surface_enabled ? (void *)vkGetPhysicalDeviceWaylandPresentationSupportKHR : NULL;
+        *addr =
+            loader_inst->enabled_extensions.khr_wayland_surface ? (void *)vkGetPhysicalDeviceWaylandPresentationSupportKHR : NULL;
         return true;
     }
 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
@@ -2779,11 +2956,11 @@
 
     // Functions for the VK_KHR_xcb_surface extension:
     if (!strcmp("vkCreateXcbSurfaceKHR", name)) {
-        *addr = loader_inst->wsi_xcb_surface_enabled ? (void *)vkCreateXcbSurfaceKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_xcb_surface ? (void *)vkCreateXcbSurfaceKHR : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", name)) {
-        *addr = loader_inst->wsi_xcb_surface_enabled ? (void *)vkGetPhysicalDeviceXcbPresentationSupportKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_xcb_surface ? (void *)vkGetPhysicalDeviceXcbPresentationSupportKHR : NULL;
         return true;
     }
 #endif  // VK_USE_PLATFORM_XCB_KHR
@@ -2791,11 +2968,11 @@
 
     // Functions for the VK_KHR_xlib_surface extension:
     if (!strcmp("vkCreateXlibSurfaceKHR", name)) {
-        *addr = loader_inst->wsi_xlib_surface_enabled ? (void *)vkCreateXlibSurfaceKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_xlib_surface ? (void *)vkCreateXlibSurfaceKHR : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", name)) {
-        *addr = loader_inst->wsi_xlib_surface_enabled ? (void *)vkGetPhysicalDeviceXlibPresentationSupportKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_xlib_surface ? (void *)vkGetPhysicalDeviceXlibPresentationSupportKHR : NULL;
         return true;
     }
 #endif  // VK_USE_PLATFORM_XLIB_KHR
@@ -2803,11 +2980,12 @@
 
     // Functions for the VK_EXT_directfb_surface extension:
     if (!strcmp("vkCreateDirectFBSurfaceEXT", name)) {
-        *addr = loader_inst->wsi_directfb_surface_enabled ? (void *)vkCreateDirectFBSurfaceEXT : NULL;
+        *addr = loader_inst->enabled_extensions.ext_directfb_surface ? (void *)vkCreateDirectFBSurfaceEXT : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceDirectFBPresentationSupportEXT", name)) {
-        *addr = loader_inst->wsi_directfb_surface_enabled ? (void *)vkGetPhysicalDeviceDirectFBPresentationSupportEXT : NULL;
+        *addr =
+            loader_inst->enabled_extensions.ext_directfb_surface ? (void *)vkGetPhysicalDeviceDirectFBPresentationSupportEXT : NULL;
         return true;
     }
 #endif  // VK_USE_PLATFORM_DIRECTFB_EXT
@@ -2815,7 +2993,7 @@
 
     // Functions for the VK_KHR_android_surface extension:
     if (!strcmp("vkCreateAndroidSurfaceKHR", name)) {
-        *addr = loader_inst->wsi_android_surface_enabled ? (void *)vkCreateAndroidSurfaceKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_android_surface ? (void *)vkCreateAndroidSurfaceKHR : NULL;
         return true;
     }
 #endif  // VK_USE_PLATFORM_ANDROID_KHR
@@ -2824,7 +3002,7 @@
 
     // Functions for the VK_MVK_macos_surface extension:
     if (!strcmp("vkCreateMacOSSurfaceMVK", name)) {
-        *addr = loader_inst->wsi_macos_surface_enabled ? (void *)vkCreateMacOSSurfaceMVK : NULL;
+        *addr = loader_inst->enabled_extensions.mvk_macos_surface ? (void *)vkCreateMacOSSurfaceMVK : NULL;
         return true;
     }
 #endif  // VK_USE_PLATFORM_MACOS_MVK
@@ -2832,7 +3010,7 @@
 
     // Functions for the VK_MVK_ios_surface extension:
     if (!strcmp("vkCreateIOSSurfaceMVK", name)) {
-        *addr = loader_inst->wsi_ios_surface_enabled ? (void *)vkCreateIOSSurfaceMVK : NULL;
+        *addr = loader_inst->enabled_extensions.mvk_ios_surface ? (void *)vkCreateIOSSurfaceMVK : NULL;
         return true;
     }
 #endif  // VK_USE_PLATFORM_IOS_MVK
@@ -2840,7 +3018,7 @@
 
     // Functions for the VK_GGP_stream_descriptor_surface extension:
     if (!strcmp("vkCreateStreamDescriptorSurfaceGGP", name)) {
-        *addr = loader_inst->wsi_ggp_surface_enabled ? (void *)vkCreateStreamDescriptorSurfaceGGP : NULL;
+        *addr = loader_inst->enabled_extensions.wsi_ggp_surface_enabled ? (void *)vkCreateStreamDescriptorSurfaceGGP : NULL;
         return true;
     }
 #endif  // VK_USE_PLATFORM_GGP
@@ -2848,7 +3026,7 @@
 
     // Functions for the VK_FUCHSIA_imagepipe_surface extension:
     if (!strcmp("vkCreateImagePipeSurfaceFUCHSIA", name)) {
-        *addr = loader_inst->wsi_imagepipe_surface_enabled ? (void *)vkCreateImagePipeSurfaceFUCHSIA : NULL;
+        *addr = loader_inst->enabled_extensions.fuchsia_imagepipe_surface ? (void *)vkCreateImagePipeSurfaceFUCHSIA : NULL;
         return true;
     }
 
@@ -2856,14 +3034,14 @@
 
     // Functions for the VK_EXT_headless_surface extension:
     if (!strcmp("vkCreateHeadlessSurfaceEXT", name)) {
-        *addr = loader_inst->wsi_headless_surface_enabled ? (void *)vkCreateHeadlessSurfaceEXT : NULL;
+        *addr = loader_inst->enabled_extensions.ext_headless_surface ? (void *)vkCreateHeadlessSurfaceEXT : NULL;
         return true;
     }
 
 #if defined(VK_USE_PLATFORM_METAL_EXT)
     // Functions for the VK_MVK_macos_surface extension:
     if (!strcmp("vkCreateMetalSurfaceEXT", name)) {
-        *addr = loader_inst->wsi_metal_surface_enabled ? (void *)vkCreateMetalSurfaceEXT : NULL;
+        *addr = loader_inst->enabled_extensions.ext_metal_surface ? (void *)vkCreateMetalSurfaceEXT : NULL;
         return true;
     }
 #endif  // VK_USE_PLATFORM_METAL_EXT
@@ -2872,11 +3050,11 @@
 
     // Functions for the VK_QNX_screen_surface extension:
     if (!strcmp("vkCreateScreenSurfaceQNX", name)) {
-        *addr = loader_inst->wsi_screen_surface_enabled ? (void *)vkCreateScreenSurfaceQNX : NULL;
+        *addr = loader_inst->enabled_extensions.qnx_screen_surface ? (void *)vkCreateScreenSurfaceQNX : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceScreenPresentationSupportQNX", name)) {
-        *addr = loader_inst->wsi_screen_surface_enabled ? (void *)vkGetPhysicalDeviceScreenPresentationSupportQNX : NULL;
+        *addr = loader_inst->enabled_extensions.qnx_screen_surface ? (void *)vkGetPhysicalDeviceScreenPresentationSupportQNX : NULL;
         return true;
     }
 #endif  // VK_USE_PLATFORM_SCREEN_QNX
@@ -2885,38 +3063,38 @@
 
     // Functions for the VK_NN_vi_surface extension:
     if (!strcmp("vkCreateViSurfaceNN", name)) {
-        *addr = loader_inst->wsi_vi_surface_enabled ? (void *)vkCreateViSurfaceNN : NULL;
+        *addr = loader_inst->enabled_extensions.nn_vi_surface ? (void *)vkCreateViSurfaceNN : NULL;
         return true;
     }
 #endif  // VK_USE_PLATFORM_VI_NN
 
     // Functions for VK_KHR_display extension:
     if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name)) {
-        *addr = loader_inst->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_display ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceDisplayPlanePropertiesKHR", name)) {
-        *addr = loader_inst->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPlanePropertiesKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_display ? (void *)vkGetPhysicalDeviceDisplayPlanePropertiesKHR : NULL;
         return true;
     }
     if (!strcmp("vkGetDisplayPlaneSupportedDisplaysKHR", name)) {
-        *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayPlaneSupportedDisplaysKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_display ? (void *)vkGetDisplayPlaneSupportedDisplaysKHR : NULL;
         return true;
     }
     if (!strcmp("vkGetDisplayModePropertiesKHR", name)) {
-        *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayModePropertiesKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_display ? (void *)vkGetDisplayModePropertiesKHR : NULL;
         return true;
     }
     if (!strcmp("vkCreateDisplayModeKHR", name)) {
-        *addr = loader_inst->wsi_display_enabled ? (void *)vkCreateDisplayModeKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_display ? (void *)vkCreateDisplayModeKHR : NULL;
         return true;
     }
     if (!strcmp("vkGetDisplayPlaneCapabilitiesKHR", name)) {
-        *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayPlaneCapabilitiesKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_display ? (void *)vkGetDisplayPlaneCapabilitiesKHR : NULL;
         return true;
     }
     if (!strcmp("vkCreateDisplayPlaneSurfaceKHR", name)) {
-        *addr = loader_inst->wsi_display_enabled ? (void *)vkCreateDisplayPlaneSurfaceKHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_display ? (void *)vkCreateDisplayPlaneSurfaceKHR : NULL;
         return true;
     }
 
@@ -2928,19 +3106,21 @@
 
     // Functions for KHR_get_display_properties2
     if (!strcmp("vkGetPhysicalDeviceDisplayProperties2KHR", name)) {
-        *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetPhysicalDeviceDisplayProperties2KHR : NULL;
+        *addr =
+            loader_inst->enabled_extensions.khr_get_display_properties2 ? (void *)vkGetPhysicalDeviceDisplayProperties2KHR : NULL;
         return true;
     }
     if (!strcmp("vkGetPhysicalDeviceDisplayPlaneProperties2KHR", name)) {
-        *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetPhysicalDeviceDisplayPlaneProperties2KHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_get_display_properties2 ? (void *)vkGetPhysicalDeviceDisplayPlaneProperties2KHR
+                                                                            : NULL;
         return true;
     }
     if (!strcmp("vkGetDisplayModeProperties2KHR", name)) {
-        *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetDisplayModeProperties2KHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_get_display_properties2 ? (void *)vkGetDisplayModeProperties2KHR : NULL;
         return true;
     }
     if (!strcmp("vkGetDisplayPlaneCapabilities2KHR", name)) {
-        *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetDisplayPlaneCapabilities2KHR : NULL;
+        *addr = loader_inst->enabled_extensions.khr_get_display_properties2 ? (void *)vkGetDisplayPlaneCapabilities2KHR : NULL;
         return true;
     }
 
diff --git a/loader/wsi.h b/loader/wsi.h
index c2ec9af..c259f3b 100644
--- a/loader/wsi.h
+++ b/loader/wsi.h
@@ -25,12 +25,74 @@
 #include "loader_common.h"
 
 typedef struct {
-    uint32_t surface_index;  // This surface's index into each drivers list of created surfaces
+    // This union holds the data that drivers which use ICD interface version 2 and before expect. This is so they can dereference
+    // VkSurfaceKHR to get this struct and access the creation parameters used in subsequent API calls, such as get surface formats
+    // & get surface present modes.
+    // Thus, these members need to stay here in order to preserve ABI compatibility.
+    union {
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+        VkIcdSurfaceWayland wayland_surf;
+#endif  // VK_USE_PLATFORM_WAYLAND_KHR
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+        VkIcdSurfaceWin32 win_surf;
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+        VkIcdSurfaceXcb xcb_surf;
+#endif  // VK_USE_PLATFORM_XCB_KHR
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+        VkIcdSurfaceXlib xlib_surf;
+#endif  // VK_USE_PLATFORM_XLIB_KHR
+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+        VkIcdSurfaceDirectFB directfb_surf;
+#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
+#if defined(VK_USE_PLATFORM_MACOS_MVK)
+        VkIcdSurfaceMacOS macos_surf;
+#endif  // VK_USE_PLATFORM_MACOS_MVK
+#if defined(VK_USE_PLATFORM_GGP)
+        VkIcdSurfaceGgp ggp_surf;
+#endif  // VK_USE_PLATFORM_GGP
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+        VkIcdSurfaceImagePipe imagepipe_surf;
+#endif  // VK_USE_PLATFORM_FUCHSIA
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+        VkIcdSurfaceMetal metal_surf;
+#endif  // VK_USE_PLATFORM_METAL_EXT
+#if defined(VK_USE_PLATFORM_SCREEN_QNX)
+        VkIcdSurfaceScreen screen_surf;
+#endif  // VK_USE_PLATFORM_SCREEN_QNX
+#if defined(VK_USE_PLATFORM_VI_NN)
+        VkIcdSurfaceVi vi_surf;
+#endif  // VK_USE_PLATFORM_VI_NN
+        VkIcdSurfaceDisplay display_surf;
+        VkIcdSurfaceHeadless headless_surf;
+
+        // All of the specific ICD surface structures start with the base structure
+        VkIcdSurfaceBase base;
+    };
+    uint32_t base_size;            // Size of VkIcdSurfaceBase
+    uint32_t platform_size;        // Size of corresponding VkIcdSurfaceXXX
+    uint32_t non_platform_offset;  // Start offset to base_size
+    uint32_t entire_size;          // Size of entire VkIcdSurface
+    uint32_t surface_index;        // This surface's index into each drivers list of created surfaces
+
+    bool callbacks_valid;             // Need to store if a VkAllocationCallbacks pointer was used.
+    VkAllocationCallbacks callbacks;  // Storage for the callbacks
+
+    // The create info parameters captured by the union in VkIcdSurface are insufficient, as they do not
+    // capture every single parameter from the create info (e.g. flags that did not have any flags defined
+    // at the time) and they also cannot capture extension structures, so we are including a separate
+    // pointer that will hold a copy of the original creation structure chain. This chain can only capture
+    // known extension structures and preferably should be auto-generated, but the list of extension
+    // structures is rather limited (there is only a single display surface creation structure extension
+    // at the time of writing).
+    uint8_t *create_info;
+
 } VkIcdSurface;
 
+VkResult wsi_unwrap_icd_surface(struct loader_icd_term *icd_term, VkSurfaceKHR *surface);
+
 bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr);
 
-void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo);
 bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop);
 
 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateHeadlessSurfaceEXT(VkInstance instance,
diff --git a/scripts/common_codegen.py b/scripts/common_codegen.py
index 92ebb5a..860eea5 100644
--- a/scripts/common_codegen.py
+++ b/scripts/common_codegen.py
@@ -19,6 +19,8 @@
 # Author: Mark Lobodzinski <mark@lunarg.com>
 
 import os
+import sys
+import subprocess
 
 # Copyright text prefixing all headers (list of strings).
 prefixStrings = [
@@ -75,3 +77,34 @@
 # helper to define paths relative to the repo root
 def repo_relative(path):
     return os.path.abspath(os.path.join(os.path.dirname(__file__), '..', path))
+
+# Points to the directory containing the top level CMakeLists.txt
+PROJECT_SRC_DIR = os.path.abspath(os.path.join(os.path.split(os.path.abspath(__file__))[0], '..'))
+if not os.path.isfile(f'{PROJECT_SRC_DIR}/CMakeLists.txt'):
+    print(f'PROJECT_SRC_DIR invalid! {PROJECT_SRC_DIR}')
+    sys.exit(1)
+
+# Returns true if we are running in GitHub actions
+# https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables
+def IsGHA():
+    if 'GITHUB_ACTION' in os.environ:
+        return True
+    return False
+
+# Runs a command in a directory and returns its return code.
+# Directory is project root by default, or a relative path from project root
+def RunShellCmd(command, start_dir = PROJECT_SRC_DIR, env=None, verbose=False):
+    # Flush stdout here. Helps when debugging on CI.
+    sys.stdout.flush()
+
+    if start_dir != PROJECT_SRC_DIR:
+        start_dir = repo_relative(start_dir)
+    cmd_list = command.split(" ")
+
+    # Helps a lot when debugging CI issues
+    if IsGHA():
+        verbose = True
+
+    if verbose:
+        print(f'CICMD({cmd_list}, env={env})')
+    subprocess.check_call(cmd_list, cwd=start_dir, env=env)
diff --git a/scripts/dispatch_table_helper_generator.py b/scripts/dispatch_table_helper_generator.py
deleted file mode 100644
index 67af7be..0000000
--- a/scripts/dispatch_table_helper_generator.py
+++ /dev/null
@@ -1,236 +0,0 @@
-#!/usr/bin/python3 -i
-#
-# Copyright (c) 2015-2021 The Khronos Group Inc.
-# Copyright (c) 2015-2021 Valve Corporation
-# Copyright (c) 2015-2021 LunarG, Inc.
-# Copyright (c) 2015-2021 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Author: Mark Lobodzinski <mark@lunarg.com>
-
-import os,re,sys
-import xml.etree.ElementTree as etree
-from generator import *
-from collections import namedtuple
-from common_codegen import *
-
-return_type_table = {"VkResult": "VK_SUCCESS",
-                     "uint32_t": "0",
-                     "uint64_t": "0L",
-                     "VkDeviceAddress": "0L",
-                     "VkDeviceSize": "0L"}
-
-#
-# DispatchTableHelperOutputGeneratorOptions - subclass of GeneratorOptions.
-class DispatchTableHelperOutputGeneratorOptions(GeneratorOptions):
-    def __init__(self,
-                 conventions = None,
-                 filename = None,
-                 directory = '.',
-                 genpath = None,
-                 apiname = None,
-                 profile = None,
-                 versions = '.*',
-                 emitversions = '.*',
-                 defaultExtensions = None,
-                 addExtensions = None,
-                 removeExtensions = None,
-                 emitExtensions = None,
-                 sortProcedure = regSortFeatures,
-                 prefixText = "",
-                 genFuncPointers = True,
-                 apicall = '',
-                 apientry = '',
-                 apientryp = '',
-                 alignFuncParam = 0,
-                 expandEnumerants = True):
-        GeneratorOptions.__init__(self,
-                conventions = conventions,
-                filename = filename,
-                directory = directory,
-                genpath = genpath,
-                apiname = apiname,
-                profile = profile,
-                versions = versions,
-                emitversions = emitversions,
-                defaultExtensions = defaultExtensions,
-                addExtensions = addExtensions,
-                removeExtensions = removeExtensions,
-                emitExtensions = emitExtensions,
-                sortProcedure = sortProcedure)
-        self.prefixText      = prefixText
-        self.genFuncPointers = genFuncPointers
-        self.prefixText      = None
-        self.apicall         = apicall
-        self.apientry        = apientry
-        self.apientryp       = apientryp
-        self.alignFuncParam  = alignFuncParam
-#
-# DispatchTableHelperOutputGenerator - subclass of OutputGenerator.
-# Generates dispatch table helper header files for LVL
-class DispatchTableHelperOutputGenerator(OutputGenerator):
-    """Generate dispatch table helper header based on XML element attributes"""
-    def __init__(self,
-                 errFile = sys.stderr,
-                 warnFile = sys.stderr,
-                 diagFile = sys.stdout):
-        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
-        # Internal state - accumulators for different inner block text
-        self.instance_dispatch_list = []      # List of entries for instance dispatch list
-        self.device_dispatch_list = []        # List of entries for device dispatch list
-        self.dev_ext_stub_list = []           # List of stub functions for device extension functions
-        self.device_extension_list = []       # List of device extension functions
-        self.extension_type = ''
-    #
-    # Called once at the beginning of each run
-    def beginFile(self, genOpts):
-        OutputGenerator.beginFile(self, genOpts)
-        write("#pragma once", file=self.outFile)
-        # User-supplied prefix text, if any (list of strings)
-        if (genOpts.prefixText):
-            for s in genOpts.prefixText:
-                write(s, file=self.outFile)
-        # File Comment
-        file_comment = '// *** THIS FILE IS GENERATED - DO NOT EDIT ***\n'
-        file_comment += '// See dispatch_table_helper_generator.py for modifications\n'
-        write(file_comment, file=self.outFile)
-        # Copyright Notice
-        copyright =  '/*\n'
-        copyright += ' * Copyright (c) 2015-2021 The Khronos Group Inc.\n'
-        copyright += ' * Copyright (c) 2015-2021 Valve Corporation\n'
-        copyright += ' * Copyright (c) 2015-2021 LunarG, Inc.\n'
-        copyright += ' *\n'
-        copyright += ' * Licensed under the Apache License, Version 2.0 (the "License");\n'
-        copyright += ' * you may not use this file except in compliance with the License.\n'
-        copyright += ' * You may obtain a copy of the License at\n'
-        copyright += ' *\n'
-        copyright += ' *     http://www.apache.org/licenses/LICENSE-2.0\n'
-        copyright += ' *\n'
-        copyright += ' * Unless required by applicable law or agreed to in writing, software\n'
-        copyright += ' * distributed under the License is distributed on an "AS IS" BASIS,\n'
-        copyright += ' * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n'
-        copyright += ' * See the License for the specific language governing permissions and\n'
-        copyright += ' * limitations under the License.\n'
-        copyright += ' *\n'
-        copyright += ' * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>\n'
-        copyright += ' * Author: Jon Ashburn <jon@lunarg.com>\n'
-        copyright += ' * Author: Mark Lobodzinski <mark@lunarg.com>\n'
-        copyright += ' */\n'
-
-        preamble = ''
-        preamble += '#include <vulkan/vulkan.h>\n'
-        preamble += '#include <vulkan/vk_layer.h>\n'
-        preamble += '#include <string.h>\n'
-        preamble += '#include "loader/generated/vk_layer_dispatch_table.h"\n'
-
-        write(copyright, file=self.outFile)
-        write(preamble, file=self.outFile)
-    #
-    # Write generate and write dispatch tables to output file
-    def endFile(self):
-        device_table = ''
-        instance_table = ''
-
-        device_table += self.OutputDispatchTableHelper('device')
-        instance_table += self.OutputDispatchTableHelper('instance')
-
-        for stub in self.dev_ext_stub_list:
-            write(stub, file=self.outFile)
-        write("\n\n", file=self.outFile)
-        write(device_table, file=self.outFile);
-        write("\n", file=self.outFile)
-        write(instance_table, file=self.outFile);
-
-        # Finish processing in superclass
-        OutputGenerator.endFile(self)
-    #
-    # Processing at beginning of each feature or extension
-    def beginFeature(self, interface, emit):
-        OutputGenerator.beginFeature(self, interface, emit)
-        self.featureExtraProtect = GetFeatureProtect(interface)
-        self.extension_type = interface.get('type')
-
-    #
-    # Process commands, adding to appropriate dispatch tables
-    def genCmd(self, cmdinfo, name, alias):
-        OutputGenerator.genCmd(self, cmdinfo, name, alias)
-
-        avoid_entries = ['vkCreateInstance',
-                         'vkCreateDevice']
-        # Get first param type
-        params = cmdinfo.elem.findall('param')
-        info = self.getTypeNameTuple(params[0])
-
-        if name not in avoid_entries:
-            self.AddCommandToDispatchList(name, info[0], self.featureExtraProtect, cmdinfo)
-
-    #
-    # Determine if this API should be ignored or added to the instance or device dispatch table
-    def AddCommandToDispatchList(self, name, handle_type, protect, cmdinfo):
-        handle = self.registry.tree.find("types/type/[name='" + handle_type + "'][@category='handle']")
-        if handle is None:
-            return
-        if handle_type != 'VkInstance' and handle_type != 'VkPhysicalDevice' and name != 'vkGetInstanceProcAddr':
-            self.device_dispatch_list.append((name, self.featureExtraProtect))
-        else:
-            self.instance_dispatch_list.append((name, self.featureExtraProtect))
-        return
-    #
-    # Retrieve the type and name for a parameter
-    def getTypeNameTuple(self, param):
-        type = ''
-        name = ''
-        for elem in param:
-            if elem.tag == 'type':
-                type = noneStr(elem.text)
-            elif elem.tag == 'name':
-                name = noneStr(elem.text)
-        return (type, name)
-    #
-    # Create a dispatch table from the appropriate list and return it as a string
-    def OutputDispatchTableHelper(self, table_type):
-        entries = []
-        table = ''
-        if table_type == 'device':
-            entries = self.device_dispatch_list
-            table += 'static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDispatchTable *table, PFN_vkGetDeviceProcAddr gpa) {\n'
-            table += '    memset(table, 0, sizeof(*table));\n'
-            table += '    table->magic = DEVICE_DISP_TABLE_MAGIC_NUMBER;\n\n'
-            table += '    // Device function pointers\n'
-        else:
-            entries = self.instance_dispatch_list
-            table += 'static inline void layer_init_instance_dispatch_table(VkInstance instance, VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa) {\n'
-            table += '    memset(table, 0, sizeof(*table));\n\n'
-            table += '    // Instance function pointers\n'
-
-        for item in entries:
-            # Remove 'vk' from proto name
-            base_name = item[0][2:]
-
-            if item[1] is not None:
-                table += '#if defined(%s)\n' % item[1]
-
-            # If we're looking for the proc we are passing in, just point the table to it.  This fixes the issue where
-            # a layer overrides the function name for the loader.
-            if (table_type == 'device' and base_name == 'GetDeviceProcAddr'):
-                table += '    table->GetDeviceProcAddr = gpa;\n'
-            elif (table_type != 'device' and base_name == 'GetInstanceProcAddr'):
-                table += '    table->GetInstanceProcAddr = gpa;\n'
-            else:
-                table += '    table->%s = (PFN_%s) gpa(%s, "%s");\n' % (base_name, item[0], table_type, item[0])
-            if item[1] is not None:
-                table += '#endif // %s\n' % item[1]
-
-        table += '}'
-        return table
diff --git a/scripts/generate_source.py b/scripts/generate_source.py
index f1dbfc8..7af0479 100755
--- a/scripts/generate_source.py
+++ b/scripts/generate_source.py
@@ -21,17 +21,159 @@
 # Author: Mike Schuchardt <mikes@lunarg.com>
 
 import argparse
-import common_codegen
 import filecmp
 import os
-import shutil
 import subprocess
+import shutil
 import sys
 import tempfile
 import datetime
 import re
+import common_codegen
+
+from xml.etree import ElementTree
+
+# Because we have special logic to import the Registry from input arguments and the BaseGenerator comes from the registry, we have to delay defining it until *after*
+# the Registry has been imported. Yes this is awkward, but it was the least awkward way to make --verify work.
+generators = {}
+
+def RunGenerators(api: str, registry: str, directory: str, styleFile: str, targetFilter: str, flatOutput: bool):
+
+    try:
+        common_codegen.RunShellCmd(f'clang-format --version')
+        has_clang_format = True
+    except:
+        has_clang_format = False
+    if not has_clang_format:
+        print("WARNING: Unable to find clang-format!")
+
+    # These live in the Vulkan-Docs repo, but are pulled in via the
+    # Vulkan-Headers/registry folder
+    # At runtime we inject python path to find these helper scripts
+    scripts = os.path.dirname(registry)
+    scripts_directory_path = os.path.dirname(os.path.abspath(__file__))
+    registry_headers_path = os.path.join(scripts_directory_path, scripts)
+    sys.path.insert(0, registry_headers_path)
+    try:
+        from reg import Registry
+    except:
+        print("ModuleNotFoundError: No module named 'reg'") # normal python error message
+        print(f'{registry_headers_path} is not pointing to the Vulkan-Headers registry directory.')
+        print("Inside Vulkan-Headers there is a registry/reg.py file that is used.")
+        sys.exit(1) # Return without call stack so easy to spot error
+
+    from base_generator import BaseGeneratorOptions
+    from generators.dispatch_table_helper_generator import DispatchTableHelperGenerator
+    from generators.helper_file_generator import HelperFileGenerator
+    from generators.loader_extension_generator import LoaderExtensionGenerator
+    from generators.vk_result_to_string_generator import VkResultToStringGenerator
+
+    # These set fields that are needed by both OutputGenerator and BaseGenerator,
+    # but are uniform and don't need to be set at a per-generated file level
+    from base_generator import (SetTargetApiName, SetMergedApiNames)
+    SetTargetApiName(api)
+
+    # Generated directory and dispatch table helper file name may be API specific (e.g. Vulkan SC)
+    generated_directory = 'loader/generated'
+    dispatch_table_helper_filename = 'vk_dispatch_table_helper.h'
+    result_to_string_filename = 'vk_result_to_string_helper.h'
+
+    generators.update({
+        'vk_layer_dispatch_table.h': {
+            'generator' : LoaderExtensionGenerator,
+            'genCombined': False,
+            'directory' : generated_directory,
+        },
+        'vk_loader_extensions.c': {
+            'generator' : LoaderExtensionGenerator,
+            'genCombined': False,
+            'directory' : generated_directory,
+        },
+        'vk_loader_extensions.h': {
+            'generator' : LoaderExtensionGenerator,
+            'genCombined': False,
+            'directory' : generated_directory,
+        },
+        'vk_object_types.h': {
+            'generator' : HelperFileGenerator,
+            'genCombined': True,
+            'directory' : generated_directory,
+        },
+        f'{dispatch_table_helper_filename}': {
+            'generator' : DispatchTableHelperGenerator,
+            'genCombined': False,
+            'directory' : 'tests/framework/layer/generated',
+        },
+        f'{result_to_string_filename}': {
+            'generator' : VkResultToStringGenerator,
+            'genCombined': False,
+            'directory' : 'tests/framework/generated',
+        }
+    })
+
+    unknownTargets = [x for x in (targetFilter if targetFilter else []) if x not in generators.keys()]
+    if unknownTargets:
+        print(f'ERROR: No generator options for unknown target(s): {", ".join(unknownTargets)}', file=sys.stderr)
+        return 1
+
+    # Filter if --target is passed in
+    targets = [x for x in generators.keys() if not targetFilter or x in targetFilter]
+
+    for index, target in enumerate(targets, start=1):
+        print(f'[{index}|{len(targets)}] Generating {target}')
+
+        # First grab a class constructor object and create an instance
+        generator = generators[target]['generator']
+        gen = generator()
+
+        # This code and the 'genCombined' generator metadata is used by downstream
+        # users to generate code with all Vulkan APIs merged into the target API variant
+        # (e.g. Vulkan SC) when needed. The constructed apiList is also used to filter
+        # out non-applicable extensions later below.
+        apiList = [api]
+        if api != 'vulkan' and generators[target]['genCombined']:
+            SetMergedApiNames('vulkan')
+            apiList.append('vulkan')
+        else:
+            SetMergedApiNames(None)
+
+        # For people who want to generate all the files in a single director
+        if flatOutput:
+            outDirectory = os.path.abspath(os.path.join(directory))
+        else:
+            outDirectory = os.path.abspath(os.path.join(directory, generators[target]['directory']))
+
+        options = BaseGeneratorOptions(
+            customFileName  = target,
+            customDirectory = outDirectory)
+
+        if not os.path.exists(outDirectory):
+            os.makedirs(outDirectory)
+
+        # Create the registry object with the specified generator and generator
+        # options. The options are set before XML loading as they may affect it.
+        reg = Registry(gen, options)
+
+        # Parse the specified registry XML into an ElementTree object
+        tree = ElementTree.parse(registry)
+
+        # Load the XML tree into the registry object
+        reg.loadElementTree(tree)
+
+        # Finally, use the output generator to create the requested target
+        reg.apiGen()
+
+        # Run clang-format on the file
+        if has_clang_format and styleFile:
+            common_codegen.RunShellCmd(f'clang-format -i --style=file:{styleFile} {os.path.join(outDirectory, target)}')
+
 
 def main(argv):
+
+    # files to exclude from --verify check
+    verify_exclude = [] # None currently
+
+
     parser = argparse.ArgumentParser(description='Generate source code for this repository')
     parser.add_argument('registry', metavar='REGISTRY_PATH', help='path to the Vulkan-Headers registry directory')
     parser.add_argument('--api',
@@ -40,10 +182,14 @@
                         help='Specify API name to generate')
     parser.add_argument('--generated-version', help='sets the header version used to generate the repo')
     group = parser.add_mutually_exclusive_group()
+    group.add_argument('--target', nargs='+', help='only generate file names passed in')
     group.add_argument('-i', '--incremental', action='store_true', help='only update repo files that change')
     group.add_argument('-v', '--verify', action='store_true', help='verify repo files match generator output')
+    group.add_argument('-o', action='store', dest='directory', help='Create target and related files in specified directory')
     args = parser.parse_args(argv)
 
+    repo_dir = common_codegen.repo_relative('.')
+
     registry = os.path.abspath(os.path.join(args.registry,  'vk.xml'))
     if not os.path.isfile(registry):
         registry = os.path.abspath(os.path.join(args.registry, 'Vulkan-Headers/registry/vk.xml'))
@@ -51,15 +197,8 @@
             print(f'cannot find vk.xml in {args.registry}')
             return -1
 
-    gen_cmds = [[common_codegen.repo_relative('scripts/loader_genvk.py'),
-                 '-registry', registry,
-                 '-quiet',
-                 filename] for filename in ['vk_layer_dispatch_table.h',
-                                            'vk_loader_extensions.h',
-                                            'vk_loader_extensions.c',
-                                            'vk_object_types.h']]
-
-    repo_dir = common_codegen.repo_relative('loader/generated')
+    # Need pass style file incase running with --verify and it can't find the file automatically in the temp directory
+    style_file = os.path.join(repo_dir, '.clang-format')
 
     # get directory where generators will run
     if args.verify or args.incremental:
@@ -67,38 +206,40 @@
         temp_obj = tempfile.TemporaryDirectory(prefix='loader_codegen_')
         temp_dir = temp_obj.name
         gen_dir = temp_dir
+    elif args.directory:
+        gen_dir = args.directory
     else:
         # generate directly in the repo
         gen_dir = repo_dir
 
-    # run each code generator
-    for cmd in gen_cmds:
-        print(' '.join(cmd))
-        try:
-            subprocess.check_call([sys.executable] + cmd,
-                                  # ignore generator output, vk_validation_stats.py is especially noisy
-                                  stdout=subprocess.DEVNULL,
-                                  cwd=gen_dir)
-        except Exception as e:
-            print('ERROR:', str(e))
-            return 1
+    RunGenerators(api=args.api,registry=registry, directory=gen_dir, styleFile=style_file, targetFilter=args.target, flatOutput=False)
 
     # optional post-generation steps
     if args.verify:
+
         # compare contents of temp dir and repo
-        temp_files = set(os.listdir(temp_dir))
-        repo_files = set(os.listdir(repo_dir))
+        temp_files = {}
+        repo_files = {}
+        for details in generators.values():
+            if details['directory'] not in temp_files:
+                temp_files[details['directory']] = set()
+            temp_files[details['directory']].update(set(os.listdir(os.path.join(temp_dir, details['directory']))))
+            if details['directory'] not in repo_files:
+                repo_files[details['directory']] = set()
+            repo_files[details['directory']].update(set(os.listdir(os.path.join(repo_dir, details['directory']))) - set(verify_exclude))
+
+        # compare contents of temp dir and repo
         files_match = True
-        for filename in sorted((temp_files | repo_files)):
-            if filename not in repo_files:
+        for filename, details in generators.items():
+            if filename not in repo_files[details['directory']]:
                 print('ERROR: Missing repo file', filename)
                 files_match = False
-            elif filename not in temp_files:
+            elif filename not in temp_files[details['directory']]:
                 print('ERROR: Missing generator for', filename)
                 files_match = False
-            elif not filecmp.cmp(os.path.join(temp_dir, filename),
-                               os.path.join(repo_dir, filename),
-                               shallow=False):
+            elif not filecmp.cmp(os.path.join(temp_dir, details['directory'], filename),
+                            os.path.join(repo_dir, details['directory'], filename),
+                            shallow=False):
                 print('ERROR: Repo files do not match generator output for', filename)
                 files_match = False
 
@@ -110,11 +251,11 @@
 
     elif args.incremental:
         # copy missing or differing files from temp directory to repo
-        for filename in os.listdir(temp_dir):
-            temp_filename = os.path.join(temp_dir, filename)
-            repo_filename = os.path.join(repo_dir, filename)
+        for filename, details in generators.items():
+            temp_filename = os.path.join(temp_dir, details['directory'], filename)
+            repo_filename = os.path.join(repo_dir, details['directory'], filename)
             if not os.path.exists(repo_filename) or \
-               not filecmp.cmp(temp_filename, repo_filename, shallow=False):
+            not filecmp.cmp(temp_filename, repo_filename, shallow=False):
                 print('update', repo_filename)
                 shutil.copyfile(temp_filename, repo_filename)
 
diff --git a/scripts/generators/dispatch_table_helper_generator.py b/scripts/generators/dispatch_table_helper_generator.py
new file mode 100644
index 0000000..cf00609
--- /dev/null
+++ b/scripts/generators/dispatch_table_helper_generator.py
@@ -0,0 +1,104 @@
+#!/usr/bin/python3 -i
+#
+# Copyright (c) 2015-2021 The Khronos Group Inc.
+# Copyright (c) 2015-2021 Valve Corporation
+# Copyright (c) 2015-2021 LunarG, Inc.
+# Copyright (c) 2015-2021 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Author: Mark Lobodzinski <mark@lunarg.com>
+# Author: Charles Giessen <charles@lunarg.com>
+
+import os
+from base_generator import BaseGenerator
+
+class DispatchTableHelperGenerator(BaseGenerator):
+    def __init__(self):
+        BaseGenerator.__init__(self)
+
+    def generate(self):
+        out = []
+
+        out.append(f'''#pragma once
+// *** THIS FILE IS GENERATED - DO NOT EDIT ***
+// See {os.path.basename(__file__)} for modifications
+
+/*
+ * Copyright (c) 2015-2025 The Khronos Group Inc.
+ * Copyright (c) 2015-2025 Valve Corporation
+ * Copyright (c) 2015-2025 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
+ * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Charles Giessen <charles@lunarg.com>
+ */
+
+#include <vulkan/vulkan.h>
+#include <vulkan/vk_layer.h>
+#include <string.h>
+#include "loader/generated/vk_layer_dispatch_table.h"
+
+''')
+
+        self.OutputDispatchTableHelper(out, 'device')
+        out.append('\n\n')
+        self.OutputDispatchTableHelper(out, 'instance')
+
+        self.write(''.join(out))
+
+    # Create a dispatch table from the corresponding table_type and append it to out
+    def OutputDispatchTableHelper(self, out: list, table_type: str):
+        out.append('    // clang-format off\n')
+        if table_type == 'device':
+            out.append('static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDispatchTable *table, PFN_vkGetDeviceProcAddr gpa) {\n')
+            out.append('    memset(table, 0, sizeof(*table));\n')
+            out.append('    table->magic = DEVICE_DISP_TABLE_MAGIC_NUMBER;\n\n')
+            out.append('    // Device function pointers\n')
+        else:
+            out.append('static inline void layer_init_instance_dispatch_table(VkInstance instance, VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa) {\n')
+            out.append('    memset(table, 0, sizeof(*table));\n\n')
+            out.append('    // Instance function pointers\n')
+
+        for command_name, command in self.vk.commands.items():
+            if (table_type == 'device' and not command.device) or (table_type == 'instance' and command.device):
+                continue
+
+            if command.protect is not None:
+                out.append( f'#if defined({command.protect})\n')
+
+            # If we're looking for the proc we are passing in, just point the table to it.  This fixes the issue where
+            # a layer overrides the function name for the loader.
+            if (table_type == 'device' and command_name == 'vkGetDeviceProcAddr'):
+                out.append( '    table->GetDeviceProcAddr = gpa;\n')
+            elif (table_type != 'device' and command_name == 'vkGetInstanceProcAddr'):
+                out.append( '    table->GetInstanceProcAddr = gpa;\n')
+            else:
+                out.append( f'    table->{command_name[2:]} = (PFN_{command_name})gpa({table_type}, "{command_name}");\n')
+            if command.protect is not None:
+                out.append( f'#endif  // {command.protect}\n')
+        out.append('    // clang-format on\n')
+        out.append('}')
diff --git a/scripts/generators/helper_file_generator.py b/scripts/generators/helper_file_generator.py
new file mode 100644
index 0000000..7cea3df
--- /dev/null
+++ b/scripts/generators/helper_file_generator.py
@@ -0,0 +1,205 @@
+#!/usr/bin/python3 -i
+#
+# Copyright (c) 2015-2017 The Khronos Group Inc.
+# Copyright (c) 2015-2017 Valve Corporation
+# Copyright (c) 2015-2017 LunarG, Inc.
+# Copyright (c) 2015-2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Author: Mark Lobodzinski <mark@lunarg.com>
+# Author: Tobin Ehlis <tobine@google.com>
+# Author: John Zulauf <jzulauf@lunarg.com>
+# Author: Charles Giessen <charles@lunarg.com>
+
+import re
+import os
+from base_generator import BaseGenerator
+
+class HelperFileGenerator(BaseGenerator):
+    def __init__(self):
+        BaseGenerator.__init__(self)
+
+        # Helper for VkDebugReportObjectTypeEXT
+        # Maps [ 'VkBuffer' : 'VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT' ]
+        # Will be 'VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT' if no type
+        self.debugReportObject = dict()
+        # Maps [ 'VkBuffer' : 'VK_OBJECT_TYPE_BUFFER' ]
+        self.objectType = dict()
+
+    # Takes a VK_OBJECT_TYPE_THE_TYP_EXT and turns it into TheTypeEXT
+    def get_kVulkanObjectName(self, str_to_process):
+        removed_prefix = str_to_process.split('_')[3:]
+        if ''.join(removed_prefix[-1:]) in self.vk.vendorTags:
+            return ''.join(str_to_process.title().split('_')[3:-1] + removed_prefix[-1:])
+        else:
+            return ''.join(str_to_process.title().split('_')[3:])
+
+    def split_handle_by_capital_case(self, str_to_split):
+        name = str_to_split[2:]
+        name = name.replace('NVX', 'Nvx')
+        # Force vendor tags to be title case so we can split by capital letter
+        for tag in self.vk.vendorTags:
+            name = name.replace(tag, tag.title())
+        # Split by capital letters so we can concoct a VK_DEBUG_REPORT_<>_EXT string out of it
+        return re.split('(?<=.)(?=[A-Z])', f'{name}')
+
+
+    def convert_to_VK_OBJECT_TYPE(self, str_to_convert):
+        return '_'.join(['VK_OBJECT_TYPE'] + self.split_handle_by_capital_case(str_to_convert)).upper()
+
+    def convert_to_VK_DEBUG_REPORT_OBJECT_TYPE(self, str_to_convert):
+        return '_'.join(['VK_DEBUG_REPORT_OBJECT_TYPE'] + self.split_handle_by_capital_case(str_to_convert) + ['EXT']).upper()
+
+    def generate(self):
+        # Search all fields of the Enum to see if has a DEBUG_REPORT_OBJECT
+        for handle in self.vk.handles.values():
+            debugObjects = ([enum.name for enum in self.vk.enums['VkDebugReportObjectTypeEXT'].fields if f'{handle.type[3:]}_EXT' in enum.name])
+            object = 'VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT' if len(debugObjects) == 0 else debugObjects[0]
+            self.debugReportObject[handle.name] = object
+
+
+
+        out = []
+        out.append(f'''// clang-format off
+// *** THIS FILE IS GENERATED - DO NOT EDIT ***
+// See {os.path.basename(__file__)} for modifications
+
+
+/***************************************************************************
+ *
+ * Copyright (c) 2015-2025 The Khronos Group Inc.
+ * Copyright (c) 2015-2025 Valve Corporation
+ * Copyright (c) 2015-2025 LunarG, Inc.
+ * Copyright (c) 2015-2017 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Courtney Goeltzenleuchter <courtneygo@google.com>
+ * Author: Tobin Ehlis <tobine@google.com>
+ * Author: Chris Forbes <chrisforbes@google.com>
+ * Author: John Zulauf<jzulauf@lunarg.com>
+ * Author: Charles Giessen<charles@lunarg.com>
+ *
+ ****************************************************************************/
+
+
+#pragma once
+
+#include <vulkan/vulkan.h>
+
+''')
+
+        # Get the list of field names from VkDebugReportObjectTypeEXT
+        VkDebugReportObjectTypeEXT_field_names = []
+        for field in self.vk.enums['VkDebugReportObjectTypeEXT'].fields:
+            VkDebugReportObjectTypeEXT_field_names.append(field.name)
+
+        # Create a list with the needed information so that when we print, we print in the exact same order, as we are printing arrays where external code may index into it
+        object_types = []
+        object_type_aliases = {}
+        enum_num = 1 # start at one since the zero place is manually printed with the UNKNOWN value
+        for handle in self.vk.handles.values():
+            debug_report_object_name = self.convert_to_VK_DEBUG_REPORT_OBJECT_TYPE(handle.name)
+            if debug_report_object_name in VkDebugReportObjectTypeEXT_field_names:
+                object_types.append((f'{handle.name[2:]}', enum_num, debug_report_object_name))
+            else:
+                object_types.append((f'{handle.name[2:]}', enum_num, 'VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT'))
+            enum_num += 1
+            if len(handle.aliases) > 0:
+                object_type_aliases[handle.name] = handle.aliases
+
+        out.append('// Object Type enum for validation layer internal object handling\n')
+        out.append('typedef enum VulkanObjectType {\n')
+        out.append('    kVulkanObjectTypeUnknown = 0,\n')
+        for name, number, debug_report in object_types:
+            out.append(f'    kVulkanObjectType{name} = {number},\n')
+        out.append(f'    kVulkanObjectTypeMax = {enum_num},\n')
+
+        out.append('    // Aliases for backwards compatibility of "promoted" types\n')
+        for name, aliases in object_type_aliases.items():
+            for alias in aliases:
+                out.append(f'    kVulkanObjectType{alias[2:]} = kVulkanObjectType{name[2:]},\n')
+
+        out.append('} VulkanObjectType;\n')
+        out.append('\n')
+
+        out.append('// Array of object name strings for OBJECT_TYPE enum conversion\n')
+        out.append('static const char * const object_string[kVulkanObjectTypeMax] = {\n')
+        out.append('    \"Unknown\",\n')
+        for name, number, debug_report in object_types:
+            out.append(f'    \"{name}\",\n')
+        out.append('};\n')
+        out.append('\n')
+
+        out.append('// Helper array to get Vulkan VK_EXT_debug_report object type enum from the internal layers version\n')
+        out.append('const VkDebugReportObjectTypeEXT get_debug_report_enum[] = {\n')
+        out.append('    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeUnknown\n')
+        for name, number, debug_report in object_types:
+            out.append(f'    {debug_report},   // kVulkanObjectType{name}\n')
+        out.append('};\n')
+        out.append('\n')
+
+        out.append('// Helper array to get Official Vulkan VkObjectType enum from the internal layers version\n')
+        out.append('const VkObjectType get_object_type_enum[] = {\n')
+        out.append('    VK_OBJECT_TYPE_UNKNOWN, // kVulkanObjectTypeUnknown\n')
+        for handle in self.vk.handles.values():
+            object_name = self.convert_to_VK_OBJECT_TYPE(handle.name)
+            out.append(f'    {object_name},   // kVulkanObjectType{handle.name[2:]}\n')
+        out.append('};\n')
+        out.append('\n')
+
+        out.append('// Helper function to convert from VkDebugReportObjectTypeEXT to VkObjectType\n')
+        out.append('static inline VkObjectType convertDebugReportObjectToCoreObject(VkDebugReportObjectTypeEXT debug_report_obj){\n')
+        out.append('    if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT) {\n')
+        out.append('        return VK_OBJECT_TYPE_UNKNOWN;\n')
+        for field in self.vk.enums['VkObjectType'].fields:
+            enum_field_name = f'VK_DEBUG_REPORT_{field.name[3:]}_EXT'
+            for debug_report_field in self.vk.enums['VkDebugReportObjectTypeEXT'].fields:
+                if enum_field_name == debug_report_field.name:
+                    out.append(f'    }} else if (debug_report_obj == VK_DEBUG_REPORT_{field.name[3:]}_EXT) {{\n')
+                    out.append(f'        return {field.name};\n')
+                    break
+        out.append('    }\n')
+        out.append('    return VK_OBJECT_TYPE_UNKNOWN;\n')
+        out.append('}\n')
+        out.append('\n')
+
+        out.append('// Helper function to convert from VkDebugReportObjectTypeEXT to VkObjectType\n')
+        out.append('static inline VkDebugReportObjectTypeEXT convertCoreObjectToDebugReportObject(VkObjectType core_report_obj){\n')
+        out.append('    if (core_report_obj == VK_OBJECT_TYPE_UNKNOWN) {\n')
+        out.append('        return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;\n')
+        for field in self.vk.enums['VkObjectType'].fields:
+            enum_field_name = f'VK_DEBUG_REPORT_{field.name[3:]}_EXT'
+            for debug_report_field in self.vk.enums['VkDebugReportObjectTypeEXT'].fields:
+                if enum_field_name == debug_report_field.name:
+                    out.append(f'    }} else if (core_report_obj == {field.name}) {{\n')
+                    out.append(f'        return VK_DEBUG_REPORT_{field.name[3:]}_EXT;\n')
+                    break
+        out.append('    }\n')
+        out.append('    return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;\n')
+        out.append('}\n')
+
+        out.append('// clang-format on')
+        self.write("".join(out))
diff --git a/scripts/generators/loader_extension_generator.py b/scripts/generators/loader_extension_generator.py
new file mode 100644
index 0000000..6523795
--- /dev/null
+++ b/scripts/generators/loader_extension_generator.py
@@ -0,0 +1,1365 @@
+#!/usr/bin/python3 -i
+#
+# Copyright (c) 2015-2022 The Khronos Group Inc.
+# Copyright (c) 2015-2022 Valve Corporation
+# Copyright (c) 2015-2022 LunarG, Inc.
+# Copyright (c) 2015-2017 Google Inc.
+# Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# Copyright (c) 2023-2023 RasterGrid Kft.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Author: Mark Young <marky@lunarg.com>
+# Author: Mark Lobodzinski <mark@lunarg.com>
+# Author: Charles Giessen <charles@lunarg.com>
+
+import re
+import os
+from base_generator import BaseGenerator
+from vulkan_object import Version
+
+WSI_EXT_NAMES = ['VK_KHR_surface',
+                 'VK_KHR_display',
+                 'VK_KHR_xlib_surface',
+                 'VK_KHR_xcb_surface',
+                 'VK_KHR_wayland_surface',
+                 'VK_EXT_directfb_surface',
+                 'VK_KHR_win32_surface',
+                 'VK_KHR_android_surface',
+                 'VK_GGP_stream_descriptor_surface',
+                 'VK_MVK_macos_surface',
+                 'VK_MVK_ios_surface',
+                 'VK_EXT_headless_surface',
+                 'VK_EXT_metal_surface',
+                 'VK_FUCHSIA_imagepipe_surface',
+                 'VK_KHR_swapchain',
+                 'VK_KHR_display_swapchain',
+                 'VK_KHR_get_display_properties2',
+                 'VK_KHR_get_surface_capabilities2',
+                 'VK_QNX_screen_surface',
+                 'VK_NN_vi_surface']
+
+ADD_INST_CMDS = ['vkCreateInstance',
+                 'vkEnumerateInstanceExtensionProperties',
+                 'vkEnumerateInstanceLayerProperties',
+                 'vkEnumerateInstanceVersion']
+
+AVOID_EXT_NAMES = ['VK_EXT_debug_report']
+
+NULL_CHECK_EXT_NAMES= ['VK_EXT_debug_utils']
+
+AVOID_CMD_NAMES = ['vkCreateDebugUtilsMessengerEXT',
+                   'vkDestroyDebugUtilsMessengerEXT',
+                   'vkSubmitDebugUtilsMessageEXT']
+
+DEVICE_CMDS_NEED_TERM = ['vkGetDeviceProcAddr',
+                         'vkCreateSwapchainKHR',
+                         'vkCreateSharedSwapchainsKHR',
+                         'vkGetDeviceGroupSurfacePresentModesKHR',
+                         'vkDebugMarkerSetObjectTagEXT',
+                         'vkDebugMarkerSetObjectNameEXT',
+                         'vkSetDebugUtilsObjectNameEXT',
+                         'vkSetDebugUtilsObjectTagEXT',
+                         'vkQueueBeginDebugUtilsLabelEXT',
+                         'vkQueueEndDebugUtilsLabelEXT',
+                         'vkQueueInsertDebugUtilsLabelEXT',
+                         'vkCmdBeginDebugUtilsLabelEXT',
+                         'vkCmdEndDebugUtilsLabelEXT',
+                         'vkCmdInsertDebugUtilsLabelEXT',
+                         'vkGetDeviceGroupSurfacePresentModes2EXT']
+
+DEVICE_CMDS_MUST_USE_TRAMP = ['vkSetDebugUtilsObjectNameEXT',
+                              'vkSetDebugUtilsObjectTagEXT',
+                              'vkDebugMarkerSetObjectNameEXT',
+                              'vkDebugMarkerSetObjectTagEXT']
+
+# These are the aliased functions that use the same terminator for both extension and core versions
+# Generally, this is only applies to physical device level functions in instance extensions
+SHARED_ALIASES = {
+    # 1.1 aliases
+    'vkEnumeratePhysicalDeviceGroupsKHR':                   'vkEnumeratePhysicalDeviceGroups',
+    'vkGetPhysicalDeviceFeatures2KHR':                      'vkGetPhysicalDeviceFeatures2',
+    'vkGetPhysicalDeviceProperties2KHR':                    'vkGetPhysicalDeviceProperties2',
+    'vkGetPhysicalDeviceFormatProperties2KHR':              'vkGetPhysicalDeviceFormatProperties2',
+    'vkGetPhysicalDeviceImageFormatProperties2KHR':         'vkGetPhysicalDeviceImageFormatProperties2',
+    'vkGetPhysicalDeviceQueueFamilyProperties2KHR':         'vkGetPhysicalDeviceQueueFamilyProperties2',
+    'vkGetPhysicalDeviceMemoryProperties2KHR':              'vkGetPhysicalDeviceMemoryProperties2',
+    'vkGetPhysicalDeviceSparseImageFormatProperties2KHR':   'vkGetPhysicalDeviceSparseImageFormatProperties2',
+    'vkGetPhysicalDeviceExternalBufferPropertiesKHR':       'vkGetPhysicalDeviceExternalBufferProperties',
+    'vkGetPhysicalDeviceExternalSemaphorePropertiesKHR':    'vkGetPhysicalDeviceExternalSemaphoreProperties',
+    'vkGetPhysicalDeviceExternalFencePropertiesKHR':        'vkGetPhysicalDeviceExternalFenceProperties',
+}
+
+PRE_INSTANCE_FUNCTIONS = ['vkEnumerateInstanceExtensionProperties',
+                          'vkEnumerateInstanceLayerProperties',
+                          'vkEnumerateInstanceVersion']
+
+# This class is a container for any source code, data, or other behavior that is necessary to
+# customize the generator script for a specific target API variant (e.g. Vulkan SC). As such,
+# all of these API-specific interfaces and their use in the generator script are part of the
+# contract between this repository and its downstream users. Changing or removing any of these
+# interfaces or their use in the generator script will have downstream effects and thus
+# should be avoided unless absolutely necessary.
+class APISpecific:
+    @staticmethod
+    def getApiVersionDisplayName(targetApiName: str, name: str) -> str:
+        match targetApiName:
+            case 'vulkan':
+                api_name = 'Vulkan'
+
+        version_number = name[name.find('_VERSION_') + len('_VERSION_'):].replace('_', '.')
+        return f'{api_name} {version_number}'
+
+    @staticmethod
+    def getFirstVersionName(targetApiName: str) -> str:
+        match targetApiName:
+            case 'vulkan':
+                return 'VK_VERSION_1_0'
+
+    # This handles the dependency across versions of APIs, even across API variants
+    # (e.g. maps VK_VERSION_1_2 to VKSC_VERSION_1_0 for Vulkan SC).
+    # This handles the lack of proper support for the "depends" attribute of <feature> tags in the XML.
+    @staticmethod
+    def getEffectiveVersionName(targetApiName: str, version: Version) -> str:
+        if version is None:
+            return APISpecific.getFirstVersionName(targetApiName)
+
+        match targetApiName:
+            case 'vulkan':
+                return version.name
+
+
+class LoaderExtensionGenerator(BaseGenerator):
+    def __init__(self):
+        BaseGenerator.__init__(self)
+
+        self.core_commands = []
+        self.extension_commands = []
+        self.instance_extensions = []
+
+    def generate(self):
+
+        self.core_commands = [x for x in self.vk.commands.values() if len(x.extensions) == 0]
+        self.extension_commands = [x for x in self.vk.commands.values() if len(x.extensions) > 0]
+
+        self.instance_extensions = [x for x in self.vk.extensions.values() if x.instance]
+
+        out = []
+        self.add_preamble(out)
+
+        if self.filename == 'vk_loader_extensions.h':
+            self.print_vk_loader_extensions_h(out)
+        elif self.filename == 'vk_loader_extensions.c':
+            self.print_vk_loader_extensions_c(out)
+        elif self.filename == 'vk_layer_dispatch_table.h':
+            self.print_vk_layer_dispatch_table(out)
+
+        out.append('// clang-format on')
+
+        self.write(''.join(out))
+
+    def add_preamble(self, out):
+        out.append(f'''// *** THIS FILE IS GENERATED - DO NOT EDIT ***
+// See {os.path.basename(__file__)} for modifications
+
+/*
+ * Copyright (c) 2015-2025 The Khronos Group Inc.
+ * Copyright (c) 2015-2025 Valve Corporation
+ * Copyright (c) 2015-2025 LunarG, Inc.
+ * Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ * Copyright (c) 2023-2023 RasterGrid Kft.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Mark Young <marky@lunarg.com>
+ * Author: Charles Giessen <charles@lunarg.com>
+ */
+
+// clang-format off
+''')
+
+    def print_vk_loader_extensions_h(self, out):
+        out.append('#pragma once\n')
+        out.append('\n')
+        out.append('#include <stdbool.h>\n')
+        out.append('#include <vulkan/vulkan.h>\n')
+        out.append('#include <vulkan/vk_layer.h>\n')
+        out.append('#include "vk_layer_dispatch_table.h"\n')
+        out.append('\n\n')
+
+        self.OutputPrototypesInHeader(out)
+        self.OutputLoaderTerminators(out)
+        self.OutputIcdDispatchTable(out)
+        self.OutputIcdExtensionEnableUnion(out)
+        self.OutputDeviceFunctionTerminatorDispatchTable(out)
+
+
+    def print_vk_loader_extensions_c(self, out):
+        out.append('#include <stdio.h>\n')
+        out.append('#include <stdlib.h>\n')
+        out.append('#include <string.h>\n')
+        out.append('#include "loader.h"\n')
+        out.append('#include "vk_loader_extensions.h"\n')
+        out.append('#include <vulkan/vk_icd.h>\n')
+        out.append('#include "wsi.h"\n')
+        out.append('#include "debug_utils.h"\n')
+        out.append('#include "extension_manual.h"\n')
+        self.OutputUtilitiesInSource(out)
+        self.OutputIcdDispatchTableInit(out)
+        self.OutputLoaderDispatchTables(out)
+        self.InitDeviceFunctionTerminatorDispatchTable(out)
+        self.OutputDeviceFunctionTrampolinePrototypes(out)
+        self.OutputLoaderLookupFunc(out)
+        self.CreateTrampTermFuncs(out)
+        self.InstExtensionGPA(out)
+        self.InstantExtensionCreate(out)
+        self.DeviceExtensionGetTerminator(out)
+        self.InitInstLoaderExtensionDispatchTable(out)
+        self.OutputInstantExtensionWhitelistArray(out)
+
+    def print_vk_layer_dispatch_table(self, out):
+        out.append('#pragma once\n')
+        out.append('\n')
+        out.append('#include <vulkan/vulkan.h>\n')
+        out.append('#include <vulkan/vk_layer.h>\n')
+        out.append('\n')
+        self.OutputLayerInstanceDispatchTable(out)
+        self.OutputLayerDeviceDispatchTable(out)
+
+    def DescribeBlock(self, command, current_block, out, custom_commands_string = ' commands', indent = '    '):
+        effective_version_name = APISpecific.getEffectiveVersionName(self.targetApiName, command.version)
+        if command.extensions != current_block and effective_version_name != current_block:
+            if effective_version_name and len(command.extensions) == 0:
+                # Entry points that have an effective version in the target API
+                api_version_display_name = APISpecific.getApiVersionDisplayName(self.targetApiName, effective_version_name)
+                out.append(f"\n{indent}// ---- Core {api_version_display_name}{custom_commands_string}\n")
+                return effective_version_name
+            else:
+                # don't repeat unless the first extension is different (while rest can vary)
+                if not isinstance(current_block, list) or current_block[0] != command.extensions[0]:
+                    out.append(f"\n{indent}// ---- {command.extensions[0] if len(command.extensions) > 0 else ''} extension{custom_commands_string}\n")
+                return command.extensions
+        else:
+            return current_block
+
+    def OutputPrototypesInHeader(self, out: list):
+        out.append('''// Structures defined externally, but used here
+struct loader_instance;
+struct loader_device;
+struct loader_icd_term;
+struct loader_dev_dispatch_table;
+
+// Device extension error function
+VKAPI_ATTR VkResult VKAPI_CALL vkDevExtError(VkDevice dev);
+
+// Extension interception for vkGetInstanceProcAddr function, so we can return
+// the appropriate information for any instance extensions we know about.
+bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr);
+
+struct loader_instance_extension_enable_list; // Forward declaration
+
+// Extension interception for vkCreateInstance function, so we can properly
+// detect and enable any instance extension information for extensions we know
+// about.
+void fill_out_enabled_instance_extensions(uint32_t extension_count, const char *const * extension_list, struct loader_instance_extension_enable_list* enables);
+
+// Extension interception for vkGetDeviceProcAddr function, so we can return
+// an appropriate terminator if this is one of those few device commands requiring
+// a terminator.
+PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *name, bool* found_name);
+
+// Dispatch table properly filled in with appropriate terminators for the
+// supported extensions.
+extern const VkLayerInstanceDispatchTable instance_disp;
+
+// Array of extension strings for instance extensions we support.
+extern const char *const LOADER_INSTANCE_EXTENSIONS[];
+
+VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_instance* inst, struct loader_icd_term *icd_term);
+
+// Init Device function pointer dispatch table with core commands
+VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_dispatch_table *dev_table, PFN_vkGetDeviceProcAddr gpa,
+                                                             VkDevice dev);
+
+// Init Device function pointer dispatch table with extension commands
+VKAPI_ATTR void VKAPI_CALL loader_init_device_extension_dispatch_table(struct loader_dev_dispatch_table *dev_table,
+                                                                       PFN_vkGetInstanceProcAddr gipa,
+                                                                       PFN_vkGetDeviceProcAddr gdpa,
+                                                                       VkInstance inst,
+                                                                       VkDevice dev);
+
+// Init Instance function pointer dispatch table with core commands
+VKAPI_ATTR void VKAPI_CALL loader_init_instance_core_dispatch_table(VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,
+                                                                    VkInstance inst);
+
+// Init Instance function pointer dispatch table with core commands
+VKAPI_ATTR void VKAPI_CALL loader_init_instance_extension_dispatch_table(VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,
+                                                                         VkInstance inst);
+
+// Device command lookup function
+VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDispatchTable *table, const char *name, bool* name_found);
+
+// Instance command lookup function
+VKAPI_ATTR void* VKAPI_CALL loader_lookup_instance_dispatch_table(const VkLayerInstanceDispatchTable *table, const char *name,
+                                                                  bool *found_name);
+
+''')
+
+    # Creates the prototypes for the loader's core instance command terminators
+    def OutputLoaderTerminators(self, out):
+        out.append('// Loader core instance terminators\n')
+
+        for command in [x for x in self.vk.commands.values() if len(x.extensions) == 0]:
+            if not (command.name in ADD_INST_CMDS) and not (command.params[0].type in ['VkInstance', 'VkPhysicalDevice']):
+                continue
+
+            mod_string = ''
+            new_terminator = command.cPrototype
+            mod_string = new_terminator.replace("VKAPI_CALL vk", "VKAPI_CALL terminator_")
+
+            if command.name in PRE_INSTANCE_FUNCTIONS:
+                pre_instance_basic_version = mod_string
+                mod_string = mod_string.replace("terminator_", "terminator_pre_instance_")
+                mod_string = mod_string.replace(command.name[2:] + '(\n', command.name[2:] + '(\n    const Vk' + command.name[2:] + 'Chain* chain,\n')
+
+            if command.protect is not None:
+                out.append(f'#if defined({command.protect})\n')
+
+            if command.name in PRE_INSTANCE_FUNCTIONS:
+                out.append(pre_instance_basic_version)
+                out.append('\n')
+
+            out.append(mod_string)
+            out.append('\n')
+
+            if command.protect is not None:
+                out.append(f'#endif // {command.protect}\n')
+
+        out.append('\n')
+
+    # Create a dispatch table from the appropriate list
+    def OutputIcdDispatchTable(self, out):
+        skip_commands = ['vkGetInstanceProcAddr',
+                         'vkEnumerateDeviceLayerProperties',
+                        ]
+
+        out.append('// ICD function pointer dispatch table\n')
+        out.append('struct loader_icd_term_dispatch {\n')
+
+        current_block = ''
+        for command in self.vk.commands.values():
+            if (command.name in skip_commands or command.device )and command.name != 'vkGetDeviceProcAddr':
+                continue
+
+            current_block = self.DescribeBlock(command, current_block, out)
+
+            if command.protect:
+                out.append(f'#if defined({command.protect})\n')
+
+            out.append(f'    PFN_{command.name} {command.name[2:]};\n')
+
+            if command.protect:
+                out.append(f'#endif // {command.protect}\n')
+        out.append('};\n\n')
+
+    # Create the extension enable union
+    def OutputIcdExtensionEnableUnion(self, out):
+
+        out.append( 'struct loader_instance_extension_enable_list {\n')
+        for extension in self.instance_extensions:
+            if extension.protect:
+                out.append(f'#if defined({extension.protect})\n')
+            out.append( f'    uint8_t {extension.name[3:].lower()};\n')
+            if extension.protect:
+                out.append(f'#endif // defined({extension.protect})\n')
+
+        out.append( '};\n\n')
+
+    # Create a dispatch table solely for device functions which have custom terminators
+    def OutputDeviceFunctionTerminatorDispatchTable(self, out):
+        out.append('// Functions that required a terminator need to have a separate dispatch table which contains their corresponding\n')
+        out.append('// device function. This is used in the terminators themselves.\n')
+        out.append('struct loader_device_terminator_dispatch {\n')
+
+        # last_protect = None
+        current_block = ''
+        for command in self.vk.commands.values():
+            if len(command.extensions) == 0:
+                continue
+            if command.name in DEVICE_CMDS_NEED_TERM:
+                if command.protect is not None:
+                    out.append( f'#if defined({command.protect})\n')
+
+                current_block = self.DescribeBlock(command, current_block, out)
+
+                out.append( f'    PFN_{command.name} {command.name[2:]};\n')
+
+                if command.protect is not None:
+                    out.append( f'#endif // {command.protect}\n')
+
+        out.append( '};\n\n')
+
+
+    # Create a layer instance dispatch table from the appropriate list
+    def OutputLayerInstanceDispatchTable(self, out):
+
+        out.append('// Instance function pointer dispatch table\n')
+        out.append('typedef struct VkLayerInstanceDispatchTable_ {\n')
+
+        # First add in an entry for GetPhysicalDeviceProcAddr.  This will not
+        # ever show up in the XML or header, so we have to manually add it.
+        out.append('    // Manually add in GetPhysicalDeviceProcAddr entry\n')
+        out.append('    PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr;\n')
+
+        current_block = ''
+        for command_name, command in self.vk.commands.items():
+            if not command.instance:
+                continue
+
+            current_block = self.DescribeBlock(command, current_block, out)
+
+            if command.protect:
+                out.append(f'#if defined({command.protect})\n')
+
+            out.append(f'    PFN_{command_name} {command_name[2:]};\n')
+
+            if command.protect:
+                out.append(f'#endif // {command.protect}\n')
+
+        out.append('} VkLayerInstanceDispatchTable;\n\n')
+
+    # Create a layer device dispatch table from the appropriate list
+    def OutputLayerDeviceDispatchTable(self, out):
+
+        out.append('// Device function pointer dispatch table\n')
+        out.append('#define DEVICE_DISP_TABLE_MAGIC_NUMBER 0x10ADED040410ADEDUL\n')
+        out.append('typedef struct VkLayerDispatchTable_ {\n')
+        out.append('    uint64_t magic; // Should be DEVICE_DISP_TABLE_MAGIC_NUMBER\n')
+
+        current_block = ''
+        for command in [x for x in self.vk.commands.values() if x.device]:
+
+            current_block = self.DescribeBlock(command, current_block, out)
+
+            if command.protect:
+                out.append(f'#if defined({command.protect})\n')
+
+            out.append(f'    PFN_{command.name} {command.name[2:]};\n')
+
+            if command.protect:
+                out.append(f'#endif // {command.protect}\n')
+        out.append('} VkLayerDispatchTable;\n\n')
+
+    def OutputUtilitiesInSource(self, out):
+        out.append('''
+// Device extension error function
+VKAPI_ATTR VkResult VKAPI_CALL vkDevExtError(VkDevice dev) {
+    struct loader_device *found_dev;
+    // The device going in is a trampoline device
+    struct loader_icd_term *icd_term = loader_get_icd_and_device(dev, &found_dev);
+
+    if (icd_term)
+        loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
+                   "Bad destination in loader trampoline dispatch,"
+                   "Are layers and extensions that you are calling enabled?");
+    return VK_ERROR_EXTENSION_NOT_PRESENT;
+}
+
+''')
+
+
+    # Init a dispatch table from the appropriate list
+    def OutputIcdDispatchTableInit(self, out):
+        out.append('VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_instance* inst, struct loader_icd_term *icd_term) {\n')
+        out.append('    const PFN_vkGetInstanceProcAddr fp_gipa = icd_term->scanned_icd->GetInstanceProcAddr;\n')
+        out.append('\n')
+        out.append('#define LOOKUP_GIPA(func) icd_term->dispatch.func = (PFN_vk##func)fp_gipa(icd_term->instance, "vk" #func);\n')
+        out.append('\n')
+        out.append('#define LOOKUP_REQUIRED_GIPA(func)                                                      \\\n')
+        out.append('    do {                                                                                \\\n')
+        out.append('        LOOKUP_GIPA(func);                                                              \\\n')
+        out.append('        if (!icd_term->dispatch.func) {                                                 \\\n')
+        out.append('            loader_log(inst, VULKAN_LOADER_WARN_BIT, 0, "Unable to load %s from ICD %s",\\\n')
+        out.append('                       "vk"#func, icd_term->scanned_icd->lib_name);                     \\\n')
+        out.append('            return false;                                                               \\\n')
+        out.append('        }                                                                               \\\n')
+        out.append('    } while (0)\n')
+        out.append('\n')
+
+
+        skip_gipa_commands = ['vkGetInstanceProcAddr',
+                              'vkEnumerateDeviceLayerProperties',
+                              'vkCreateInstance',
+                              'vkEnumerateInstanceExtensionProperties',
+                              'vkEnumerateInstanceLayerProperties',
+                              'vkEnumerateInstanceVersion',
+                             ]
+
+        current_block = ''
+        for command in [x for x in self.vk.commands.values() if x.instance or x.name == 'vkGetDeviceProcAddr']:
+            if command.name in skip_gipa_commands:
+                continue
+            custom_commands_string= ' commands' if len(command.extensions) > 0 else ''
+            current_block = self.DescribeBlock(command, current_block, out, custom_commands_string=custom_commands_string)
+
+            if command.protect is not None:
+                out.append( f'#if defined({command.protect})\n')
+
+            effective_version_name = APISpecific.getEffectiveVersionName(self.targetApiName, command.version)
+            if effective_version_name == APISpecific.getFirstVersionName(self.targetApiName) and len(command.extensions) == 0:
+                # The Core Vulkan code will be wrapped in a feature called VK_VERSION_#_#
+                # For example: VK_VERSION_1_0 wraps the core 1.0 Vulkan functionality
+                out.append(f'    LOOKUP_REQUIRED_GIPA({command.name[2:]});\n')
+            else:
+                out.append( f'    LOOKUP_GIPA({command.name[2:]});\n')
+
+            if command.protect is not None:
+                out.append(f'#endif // {command.protect}\n')
+
+        out.append('\n')
+        out.append('#undef LOOKUP_REQUIRED_GIPA\n')
+        out.append('#undef LOOKUP_GIPA\n')
+        out.append('\n')
+        out.append('    return true;\n')
+        out.append('};\n\n')
+
+
+    # Creates code to initialize the various dispatch tables
+    def OutputLoaderDispatchTables(self, out):
+        commands = []
+        gpa_param = ''
+        cur_type = ''
+
+        for x in range(0, 4):
+            if x == 0:
+                cur_type = 'device'
+                gpa_param = 'dev'
+                commands = self.core_commands
+
+                out.append('// Init Device function pointer dispatch table with core commands\n')
+                out.append('VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_dispatch_table *dev_table, PFN_vkGetDeviceProcAddr gpa,\n')
+                out.append('                                                             VkDevice dev) {\n')
+                out.append('    VkLayerDispatchTable *table = &dev_table->core_dispatch;\n')
+                out.append('    if (table->magic != DEVICE_DISP_TABLE_MAGIC_NUMBER) { abort(); }\n')
+                out.append('    for (uint32_t i = 0; i < MAX_NUM_UNKNOWN_EXTS; i++) dev_table->ext_dispatch[i] = (PFN_vkDevExt)vkDevExtError;\n')
+
+            elif x == 1:
+                cur_type = 'device'
+                gpa_param = 'dev'
+                commands = self.extension_commands
+
+                out.append('// Init Device function pointer dispatch table with extension commands\n')
+                out.append('VKAPI_ATTR void VKAPI_CALL loader_init_device_extension_dispatch_table(struct loader_dev_dispatch_table *dev_table,\n')
+                out.append('                                                                       PFN_vkGetInstanceProcAddr gipa,\n')
+                out.append('                                                                       PFN_vkGetDeviceProcAddr gdpa,\n')
+                out.append('                                                                       VkInstance inst,\n')
+                out.append('                                                                       VkDevice dev) {\n')
+                out.append('    VkLayerDispatchTable *table = &dev_table->core_dispatch;\n')
+                out.append('    table->magic = DEVICE_DISP_TABLE_MAGIC_NUMBER;\n')
+
+            elif x == 2:
+                cur_type = 'instance'
+                gpa_param = 'inst'
+                commands = self.core_commands
+
+                out.append('// Init Instance function pointer dispatch table with core commands\n')
+                out.append('VKAPI_ATTR void VKAPI_CALL loader_init_instance_core_dispatch_table(VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,\n')
+                out.append('                                                                    VkInstance inst) {\n')
+
+            else:
+                cur_type = 'instance'
+                gpa_param = 'inst'
+                commands = self.extension_commands
+
+                out.append('// Init Instance function pointer dispatch table with core commands\n')
+                out.append('VKAPI_ATTR void VKAPI_CALL loader_init_instance_extension_dispatch_table(VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,\n')
+                out.append('                                                                        VkInstance inst) {\n')
+
+            current_block = ''
+            for command in commands:
+                is_inst_handle_type = command.params[0].type in ['VkInstance', 'VkPhysicalDevice']
+                if ((cur_type == 'instance' and is_inst_handle_type) or (cur_type == 'device' and not is_inst_handle_type)):
+
+                    current_block = self.DescribeBlock(command, current_block, out)
+
+                    # Remove 'vk' from proto name
+                    base_name = command.name[2:]
+
+                    # Names to skip
+                    if (base_name == 'CreateInstance' or base_name == 'CreateDevice' or
+                        base_name == 'EnumerateInstanceExtensionProperties' or
+                        base_name == 'EnumerateInstanceLayerProperties' or
+                        base_name == 'EnumerateInstanceVersion'):
+                        continue
+
+                    if command.protect is not None:
+                        out.append(f'#if defined({command.protect})\n')
+
+                    # If we're looking for the proc we are passing in, just point the table to it.  This fixes the issue where
+                    # a layer overrides the function name for the loader.
+                    if x == 1:
+                        if base_name == 'GetDeviceProcAddr':
+                            out.append('    table->GetDeviceProcAddr = gdpa;\n')
+                        elif len(command.extensions) > 0 and self.vk.extensions[command.extensions[0]].instance:
+                            out.append(f'    table->{base_name} = (PFN_{command.name})gipa(inst, "{command.name}");\n')
+                        else:
+                            out.append(f'    table->{base_name} = (PFN_{command.name})gdpa(dev, "{command.name}");\n')
+                    elif (x < 1 and base_name == 'GetDeviceProcAddr'):
+                        out.append('    table->GetDeviceProcAddr = gpa;\n')
+                    elif (x > 1 and base_name == 'GetInstanceProcAddr'):
+                        out.append('    table->GetInstanceProcAddr = gpa;\n')
+                    else:
+                        out.append(f'    table->{base_name} = (PFN_{command.name})gpa({gpa_param}, "{command.name}");\n')
+
+                    if command.protect is not None:
+                        out.append(f'#endif // {command.protect}\n')
+
+            out.append('}\n\n')
+
+#
+    # Create code to initialize a dispatch table from the appropriate list of extension entrypoints
+    def InitDeviceFunctionTerminatorDispatchTable(self, out):
+        out.append('// Functions that required a terminator need to have a separate dispatch table which contains their corresponding\n')
+        out.append('// device function. This is used in the terminators themselves.\n')
+        out.append('void init_extension_device_proc_terminator_dispatch(struct loader_device *dev) {\n')
+        out.append('    struct loader_device_terminator_dispatch* dispatch = &dev->loader_dispatch.extension_terminator_dispatch;\n')
+        out.append('    PFN_vkGetDeviceProcAddr gpda = (PFN_vkGetDeviceProcAddr)dev->phys_dev_term->this_icd_term->dispatch.GetDeviceProcAddr;\n')
+        current_block = ''
+        for command in [x for x in self.vk.commands.values() if x.extensions or x.version]:
+            if command.name in DEVICE_CMDS_NEED_TERM:
+                if command.protect is not None:
+                    out.append(f'#if defined({command.protect})\n')
+
+                current_block = self.DescribeBlock(command, current_block, out)
+                enable_extension_expressions = []
+                for ext in command.extensions:
+                    enable_extension_expressions.append(f'dev->driver_extensions.{ext[3:].lower()}_enabled')
+                out.append(f'    if ({" || ".join(enable_extension_expressions)})\n')
+                out.append(f'       dispatch->{command.name[2:]} = (PFN_{(command.name)})gpda(dev->icd_device, "{(command.name)}");\n')
+
+                if command.protect is not None:
+                    out.append(f'#endif // {command.protect}\n')
+
+        out.append('}\n\n')
+
+
+    def OutputDeviceFunctionTrampolinePrototypes(self, out):
+        out.append('// These are prototypes for functions that need their trampoline called in all circumstances.\n')
+        out.append('// They are used in loader_lookup_device_dispatch_table but are defined afterwards.\n')
+        current_block = ''
+        for command in self.vk.commands.values():
+            if command.name in DEVICE_CMDS_MUST_USE_TRAMP:
+
+                if command.protect is not None:
+                    out.append(f'#if defined({command.protect})\n')
+                current_block = self.DescribeBlock(command, current_block, out)
+
+                out.append(f'{command.cPrototype.replace("VKAPI_CALL vk", "VKAPI_CALL ")}\n')
+
+                if command.protect is not None:
+                    out.append(f'#endif // {command.protect}\n')
+        out.append('\n')
+
+
+    #
+    # Create a lookup table function from the appropriate list of entrypoints
+    def OutputLoaderLookupFunc(self, out):
+        commands = []
+        cur_type = ''
+
+        for x in range(0, 2):
+            if x == 0:
+                cur_type = 'device'
+
+                out.append('// Device command lookup function\n')
+                out.append('VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDispatchTable *table, const char *name, bool* found_name) {\n')
+                out.append('    if (!name || name[0] != \'v\' || name[1] != \'k\') {\n')
+                out.append('        *found_name = false;\n')
+                out.append('        return NULL;\n')
+                out.append('    }\n')
+                out.append('\n')
+                out.append('    name += 2;\n')
+                out.append('    *found_name = true;\n')
+                out.append('    struct loader_device* dev = (struct loader_device *)table;\n')
+                out.append('    const struct loader_instance* inst = dev->phys_dev_term->this_icd_term->this_instance;\n')
+                out.append('    uint32_t api_version = VK_MAKE_API_VERSION(0, inst->app_api_version.major, inst->app_api_version.minor, inst->app_api_version.patch);\n')
+                out.append('\n')
+            else:
+                cur_type = 'instance'
+
+                out.append('// Instance command lookup function\n')
+                out.append('VKAPI_ATTR void* VKAPI_CALL loader_lookup_instance_dispatch_table(const VkLayerInstanceDispatchTable *table, const char *name,\n')
+                out.append('                                                                 bool *found_name) {\n')
+                out.append('    if (!name || name[0] != \'v\' || name[1] != \'k\') {\n')
+                out.append('        *found_name = false;\n')
+                out.append('        return NULL;\n')
+                out.append('    }\n')
+                out.append('\n')
+                out.append('    *found_name = true;\n')
+                out.append('    name += 2;\n')
+
+
+            for command_list in [self.core_commands, self.extension_commands]:
+                commands = command_list
+
+                version_check = ''
+                current_block = ''
+                for command in commands:
+                    is_inst_handle_type = command.params[0].type in ['VkInstance', 'VkPhysicalDevice']
+                    if ((cur_type == 'instance' and is_inst_handle_type) or (cur_type == 'device' and not is_inst_handle_type)):
+
+                        current_block = self.DescribeBlock(command, current_block, out)
+                        if len(command.extensions) == 0:
+                            if cur_type == 'device':
+                                effective_version_name = APISpecific.getEffectiveVersionName(self.targetApiName, command.version)
+                                api_version = effective_version_name.replace('_VERSION_', '_API_VERSION_')
+                                version_check = f"        if (dev->should_ignore_device_commands_from_newer_version && api_version < {api_version}) return NULL;\n"
+                            else:
+                                version_check = ''
+
+                        # Remove 'vk' from proto name
+                        base_name = command.name[2:]
+
+                        if (base_name == 'CreateInstance' or base_name == 'CreateDevice' or
+                            base_name == 'EnumerateInstanceExtensionProperties' or
+                            base_name == 'EnumerateInstanceLayerProperties' or
+                            base_name == 'EnumerateInstanceVersion'):
+                            continue
+
+                        if command.protect is not None:
+                            out.append(f'#if defined({command.protect})\n')
+
+                        out.append(f'    if (!strcmp(name, "{base_name}")) ')
+                        if command.name in DEVICE_CMDS_MUST_USE_TRAMP:
+                            if version_check != '':
+                                out.append(f'{{\n{version_check}        return dev->layer_extensions.{command.extensions[0][3:].lower()}_enabled ? (void *){base_name} : NULL;\n    }}\n')
+                            else:
+                                out.append(f'return dev->layer_extensions.{command.extensions[0][3:].lower()}_enabled ? (void *){base_name} : NULL;\n')
+
+                        else:
+                            if version_check != '':
+                                out.append(f'{{\n{version_check}        return (void *)table->{base_name};\n    }}\n')
+                            else:
+                                out.append(f'return (void *)table->{base_name};\n')
+
+                        if command.protect is not None:
+                            out.append(f'#endif // {command.protect}\n')
+
+            out.append('\n')
+            out.append('    *found_name = false;\n')
+            out.append('    return NULL;\n')
+            out.append('}\n\n')
+
+
+    #
+    # Create the appropriate trampoline (and possibly terminator) functions
+    def CreateTrampTermFuncs(self, out):
+        # Some extensions have to be manually added.  Skip those in the automatic
+        # generation.  They will be manually added later.
+        manual_ext_commands = ['vkEnumeratePhysicalDeviceGroupsKHR',
+                               'vkGetPhysicalDeviceExternalImageFormatPropertiesNV',
+                               'vkGetPhysicalDeviceFeatures2KHR',
+                               'vkGetPhysicalDeviceProperties2KHR',
+                               'vkGetPhysicalDeviceFormatProperties2KHR',
+                               'vkGetPhysicalDeviceImageFormatProperties2KHR',
+                               'vkGetPhysicalDeviceQueueFamilyProperties2KHR',
+                               'vkGetPhysicalDeviceMemoryProperties2KHR',
+                               'vkGetPhysicalDeviceSparseImageFormatProperties2KHR',
+                               'vkGetPhysicalDeviceSurfaceCapabilities2KHR',
+                               'vkGetPhysicalDeviceSurfaceFormats2KHR',
+                               'vkGetPhysicalDeviceSurfaceCapabilities2EXT',
+                               'vkReleaseDisplayEXT',
+                               'vkAcquireXlibDisplayEXT',
+                               'vkGetRandROutputDisplayEXT',
+                               'vkGetPhysicalDeviceExternalBufferPropertiesKHR',
+                               'vkGetPhysicalDeviceExternalSemaphorePropertiesKHR',
+                               'vkGetPhysicalDeviceExternalFencePropertiesKHR',
+                               'vkGetPhysicalDeviceDisplayProperties2KHR',
+                               'vkGetPhysicalDeviceDisplayPlaneProperties2KHR',
+                               'vkGetDisplayModeProperties2KHR',
+                               'vkGetDisplayPlaneCapabilities2KHR',
+                               'vkGetPhysicalDeviceSurfacePresentModes2EXT',
+                               'vkGetDeviceGroupSurfacePresentModes2EXT',
+                               'vkGetPhysicalDeviceToolPropertiesEXT']
+
+        current_block = ''
+        for command in [x for x in self.vk.commands.values() if x.extensions]:
+            if (command.extensions[0] in WSI_EXT_NAMES or
+                command.extensions[0] in AVOID_EXT_NAMES or
+                command.name in AVOID_CMD_NAMES or
+                command.name in manual_ext_commands):
+                continue
+
+            current_block = self.DescribeBlock(command=command, current_block=current_block, out=out, custom_commands_string=' trampoline/terminators\n', indent='')
+
+            if command.protect is not None:
+                out.append(f'#if defined({command.protect})\n')
+
+            func_header = command.cPrototype.replace(";", " {\n")
+            tramp_header = func_header.replace("VKAPI_CALL vk", "VKAPI_CALL ")
+            return_prefix = '    '
+            base_name = command.name[2:]
+            has_surface = 0
+            update_structure_surface = 0
+            update_structure_string = ''
+            requires_terminator = 0
+            surface_var_name = ''
+            phys_dev_var_name = ''
+            instance_var_name = ''
+            has_return_type = False
+            always_use_param_name = True
+            surface_type_to_replace = ''
+            surface_name_replacement = ''
+            physdev_type_to_replace = ''
+            physdev_name_replacement = ''
+
+            for param in command.params:
+                if param.type == 'VkSurfaceKHR':
+                    has_surface = 1
+                    surface_var_name = param.name
+                    requires_terminator = 1
+                    always_use_param_name = False
+                    surface_type_to_replace = 'VkSurfaceKHR'
+                    surface_name_replacement = 'unwrapped_surface'
+                if param.type == 'VkPhysicalDeviceSurfaceInfo2KHR':
+                    has_surface = 1
+                    surface_var_name = param.name + '->surface'
+                    requires_terminator = 1
+                    update_structure_surface = 1
+                    update_structure_string = '        VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;\n'
+                    update_structure_string += '        info_copy.surface = unwrapped_surface;\n'
+                    always_use_param_name = False
+                    surface_type_to_replace = 'VkPhysicalDeviceSurfaceInfo2KHR'
+                    surface_name_replacement = '&info_copy'
+                if param.type == 'VkPhysicalDevice':
+                    requires_terminator = 1
+                    phys_dev_var_name = param.name
+                    always_use_param_name = False
+                    physdev_type_to_replace = 'VkPhysicalDevice'
+                    physdev_name_replacement = 'phys_dev_term->phys_dev'
+                if param.type == 'VkInstance':
+                    requires_terminator = 1
+                    instance_var_name = param.name
+
+            if command.returnType != 'void':
+                return_prefix += 'return '
+                has_return_type = True
+
+            if ( command.params[0].type in ['VkInstance', 'VkPhysicalDevice'] or
+                'DebugMarkerSetObject' in command.name or 'SetDebugUtilsObject' in command.name or
+                command.name in DEVICE_CMDS_NEED_TERM):
+                requires_terminator = 1
+
+            if requires_terminator == 1:
+                term_header = tramp_header.replace("VKAPI_CALL ", "VKAPI_CALL terminator_")
+
+                out.append(tramp_header)
+
+                if command.params[0].type == 'VkPhysicalDevice':
+                    out.append('    const VkLayerInstanceDispatchTable *disp;\n')
+                    out.append(f'    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device({phys_dev_var_name});\n')
+                    out.append('    if (VK_NULL_HANDLE == unwrapped_phys_dev) {\n')
+                    out.append('        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n')
+                    out.append(f'                   "{command.name}: Invalid {phys_dev_var_name} "\n')
+                    out.append(f'                   "[VUID-{command.name}-{phys_dev_var_name}-parameter]");\n')
+                    out.append('        abort(); /* Intentionally fail so user can correct issue. */\n')
+                    out.append('    }\n')
+                    out.append(f'    disp = loader_get_instance_layer_dispatch({phys_dev_var_name});\n')
+                elif command.params[0].type == 'VkInstance':
+                    out.append(f'    struct loader_instance *inst = loader_get_instance({instance_var_name});\n')
+                    out.append('    if (NULL == inst) {\n')
+                    out.append('        loader_log(\n')
+                    out.append('            NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n')
+                    out.append(f'            "{command.name}: Invalid instance [VUID-{command.name}-{instance_var_name}-parameter]");\n')
+                    out.append('        abort(); /* Intentionally fail so user can correct issue. */\n')
+                    out.append('    }\n')
+                    out.append('#error("Not implemented. Likely needs to be manually generated!");\n')
+                else:
+                    out.append('    const VkLayerDispatchTable *disp = loader_get_dispatch(')
+                    out.append(command.params[0].name)
+                    out.append(');\n')
+                    out.append('    if (NULL == disp) {\n')
+                    out.append('        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n')
+                    out.append(f'                   "{command.name}: Invalid {command.params[0].name} "\n')
+                    out.append(f'                   "[VUID-{command.name}-{command.params[0].name}-parameter]");\n')
+                    out.append('        abort(); /* Intentionally fail so user can correct issue. */\n')
+                    out.append('    }\n')
+
+                if 'DebugMarkerSetObjectName' in command.name:
+                    out.append('    VkDebugMarkerObjectNameInfoEXT local_name_info;\n')
+                    out.append('    memcpy(&local_name_info, pNameInfo, sizeof(VkDebugMarkerObjectNameInfoEXT));\n')
+                    out.append('    // If this is a physical device, we have to replace it with the proper one for the next call.\n')
+                    out.append('    if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {\n')
+                    out.append('        struct loader_physical_device_tramp *phys_dev_tramp = (struct loader_physical_device_tramp *)(uintptr_t)pNameInfo->object;\n')
+                    out.append('        local_name_info.object = (uint64_t)(uintptr_t)phys_dev_tramp->phys_dev;\n')
+                    out.append('    }\n')
+                    out.append('    if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) {\n')
+                    out.append('        struct loader_instance* instance = (struct loader_instance *)(uintptr_t)pNameInfo->object;\n')
+                    out.append('        local_name_info.object = (uint64_t)(uintptr_t)instance->instance;\n')
+                    out.append('    }\n')
+                elif 'DebugMarkerSetObjectTag' in command.name:
+                    out.append('    VkDebugMarkerObjectTagInfoEXT local_tag_info;\n')
+                    out.append('    memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugMarkerObjectTagInfoEXT));\n')
+                    out.append('    // If this is a physical device, we have to replace it with the proper one for the next call.\n')
+                    out.append('    if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {\n')
+                    out.append('        struct loader_physical_device_tramp *phys_dev_tramp = (struct loader_physical_device_tramp *)(uintptr_t)pTagInfo->object;\n')
+                    out.append('        local_tag_info.object = (uint64_t)(uintptr_t)phys_dev_tramp->phys_dev;\n')
+                    out.append('    }\n')
+                    out.append('    if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) {\n')
+                    out.append('        struct loader_instance* instance = (struct loader_instance *)(uintptr_t)pTagInfo->object;\n')
+                    out.append('        local_tag_info.object = (uint64_t)(uintptr_t)instance->instance;\n')
+                    out.append('    }\n')
+                elif 'SetDebugUtilsObjectName' in command.name:
+                    out.append('    VkDebugUtilsObjectNameInfoEXT local_name_info;\n')
+                    out.append('    memcpy(&local_name_info, pNameInfo, sizeof(VkDebugUtilsObjectNameInfoEXT));\n')
+                    out.append('    // If this is a physical device, we have to replace it with the proper one for the next call.\n')
+                    out.append('    if (pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {\n')
+                    out.append('        struct loader_physical_device_tramp *phys_dev_tramp = (struct loader_physical_device_tramp *)(uintptr_t)pNameInfo->objectHandle;\n')
+                    out.append('        local_name_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_tramp->phys_dev;\n')
+                    out.append('    }\n')
+                    out.append('    if (pNameInfo->objectType == VK_OBJECT_TYPE_INSTANCE) {\n')
+                    out.append('        struct loader_instance* instance = (struct loader_instance *)(uintptr_t)pNameInfo->objectHandle;\n')
+                    out.append('        local_name_info.objectHandle = (uint64_t)(uintptr_t)instance->instance;\n')
+                    out.append('    }\n')
+                elif 'SetDebugUtilsObjectTag' in command.name:
+                    out.append('    VkDebugUtilsObjectTagInfoEXT local_tag_info;\n')
+                    out.append('    memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugUtilsObjectTagInfoEXT));\n')
+                    out.append('    // If this is a physical device, we have to replace it with the proper one for the next call.\n')
+                    out.append('    if (pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {\n')
+                    out.append('        struct loader_physical_device_tramp *phys_dev_tramp = (struct loader_physical_device_tramp *)(uintptr_t)pTagInfo->objectHandle;\n')
+                    out.append('        local_tag_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_tramp->phys_dev;\n')
+                    out.append('    }\n')
+                    out.append('    if (pTagInfo->objectType == VK_OBJECT_TYPE_INSTANCE) {\n')
+                    out.append('        struct loader_instance* instance = (struct loader_instance *)(uintptr_t)pTagInfo->objectHandle;\n')
+                    out.append('        local_tag_info.objectHandle = (uint64_t)(uintptr_t)instance->instance;\n')
+                    out.append('    }\n')
+
+                if command.extensions[0] in NULL_CHECK_EXT_NAMES:
+                    out.append('    if (disp->' + base_name + ' != NULL) {\n')
+                    out.append('    ')
+                out.append(return_prefix)
+                if command.params[0].type == 'VkInstance':
+                    out.append('inst->')
+                out.append('disp->')
+                out.append(base_name)
+                out.append('(')
+                count = 0
+                for param in command.params:
+                    if count != 0:
+                        out.append(', ')
+
+                    if param.type == 'VkPhysicalDevice':
+                        out.append('unwrapped_phys_dev')
+                    elif ('DebugMarkerSetObject' in command.name or 'SetDebugUtilsObject' in command.name) and param.name == 'pNameInfo':
+                        out.append('&local_name_info')
+                    elif ('DebugMarkerSetObject' in command.name or 'SetDebugUtilsObject' in command.name) and param.name == 'pTagInfo':
+                        out.append('&local_tag_info')
+                    else:
+                        out.append(param.name)
+
+                    count += 1
+                out.append(');\n')
+                if command.extensions[0] in NULL_CHECK_EXT_NAMES:
+                    if command.returnType != 'void':
+                        out.append('    } else {\n')
+                        out.append('        return VK_SUCCESS;\n')
+                    out.append('    }\n')
+                out.append('}\n\n')
+
+                out.append(term_header)
+                if command.params[0].type == 'VkPhysicalDevice':
+                    out.append(f'    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *){phys_dev_var_name};\n')
+                    out.append('    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;\n')
+                    out.append('    if (NULL == icd_term->dispatch.')
+                    out.append(base_name)
+                    out.append(') {\n')
+                    fatal_error_bit = '' if has_return_type and (len(command.extensions) == 0 or self.vk.extensions[command.extensions[0]].instance) else 'VULKAN_LOADER_FATAL_ERROR_BIT | '
+                    out.append(f'        loader_log(icd_term->this_instance, {fatal_error_bit}VULKAN_LOADER_ERROR_BIT, 0,\n')
+                    out.append('                   "ICD associated with VkPhysicalDevice does not support ')
+                    out.append(base_name)
+                    out.append('");\n')
+
+                    # If this is an instance function taking a physical device (i.e. pre Vulkan 1.1), we need to behave and not crash so return an
+                    # error here.
+                    if has_return_type and (len(command.extensions) == 0 or self.vk.extensions[command.extensions[0]].instance):
+                        out.append('        return VK_ERROR_EXTENSION_NOT_PRESENT;\n')
+                    else:
+                        out.append('        abort(); /* Intentionally fail so user can correct issue. */\n')
+                    out.append('    }\n')
+
+                    if has_surface == 1:
+                        out.append(f'    VkSurfaceKHR unwrapped_surface = {surface_var_name};\n')
+                        out.append('    VkResult unwrap_res = wsi_unwrap_icd_surface(icd_term, &unwrapped_surface);\n')
+                        out.append('    if (unwrap_res == VK_SUCCESS) {\n')
+
+                        # If there's a structure with a surface, we need to update its internals with the correct surface for the ICD
+                        if update_structure_surface == 1:
+                            out.append(update_structure_string)
+
+                        out.append('    ' + return_prefix + 'icd_term->dispatch.')
+                        out.append(base_name)
+                        out.append('(')
+                        count = 0
+                        for param in command.params:
+                            if count != 0:
+                                out.append(', ')
+
+                            if not always_use_param_name:
+                                if surface_type_to_replace and surface_type_to_replace == param.type:
+                                    out.append(surface_name_replacement)
+                                elif physdev_type_to_replace and physdev_type_to_replace == param.type:
+                                    out.append(physdev_name_replacement)
+                                else:
+                                    out.append(param.name)
+                            else:
+                                out.append(param.name)
+
+                            count += 1
+                        out.append(');\n')
+                        if not has_return_type:
+                            out.append('        return;\n')
+                        out.append('    }\n')
+
+                    out.append(return_prefix)
+                    out.append('icd_term->dispatch.')
+                    out.append(base_name)
+                    out.append('(')
+                    count = 0
+                    for param in command.params:
+                        if count != 0:
+                            out.append(', ')
+
+                        if param.type == 'VkPhysicalDevice':
+                            out.append('phys_dev_term->phys_dev')
+                        else:
+                            out.append(param.name)
+
+                        count += 1
+                    out.append(');\n')
+
+
+                elif command.params[0].type == 'VkInstance':
+                    out.append(f'    struct loader_instance *inst = loader_get_instance({instance_var_name});\n')
+                    out.append('    if (NULL == inst) {\n')
+                    out.append('        loader_log(\n')
+                    out.append('            NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n')
+                    out.append(f'            "{command.name}: Invalid instance [VUID-{command.name}-{instance_var_name}-parameter]");\n')
+                    out.append('        abort(); /* Intentionally fail so user can correct issue. */\n')
+                    out.append('    }\n')
+                    out.append('#error("Not implemented. Likely needs to be manually generated!");\n')
+                elif command.extensions[0] in ['VK_EXT_debug_utils', 'VK_EXT_debug_marker']:
+                    if command.name in ['vkDebugMarkerSetObjectNameEXT', 'vkDebugMarkerSetObjectTagEXT', 'vkSetDebugUtilsObjectNameEXT' , 'vkSetDebugUtilsObjectTagEXT']:
+
+                        is_debug_utils = command.extensions[0] == "VK_EXT_debug_utils"
+                        debug_struct_name = command.params[1].name
+                        local_struct = 'local_name_info' if 'ObjectName' in command.name else 'local_tag_info'
+                        member_name = 'objectHandle' if is_debug_utils else 'object'
+                        phys_dev_check = 'VK_OBJECT_TYPE_PHYSICAL_DEVICE' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT'
+                        surf_check = 'VK_OBJECT_TYPE_SURFACE_KHR' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT'
+                        inst_check = 'VK_OBJECT_TYPE_INSTANCE' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT'
+                        out.append('    struct loader_device *dev;\n')
+                        out.append(f'    struct loader_icd_term *icd_term = loader_get_icd_and_device({ command.params[0].name}, &dev);\n')
+                        out.append('    if (NULL == icd_term || NULL == dev) {\n')
+                        out.append(f'        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "{command.name[2:]}: Invalid device handle");\n')
+                        out.append('        abort(); /* Intentionally fail so user can correct issue. */\n')
+                        out.append('    }\n')
+                        out.append(f'    { command.params[1].type} {local_struct};\n')
+                        out.append(f'    memcpy(&{local_struct}, {debug_struct_name}, sizeof({ command.params[1].type}));\n')
+                        out.append('    // If this is a physical device, we have to replace it with the proper one for the next call.\n')
+                        out.append(f'    if ({debug_struct_name}->objectType == {phys_dev_check}) {{\n')
+                        out.append(f'        struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t){debug_struct_name}->{member_name};\n')
+                        out.append(f'        {local_struct}.{member_name} = (uint64_t)(uintptr_t)phys_dev_term->phys_dev;\n')
+                        out.append('    // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.\n')
+                        out.append(f'    }} else if ({debug_struct_name}->objectType == {surf_check}) {{\n')
+                        out.append('        if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) {\n')
+                        out.append(f'            VkSurfaceKHR surface = (VkSurfaceKHR)(uintptr_t){debug_struct_name}->{member_name};\n')
+                        out.append('            if (wsi_unwrap_icd_surface(icd_term, &surface) == VK_SUCCESS) {\n')
+                        out.append(f'                {local_struct}.{member_name} = (uint64_t)surface;\n')
+                        out.append('            }\n')
+                        out.append('        }\n')
+                        out.append('    // If this is an instance we have to replace it with the proper one for the next call.\n')
+                        out.append(f'    }} else if ({debug_struct_name}->objectType == {inst_check}) {{\n')
+                        out.append(f'        {local_struct}.{member_name} = (uint64_t)(uintptr_t)icd_term->instance;\n')
+                        out.append('    }\n')
+                        out.append('    // Exit early if the driver does not support the function - this can happen as a layer or the loader itself supports\n')
+                        out.append('    // debug utils but the driver does not.\n')
+                        out.append(f'    if (NULL == dev->loader_dispatch.extension_terminator_dispatch.{command.name[2:]})\n        return VK_SUCCESS;\n')
+                        dispatch = 'dev->loader_dispatch.'
+                    else:
+                        out.append(f'    struct loader_dev_dispatch_table *dispatch_table = loader_get_dev_dispatch({command.params[0].name});\n')
+                        out.append('    if (NULL == dispatch_table) {\n')
+                        out.append(f'        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "{command.extensions[0]}: Invalid device handle");\n')
+                        out.append('        abort(); /* Intentionally fail so user can correct issue. */\n')
+                        out.append('    }\n')
+                        out.append('    // Only call down if the device supports the function\n')
+                        out.append(f'    if (NULL != dispatch_table->extension_terminator_dispatch.{base_name})\n    ')
+                        dispatch = 'dispatch_table->'
+                    out.append('    ')
+                    if has_return_type:
+                        out.append('return ')
+                    out.append(f'{dispatch}extension_terminator_dispatch.{base_name}(')
+                    count = 0
+                    for param in command.params:
+                        if count != 0:
+                            out.append(', ')
+
+                        if param.type == 'VkPhysicalDevice':
+                            out.append('phys_dev_term->phys_dev')
+                        elif param.type == 'VkSurfaceKHR':
+                            out.append( 'unwrapped_surface')
+                        elif ('DebugMarkerSetObject' in command.name or 'SetDebugUtilsObject' in command.name) and param.name == 'pNameInfo':
+                            out.append( '&local_name_info')
+                        elif ('DebugMarkerSetObject' in command.name or 'SetDebugUtilsObject' in command.name) and param.name == 'pTagInfo':
+                            out.append('&local_tag_info')
+                        else:
+                            out.append(param.name)
+                        count += 1
+
+                    out.append(');\n')
+
+                else:
+                    out.append('#error("Unknown error path!");\n')
+
+                out.append('}\n\n')
+            else:
+                out.append(tramp_header)
+
+                out.append('    const VkLayerDispatchTable *disp = loader_get_dispatch(')
+                out.append(command.params[0].name)
+                out.append(');\n')
+                out.append('    if (NULL == disp) {\n')
+                out.append('        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n')
+                out.append(f'                   "{command.name}: Invalid {command.params[0].name} "\n')
+                out.append(f'                   "[VUID-{command.name}-{command.params[0].name}-parameter]");\n')
+                out.append('        abort(); /* Intentionally fail so user can correct issue. */\n')
+                out.append('    }\n')
+
+                if command.extensions[0] in NULL_CHECK_EXT_NAMES:
+                    out.append('    if (disp->' + base_name + ' != NULL) {\n')
+                    out.append('    ')
+                out.append(return_prefix)
+                out.append('disp->')
+                out.append(base_name)
+                out.append('(')
+                count = 0
+                for param in command.params:
+                    if count != 0:
+                        out.append(', ')
+                    out.append(param.name)
+                    count += 1
+                out.append(');\n')
+                if command.extensions[0] in NULL_CHECK_EXT_NAMES:
+                    if command.returnType != 'void':
+                        out.append('    } else {\n')
+                        out.append('        return VK_SUCCESS;\n')
+                    out.append('    }\n')
+                out.append('}\n\n')
+
+            if command.protect is not None:
+                out.append(f'#endif // {command.protect}\n')
+
+
+
+    #
+    # Create a function for the extension GPA call
+    def InstExtensionGPA(self, out):
+        cur_extension_name = ''
+
+        out.append( '// GPA helpers for extensions\n')
+        out.append( 'bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr) {\n')
+        out.append( '    *addr = NULL;\n\n')
+
+        for command in [x for x in self.vk.commands.values() if x.extensions]:
+            if (command.version or
+                command.extensions[0] in WSI_EXT_NAMES or
+                command.extensions[0] in AVOID_EXT_NAMES or
+                command.name in AVOID_CMD_NAMES ):
+                continue
+
+            if command.extensions[0] != cur_extension_name:
+                out.append( f'\n    // ---- {command.extensions[0]} extension commands\n')
+                cur_extension_name = command.extensions[0]
+
+            if command.protect is not None:
+                out.append( f'#if defined({command.protect})\n')
+
+            #base_name = command.name[2:]
+            base_name = SHARED_ALIASES[command.name] if command.name in SHARED_ALIASES else command.name[2:]
+
+            if len(command.extensions) > 0 and self.vk.extensions[command.extensions[0]].instance:
+                out.append( f'    if (!strcmp("{command.name}", name)) {{\n')
+                out.append( '        *addr = (ptr_instance->enabled_extensions.')
+                out.append( command.extensions[0][3:].lower())
+                out.append( ' == 1)\n')
+                out.append( f'                     ? (void *){base_name}\n')
+                out.append( '                     : NULL;\n')
+                out.append( '        return true;\n')
+                out.append( '    }\n')
+            else:
+                out.append( f'    if (!strcmp("{command.name}", name)) {{\n')
+                out.append( f'        *addr = (void *){base_name};\n')
+                out.append( '        return true;\n')
+                out.append( '    }\n')
+
+            if command.protect is not None:
+                out.append( f'#endif // {command.protect}\n')
+
+        out.append( '    return false;\n')
+        out.append( '}\n\n')
+
+
+
+    #
+    # Create the extension name init function
+    def InstantExtensionCreate(self, out):
+
+        out.append( '// Used to keep track of all enabled instance extensions\n')
+        out.append( 'void fill_out_enabled_instance_extensions(uint32_t extension_count, const char *const * extension_list, struct loader_instance_extension_enable_list* enables) {\n')
+        out.append( '    for (uint32_t i = 0; i < extension_count; i++) {\n')
+        e = ''
+        cur_extension_name = ''
+        for extension in self.instance_extensions:
+            if extension.name != cur_extension_name:
+                out.append( f'\n    // ---- {extension.name} extension commands\n')
+                cur_extension_name = extension.name
+
+            if extension.protect is not None:
+                out.append( f'#if defined({extension.protect})\n')
+
+            out.append(f'        {e}if (0 == strcmp(extension_list[i], ')
+
+            out.append( f'{extension.nameString})) {{ enables->{extension.name[3:].lower()} = 1; }}\n')
+
+            if extension.protect is not None:
+                out.append( f'#endif // {extension.protect}\n')
+            e = 'else '
+
+        out.append( '    }\n')
+        out.append( '}\n\n')
+
+
+    #
+    # Create code to initialize a dispatch table from the appropriate list of extension entrypoints
+    def DeviceExtensionGetTerminator(self, out):
+        out.append('// Some device commands still need a terminator because the loader needs to unwrap something about them.\n')
+        out.append('// In many cases, the item needing unwrapping is a VkPhysicalDevice or VkSurfaceKHR object.  But there may be other items\n')
+        out.append('// in the future.\n')
+        out.append('PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *name, bool* found_name) {\n')
+        out.append('''    *found_name = false;
+    if (!name || name[0] != 'v' || name[1] != 'k') {
+        return NULL;
+    }
+    name += 2;
+''')
+        last_protect = None
+        last_ext = None
+        for command in [x for x in self.vk.commands.values() if x.extensions]:
+            version = command.version
+            if command.name in DEVICE_CMDS_NEED_TERM:
+                if version:
+                    out.append(f'    // ---- Core {version.name} commands\n')
+                else:
+                    last_protect = command.protect
+                    if command.protect is not None:
+                        out.append(f'#if defined({command.protect})\n')
+                    if last_ext != command.extensions[0]:
+                        out.append(f'    // ---- {command.extensions[0]} extension commands\n')
+                        last_ext = command.extensions[0]
+
+                out.append(f'    if (!strcmp(name, "{command.name[2:]}")) {{\n')
+                out.append('        *found_name = true;\n')
+                enable_extension_expressions = []
+                for ext in command.extensions:
+                    enable_extension_expressions.append(f'dev->driver_extensions.{ext[3:].lower()}_enabled')
+                out.append(f'        return {" || ".join(enable_extension_expressions)} ?\n')
+                out.append(f'            (PFN_vkVoidFunction)terminator_{(command.name[2:])} : NULL;\n')
+                out.append('    }\n')
+
+        if last_protect is not None:
+            out.append(f'#endif // {last_protect}\n')
+
+        out.append('    return NULL;\n')
+        out.append('}\n\n')
+
+
+
+    #
+    # Create code to initialize a dispatch table from the appropriate list of core and extension entrypoints
+    def InitInstLoaderExtensionDispatchTable(self, out):
+        commands = []
+
+        out.append( '// This table contains the loader\'s instance dispatch table, which contains\n')
+        out.append( '// default functions if no instance layers are activated.  This contains\n')
+        out.append( '// pointers to "terminator functions".\n')
+        out.append( 'const VkLayerInstanceDispatchTable instance_disp = {\n')
+
+        for command_list in [self.core_commands, self.extension_commands]:
+            commands = command_list
+
+            current_block = ''
+            for command in commands:
+                if command.params[0].type in ['VkInstance', 'VkPhysicalDevice']:
+                    current_block = self.DescribeBlock(command, current_block, out)
+                    # Remove 'vk' from proto name
+                    base_name = command.name[2:]
+                    aliased_name = SHARED_ALIASES[command.name][2:] if command.name in SHARED_ALIASES else base_name
+
+                    if (base_name == 'CreateInstance' or base_name == 'CreateDevice' or
+                        base_name == 'EnumerateInstanceExtensionProperties' or
+                        base_name == 'EnumerateInstanceLayerProperties' or
+                        base_name == 'EnumerateInstanceVersion'):
+                        continue
+
+                    if command.protect is not None:
+                        out.append( f'#if defined({command.protect})\n')
+
+                    if base_name == 'GetInstanceProcAddr':
+                        out.append( f'    .{base_name} = {command.name},\n')
+                    else:
+                        out.append( f'    .{base_name} = terminator_{aliased_name},\n')
+
+                    if command.protect is not None:
+                        out.append( f'#endif // {command.protect}\n')
+        out.append( '};\n\n')
+
+
+
+    #
+    # Create the extension name whitelist array
+    def OutputInstantExtensionWhitelistArray(self, out):
+        out.append( '// A null-terminated list of all of the instance extensions supported by the loader.\n')
+        out.append( '// If an instance extension name is not in this list, but it is exported by one or more of the\n')
+        out.append( '// ICDs detected by the loader, then the extension name not in the list will be filtered out\n')
+        out.append( '// before passing the list of extensions to the application.\n')
+        out.append( 'const char *const LOADER_INSTANCE_EXTENSIONS[] = {\n')
+        for extension in self.instance_extensions:
+
+            if extension.protect is not None:
+                out.append( f'#if defined({extension.protect})\n')
+            out.append( '                                                  ')
+            out.append( extension.nameString + ',\n')
+
+            if extension.protect is not None:
+                out.append( f'#endif // {extension.protect}\n')
+        out.append( '                                                  NULL };\n')
diff --git a/scripts/generators/vk_result_to_string_generator.py b/scripts/generators/vk_result_to_string_generator.py
new file mode 100644
index 0000000..9efb4aa
--- /dev/null
+++ b/scripts/generators/vk_result_to_string_generator.py
@@ -0,0 +1,79 @@
+#!/usr/bin/python3 -i
+#
+# Copyright (c) 2015-2021 The Khronos Group Inc.
+# Copyright (c) 2015-2021 Valve Corporation
+# Copyright (c) 2015-2021 LunarG, Inc.
+# Copyright (c) 2015-2021 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Author: Mark Lobodzinski <mark@lunarg.com>
+# Author: Charles Giessen <charles@lunarg.com>
+
+import os
+from base_generator import BaseGenerator
+
+class VkResultToStringGenerator(BaseGenerator):
+    def __init__(self):
+        BaseGenerator.__init__(self)
+
+    def generate(self):
+        out = []
+
+        out.append(f'''#pragma once
+// *** THIS FILE IS GENERATED - DO NOT EDIT ***
+// See {os.path.basename(__file__)} for modifications
+
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+
+ */
+
+#include <ostream>
+#include <string>
+
+#include <vulkan/vulkan.h>
+
+''')
+
+        self.OutputVkResultToStringHelper(out)
+        out.append('\n')
+
+        self.write(''.join(out))
+
+    # Create a dispatch table from the corresponding table_type and append it to out
+    def OutputVkResultToStringHelper(self, out: list):
+        out.append('inline std::ostream& operator<<(std::ostream& os, const VkResult& result) {\n')
+        out.append('   switch (result) {\n')
+        for field in self.vk.enums['VkResult'].fields:
+            out.append(f'        case({field.name}):\n')
+            out.append(f'            return os << "{field.name}";\n')
+        out.append('        default:\n')
+        out.append('           return os << static_cast<int32_t>(result);\n')
+        out.append('       }\n')
+        out.append('   }\n')
diff --git a/scripts/helper_file_generator.py b/scripts/helper_file_generator.py
deleted file mode 100644
index a2b9c59..0000000
--- a/scripts/helper_file_generator.py
+++ /dev/null
@@ -1,501 +0,0 @@
-#!/usr/bin/python3 -i
-#
-# Copyright (c) 2015-2017 The Khronos Group Inc.
-# Copyright (c) 2015-2017 Valve Corporation
-# Copyright (c) 2015-2017 LunarG, Inc.
-# Copyright (c) 2015-2017 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Author: Mark Lobodzinski <mark@lunarg.com>
-# Author: Tobin Ehlis <tobine@google.com>
-# Author: John Zulauf <jzulauf@lunarg.com>
-
-import os,re,sys
-import xml.etree.ElementTree as etree
-from generator import *
-from collections import namedtuple
-from common_codegen import *
-
-#
-# HelperFileOutputGeneratorOptions - subclass of GeneratorOptions.
-class HelperFileOutputGeneratorOptions(GeneratorOptions):
-    def __init__(self,
-                 conventions = None,
-                 filename = None,
-                 directory = '.',
-                 genpath = None,
-                 apiname = None,
-                 profile = None,
-                 versions = '.*',
-                 emitversions = '.*',
-                 defaultExtensions = None,
-                 addExtensions = None,
-                 removeExtensions = None,
-                 emitExtensions = None,
-                 sortProcedure = regSortFeatures,
-                 prefixText = "",
-                 genFuncPointers = True,
-                 protectFile = True,
-                 protectFeature = True,
-                 apicall = '',
-                 apientry = '',
-                 apientryp = '',
-                 alignFuncParam = 0,
-                 library_name = '',
-                 expandEnumerants = True,
-                 helper_file_type = ''):
-        GeneratorOptions.__init__(self,
-                conventions = conventions,
-                filename = filename,
-                directory = directory,
-                genpath = genpath,
-                apiname = apiname,
-                profile = profile,
-                versions = versions,
-                emitversions = emitversions,
-                defaultExtensions = defaultExtensions,
-                addExtensions = addExtensions,
-                removeExtensions = removeExtensions,
-                emitExtensions = emitExtensions,
-                sortProcedure = sortProcedure)
-        self.prefixText       = prefixText
-        self.genFuncPointers  = genFuncPointers
-        self.protectFile      = protectFile
-        self.protectFeature   = protectFeature
-        self.apicall          = apicall
-        self.apientry         = apientry
-        self.apientryp        = apientryp
-        self.alignFuncParam   = alignFuncParam
-        self.library_name     = library_name
-        self.helper_file_type = helper_file_type
-#
-# HelperFileOutputGenerator - subclass of OutputGenerator. Outputs Vulkan helper files
-class HelperFileOutputGenerator(OutputGenerator):
-    """Generate helper file based on XML element attributes"""
-    def __init__(self,
-                 errFile = sys.stderr,
-                 warnFile = sys.stderr,
-                 diagFile = sys.stdout):
-        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
-        # Internal state - accumulators for different inner block text
-        self.enum_output = ''                             # string built up of enum string routines
-        # Internal state - accumulators for different inner block text
-        self.structNames = []                             # List of Vulkan struct typenames
-        self.structTypes = dict()                         # Map of Vulkan struct typename to required VkStructureType
-        self.structMembers = []                           # List of StructMemberData records for all Vulkan structs
-        self.object_types = []                            # List of all handle types
-        self.object_type_aliases = []                     # Aliases to handles types (for handles that were extensions)
-        self.debug_report_object_types = []               # Handy copy of debug_report_object_type enum data
-        self.core_object_types = []                       # Handy copy of core_object_type enum data
-        self.device_extension_info = dict()               # Dict of device extension name defines and ifdef values
-        self.instance_extension_info = dict()             # Dict of instance extension name defines and ifdef values
-
-        # Named tuples to store struct and command data
-        self.StructType = namedtuple('StructType', ['name', 'value'])
-        self.CommandParam = namedtuple('CommandParam', ['type', 'name', 'ispointer', 'isstaticarray', 'isconst', 'iscount', 'len', 'extstructs', 'cdecl'])
-        self.StructMemberData = namedtuple('StructMemberData', ['name', 'members', 'ifdef_protect'])
-
-        self.custom_construct_params = {
-            # safe_VkGraphicsPipelineCreateInfo needs to know if subpass has color and\or depth\stencil attachments to use its pointers
-            'VkGraphicsPipelineCreateInfo' :
-                ', const bool uses_color_attachment, const bool uses_depthstencil_attachment',
-            # safe_VkPipelineViewportStateCreateInfo needs to know if viewport and scissor is dynamic to use its pointers
-            'VkPipelineViewportStateCreateInfo' :
-                ', const bool is_dynamic_viewports, const bool is_dynamic_scissors',
-        }
-    #
-    # Called once at the beginning of each run
-    def beginFile(self, genOpts):
-        OutputGenerator.beginFile(self, genOpts)
-        # User-supplied prefix text, if any (list of strings)
-        self.helper_file_type = genOpts.helper_file_type
-        self.library_name = genOpts.library_name
-
-        write("// clang-format off", file=self.outFile)
-
-        # File Comment
-        file_comment = '// *** THIS FILE IS GENERATED - DO NOT EDIT ***\n'
-        file_comment += '// See helper_file_generator.py for modifications\n'
-        write(file_comment, file=self.outFile)
-        # Copyright Notice
-        copyright = ''
-        copyright += '\n'
-        copyright += '/***************************************************************************\n'
-        copyright += ' *\n'
-        copyright += ' * Copyright (c) 2015-2017 The Khronos Group Inc.\n'
-        copyright += ' * Copyright (c) 2015-2017 Valve Corporation\n'
-        copyright += ' * Copyright (c) 2015-2017 LunarG, Inc.\n'
-        copyright += ' * Copyright (c) 2015-2017 Google Inc.\n'
-        copyright += ' *\n'
-        copyright += ' * Licensed under the Apache License, Version 2.0 (the "License");\n'
-        copyright += ' * you may not use this file except in compliance with the License.\n'
-        copyright += ' * You may obtain a copy of the License at\n'
-        copyright += ' *\n'
-        copyright += ' *     http://www.apache.org/licenses/LICENSE-2.0\n'
-        copyright += ' *\n'
-        copyright += ' * Unless required by applicable law or agreed to in writing, software\n'
-        copyright += ' * distributed under the License is distributed on an "AS IS" BASIS,\n'
-        copyright += ' * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n'
-        copyright += ' * See the License for the specific language governing permissions and\n'
-        copyright += ' * limitations under the License.\n'
-        copyright += ' *\n'
-        copyright += ' * Author: Mark Lobodzinski <mark@lunarg.com>\n'
-        copyright += ' * Author: Courtney Goeltzenleuchter <courtneygo@google.com>\n'
-        copyright += ' * Author: Tobin Ehlis <tobine@google.com>\n'
-        copyright += ' * Author: Chris Forbes <chrisforbes@google.com>\n'
-        copyright += ' * Author: John Zulauf<jzulauf@lunarg.com>\n'
-        copyright += ' *\n'
-        copyright += ' ****************************************************************************/\n'
-        write(copyright, file=self.outFile)
-    #
-    # Write generated file content to output file
-    def endFile(self):
-        dest_file = ''
-        dest_file += self.OutputDestFile()
-        # Remove blank lines at EOF
-        if dest_file.endswith('\n'):
-            dest_file = dest_file[:-1]
-        write(dest_file, file=self.outFile)
-        write("// clang-format on", file=self.outFile)
-        # Finish processing in superclass
-        OutputGenerator.endFile(self)
-    #
-    # Override parent class to be notified of the beginning of an extension
-    def beginFeature(self, interface, emit):
-        # Start processing in superclass
-        OutputGenerator.beginFeature(self, interface, emit)
-        self.featureExtraProtect = GetFeatureProtect(interface)
-
-        if interface.tag != 'extension':
-            return
-        name = self.featureName
-        name_define = next(enum.get('name') for enum in interface.findall('require/enum') if enum.get('name').endswith('_EXTENSION_NAME'))
-        requires = interface.get('requires')
-        if requires is not None:
-            required_extensions = requires.split(',')
-        else:
-            required_extensions = list()
-        info = { 'define': name_define, 'ifdef':self.featureExtraProtect, 'reqs':required_extensions }
-        if interface.get('type') == 'instance':
-            self.instance_extension_info[name] = info
-        else:
-            self.device_extension_info[name] = info
-
-    #
-    # Override parent class to be notified of the end of an extension
-    def endFeature(self):
-        # Finish processing in superclass
-        OutputGenerator.endFeature(self)
-    #
-    # Grab group (e.g. C "enum" type) info to output for enum-string conversion helper
-    def genGroup(self, groupinfo, groupName, alias):
-        OutputGenerator.genGroup(self, groupinfo, groupName, alias)
-        groupElem = groupinfo.elem
-        # For enum_string_header
-        if self.helper_file_type == 'enum_string_header':
-            value_set = set()
-            for elem in groupElem.findall('enum'):
-                if elem.get('supported') != 'disabled' and elem.get('alias') is None:
-                    value_set.add(elem.get('name'))
-            self.enum_output += self.GenerateEnumStringConversion(groupName, value_set)
-        elif self.helper_file_type == 'object_types_header':
-            if groupName == 'VkDebugReportObjectTypeEXT':
-                for elem in groupElem.findall('enum'):
-                    if elem.get('supported') != 'disabled':
-                        item_name = elem.get('name')
-                        self.debug_report_object_types.append(item_name)
-            elif groupName == 'VkObjectType':
-                for elem in groupElem.findall('enum'):
-                    if elem.get('supported') != 'disabled':
-                        item_name = elem.get('name')
-                        self.core_object_types.append(item_name)
-
-    #
-    # Called for each type -- if the type is a struct/union, grab the metadata
-    def genType(self, typeinfo, name, alias):
-        OutputGenerator.genType(self, typeinfo, name, alias)
-        typeElem = typeinfo.elem
-        # If the type is a struct type, traverse the imbedded <member> tags generating a structure.
-        # Otherwise, emit the tag text.
-        category = typeElem.get('category')
-        if category == 'handle':
-            if alias:
-                self.object_type_aliases.append((name,alias))
-            else:
-                self.object_types.append(name)
-        elif (category == 'struct' or category == 'union'):
-            self.structNames.append(name)
-            self.genStruct(typeinfo, name, alias)
-    #
-    # Generate a VkStructureType based on a structure typename
-    def genVkStructureType(self, typename):
-        # Add underscore between lowercase then uppercase
-        value = re.sub('([a-z0-9])([A-Z])', r'\1_\2', typename)
-        # Change to uppercase
-        value = value.upper()
-        # Add STRUCTURE_TYPE_
-        return re.sub('VK_', 'VK_STRUCTURE_TYPE_', value)
-    #
-    # Check if the parameter passed in is a pointer
-    def paramIsPointer(self, param):
-        ispointer = False
-        for elem in param:
-            if ((elem.tag != 'type') and (elem.tail is not None)) and '*' in elem.tail:
-                ispointer = True
-        return ispointer
-    #
-    # Check if the parameter passed in is a static array
-    def paramIsStaticArray(self, param):
-        isstaticarray = 0
-        paramname = param.find('name')
-        if (paramname.tail is not None) and ('[' in paramname.tail):
-            isstaticarray = paramname.tail.count('[')
-        return isstaticarray
-    #
-    # Retrieve the type and name for a parameter
-    def getTypeNameTuple(self, param):
-        type = ''
-        name = ''
-        for elem in param:
-            if elem.tag == 'type':
-                type = noneStr(elem.text)
-            elif elem.tag == 'name':
-                name = noneStr(elem.text)
-        return (type, name)
-    #
-    # Retrieve the value of the len tag
-    def getLen(self, param):
-        result = None
-        len = param.attrib.get('len')
-        if len and len != 'null-terminated':
-            # For string arrays, 'len' can look like 'count,null-terminated', indicating that we
-            # have a null terminated array of strings.  We strip the null-terminated from the
-            # 'len' field and only return the parameter specifying the string count
-            if 'null-terminated' in len:
-                result = len.split(',')[0]
-            else:
-                result = len
-            if 'altlen' in param.attrib:
-                # Elements with latexmath 'len' also contain a C equivalent 'altlen' attribute
-                # Use indexing operator instead of get() so we fail if the attribute is missing
-                result = param.attrib['altlen']
-            # Spec has now notation for len attributes, using :: instead of platform specific pointer symbol
-            result = str(result).replace('::', '->')
-        return result
-    #
-    # Check if a structure is or contains a dispatchable (dispatchable = True) or
-    # non-dispatchable (dispatchable = False) handle
-    def TypeContainsObjectHandle(self, handle_type, dispatchable):
-        if dispatchable:
-            type_key = 'VK_DEFINE_HANDLE'
-        else:
-            type_key = 'VK_DEFINE_NON_DISPATCHABLE_HANDLE'
-        handle = self.registry.tree.find("types/type/[name='" + handle_type + "'][@category='handle']")
-        if handle is not None and handle.find('type').text == type_key:
-            return True
-        # if handle_type is a struct, search its members
-        if handle_type in self.structNames:
-            member_index = next((i for i, v in enumerate(self.structMembers) if v[0] == handle_type), None)
-            if member_index is not None:
-                for item in self.structMembers[member_index].members:
-                    handle = self.registry.tree.find("types/type/[name='" + item.type + "'][@category='handle']")
-                    if handle is not None and handle.find('type').text == type_key:
-                        return True
-        return False
-    #
-    # Generate local ready-access data describing Vulkan structures and unions from the XML metadata
-    def genStruct(self, typeinfo, typeName, alias):
-        OutputGenerator.genStruct(self, typeinfo, typeName, alias)
-        members = typeinfo.elem.findall('.//member')
-        # Iterate over members once to get length parameters for arrays
-        lens = set()
-        for member in members:
-            len = self.getLen(member)
-            if len:
-                lens.add(len)
-        # Generate member info
-        membersInfo = []
-        for member in members:
-            # Get the member's type and name
-            info = self.getTypeNameTuple(member)
-            type = info[0]
-            name = info[1]
-            cdecl = self.makeCParamDecl(member, 1)
-            # Process VkStructureType
-            if type == 'VkStructureType':
-                # Extract the required struct type value from the comments
-                # embedded in the original text defining the 'typeinfo' element
-                rawXml = etree.tostring(typeinfo.elem).decode('ascii')
-                result = re.search(r'VK_STRUCTURE_TYPE_\w+', rawXml)
-                if result:
-                    value = result.group(0)
-                else:
-                    value = self.genVkStructureType(typeName)
-                # Store the required type value
-                self.structTypes[typeName] = self.StructType(name=name, value=value)
-            # Store pointer/array/string info
-            isstaticarray = self.paramIsStaticArray(member)
-            membersInfo.append(self.CommandParam(type=type,
-                                                 name=name,
-                                                 ispointer=self.paramIsPointer(member),
-                                                 isstaticarray=isstaticarray,
-                                                 isconst=True if 'const' in cdecl else False,
-                                                 iscount=True if name in lens else False,
-                                                 len=self.getLen(member),
-                                                 extstructs=self.registry.validextensionstructs[typeName] if name == 'pNext' else None,
-                                                 cdecl=cdecl))
-        self.structMembers.append(self.StructMemberData(name=typeName, members=membersInfo, ifdef_protect=self.featureExtraProtect))
-    #
-    # Enum_string_header: Create a routine to convert an enumerated value into a string
-    def GenerateEnumStringConversion(self, groupName, value_list):
-        outstring = '\n'
-        outstring += 'static inline const char* string_%s(%s input_value)\n' % (groupName, groupName)
-        outstring += '{\n'
-        outstring += '    switch ((%s)input_value)\n' % groupName
-        outstring += '    {\n'
-        for item in value_list:
-            outstring += '        case %s:\n' % item
-            outstring += '            return "%s";\n' % item
-        outstring += '        default:\n'
-        outstring += '            return "Unhandled %s";\n' % groupName
-        outstring += '    }\n'
-        outstring += '}\n'
-        return outstring
-    #
-    # Combine object types helper header file preamble with body text and return
-    def GenerateObjectTypesHelperHeader(self):
-        object_types_helper_header = '\n'
-        object_types_helper_header += '#pragma once\n'
-        object_types_helper_header += '\n'
-        object_types_helper_header += '#include <vulkan/vulkan.h>\n\n'
-        object_types_helper_header += self.GenerateObjectTypesHeader()
-        return object_types_helper_header
-    #
-    # Object types header: create object enum type header file
-    def GenerateObjectTypesHeader(self):
-        object_types_header = ''
-        object_types_header += '// Object Type enum for validation layer internal object handling\n'
-        object_types_header += 'typedef enum VulkanObjectType {\n'
-        object_types_header += '    kVulkanObjectTypeUnknown = 0,\n'
-        enum_num = 1
-        type_list = [];
-        enum_entry_map = {}
-
-        # Output enum definition as each handle is processed, saving the names to use for the conversion routine
-        for item in self.object_types:
-            fixup_name = item[2:]
-            enum_entry = 'kVulkanObjectType%s' % fixup_name
-            enum_entry_map[item] = enum_entry
-            object_types_header += '    ' + enum_entry
-            object_types_header += ' = %d,\n' % enum_num
-            enum_num += 1
-            type_list.append(enum_entry)
-        object_types_header += '    kVulkanObjectTypeMax = %d,\n' % enum_num
-        object_types_header += '    // Aliases for backwards compatibilty of "promoted" types\n'
-        for (name, alias) in self.object_type_aliases:
-            fixup_name = name[2:]
-            object_types_header += '    kVulkanObjectType{} = {},\n'.format(fixup_name, enum_entry_map[alias])
-        object_types_header += '} VulkanObjectType;\n\n'
-
-        # Output name string helper
-        object_types_header += '// Array of object name strings for OBJECT_TYPE enum conversion\n'
-        object_types_header += 'static const char * const object_string[kVulkanObjectTypeMax] = {\n'
-        object_types_header += '    "Unknown",\n'
-        for item in self.object_types:
-            fixup_name = item[2:]
-            object_types_header += '    "%s",\n' % fixup_name
-        object_types_header += '};\n'
-
-        # Key creation helper for map comprehensions that convert between k<Name> and VK<Name> symbols
-        def to_key(regex, raw_key): return re.search(regex, raw_key).group(1).lower().replace("_","")
-
-        # Output a conversion routine from the layer object definitions to the debug report definitions
-        # As the VK_DEBUG_REPORT types are not being updated, specify UNKNOWN for unmatched types
-        object_types_header += '\n'
-        object_types_header += '// Helper array to get Vulkan VK_EXT_debug_report object type enum from the internal layers version\n'
-        object_types_header += 'const VkDebugReportObjectTypeEXT get_debug_report_enum[] = {\n'
-        object_types_header += '    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeUnknown\n'
-
-        dbg_re = '^VK_DEBUG_REPORT_OBJECT_TYPE_(.*?)(_EXT)?$'
-        dbg_map = {to_key(dbg_re, dbg) : dbg for dbg in self.debug_report_object_types}
-        dbg_default = 'VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT'
-        for object_type in type_list:
-            vk_object_type = dbg_map.get(object_type.replace("kVulkanObjectType", "").lower(), dbg_default)
-            object_types_header += '    %s,   // %s\n' % (vk_object_type, object_type)
-        object_types_header += '};\n'
-
-        # Output a conversion routine from the layer object definitions to the core object type definitions
-        # This will intentionally *fail* for unmatched types as the VK_OBJECT_TYPE list should match the kVulkanObjectType list
-        object_types_header += '\n'
-        object_types_header += '// Helper array to get Official Vulkan VkObjectType enum from the internal layers version\n'
-        object_types_header += 'const VkObjectType get_object_type_enum[] = {\n'
-        object_types_header += '    VK_OBJECT_TYPE_UNKNOWN, // kVulkanObjectTypeUnknown\n'
-
-        vko_re = '^VK_OBJECT_TYPE_(.*)'
-        vko_map = {to_key(vko_re, vko) : vko for vko in self.core_object_types}
-        for object_type in type_list:
-            vk_object_type = vko_map[object_type.replace("kVulkanObjectType", "").lower()]
-            object_types_header += '    %s,   // %s\n' % (vk_object_type, object_type)
-        object_types_header += '};\n'
-
-        # Create a function to convert from VkDebugReportObjectTypeEXT to VkObjectType
-        object_types_header += '\n'
-        object_types_header += '// Helper function to convert from VkDebugReportObjectTypeEXT to VkObjectType\n'
-        object_types_header += 'static inline VkObjectType convertDebugReportObjectToCoreObject(VkDebugReportObjectTypeEXT debug_report_obj){\n'
-        object_types_header += '    if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT) {\n'
-        object_types_header += '        return VK_OBJECT_TYPE_UNKNOWN;\n'
-        for core_object_type in self.core_object_types:
-            core_target_type = core_object_type.replace("VK_OBJECT_TYPE_", "").lower()
-            core_target_type = core_target_type.replace("_", "")
-            for dr_object_type in self.debug_report_object_types:
-                dr_target_type = dr_object_type.replace("VK_DEBUG_REPORT_OBJECT_TYPE_", "").lower()
-                dr_target_type = dr_target_type[:-4]
-                dr_target_type = dr_target_type.replace("_", "")
-                if core_target_type == dr_target_type:
-                    object_types_header += '    } else if (debug_report_obj == %s) {\n' % dr_object_type
-                    object_types_header += '        return %s;\n' % core_object_type
-                    break
-        object_types_header += '    }\n'
-        object_types_header += '    return VK_OBJECT_TYPE_UNKNOWN;\n'
-        object_types_header += '}\n'
-
-        # Create a function to convert from VkObjectType to VkDebugReportObjectTypeEXT
-        object_types_header += '\n'
-        object_types_header += '// Helper function to convert from VkDebugReportObjectTypeEXT to VkObjectType\n'
-        object_types_header += 'static inline VkDebugReportObjectTypeEXT convertCoreObjectToDebugReportObject(VkObjectType core_report_obj){\n'
-        object_types_header += '    if (core_report_obj == VK_OBJECT_TYPE_UNKNOWN) {\n'
-        object_types_header += '        return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;\n'
-        for core_object_type in self.core_object_types:
-            core_target_type = core_object_type.replace("VK_OBJECT_TYPE_", "").lower()
-            core_target_type = core_target_type.replace("_", "")
-            for dr_object_type in self.debug_report_object_types:
-                dr_target_type = dr_object_type.replace("VK_DEBUG_REPORT_OBJECT_TYPE_", "").lower()
-                dr_target_type = dr_target_type[:-4]
-                dr_target_type = dr_target_type.replace("_", "")
-                if core_target_type == dr_target_type:
-                    object_types_header += '    } else if (core_report_obj == %s) {\n' % core_object_type
-                    object_types_header += '        return %s;\n' % dr_object_type
-                    break
-        object_types_header += '    }\n'
-        object_types_header += '    return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;\n'
-        object_types_header += '}\n'
-        return object_types_header
-
-    #
-    # Create a helper file and return it as a string
-    def OutputDestFile(self):
-        if self.helper_file_type == 'object_types_header':
-            return self.GenerateObjectTypesHelperHeader()
-        else:
-            return 'Bad Helper File Generator Option %s' % self.helper_file_type
diff --git a/scripts/known_good.json b/scripts/known_good.json
index aaab82e..0dd54d9 100644
--- a/scripts/known_good.json
+++ b/scripts/known_good.json
@@ -7,7 +7,7 @@
             "sub_dir": "Vulkan-Headers",
             "build_dir": "Vulkan-Headers/build",
             "install_dir": "Vulkan-Headers/build/install",
-            "commit": "v1.4.304"
+            "commit": "v1.4.350"
         },
         {
             "name": "googletest",
@@ -42,4 +42,4 @@
         "googletest": "GOOGLETEST_INSTALL_DIR",
         "detours": "DETOURS_INSTALL_DIR"
     }
-}
\ No newline at end of file
+}
diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py
deleted file mode 100644
index 938c3bb..0000000
--- a/scripts/loader_extension_generator.py
+++ /dev/null
@@ -1,1772 +0,0 @@
-#!/usr/bin/python3 -i
-#
-# Copyright (c) 2015-2022 The Khronos Group Inc.
-# Copyright (c) 2015-2022 Valve Corporation
-# Copyright (c) 2015-2022 LunarG, Inc.
-# Copyright (c) 2015-2017 Google Inc.
-# Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# Copyright (c) 2023-2023 RasterGrid Kft.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Author: Mark Young <marky@lunarg.com>
-# Author: Mark Lobodzinski <mark@lunarg.com>
-
-import re
-import sys
-from collections import namedtuple
-from generator import *
-from common_codegen import *
-
-
-WSI_EXT_NAMES = ['VK_KHR_surface',
-                 'VK_KHR_display',
-                 'VK_KHR_xlib_surface',
-                 'VK_KHR_xcb_surface',
-                 'VK_KHR_wayland_surface',
-                 'VK_EXT_directfb_surface',
-                 'VK_KHR_win32_surface',
-                 'VK_KHR_android_surface',
-                 'VK_GGP_stream_descriptor_surface',
-                 'VK_MVK_macos_surface',
-                 'VK_MVK_ios_surface',
-                 'VK_EXT_headless_surface',
-                 'VK_EXT_metal_surface',
-                 'VK_FUCHSIA_imagepipe_surface',
-                 'VK_KHR_swapchain',
-                 'VK_KHR_display_swapchain',
-                 'VK_KHR_get_display_properties2',
-                 'VK_FUCHSIA_imagepipe_surface',
-                 'VK_KHR_get_surface_capabilities2',
-                 'VK_QNX_screen_surface',
-                 'VK_NN_vi_surface']
-
-ADD_INST_CMDS = ['vkCreateInstance',
-                 'vkEnumerateInstanceExtensionProperties',
-                 'vkEnumerateInstanceLayerProperties',
-                 'vkEnumerateInstanceVersion']
-
-AVOID_EXT_NAMES = ['VK_EXT_debug_report']
-
-NULL_CHECK_EXT_NAMES= ['VK_EXT_debug_utils']
-
-AVOID_CMD_NAMES = ['vkCreateDebugUtilsMessengerEXT',
-                   'vkDestroyDebugUtilsMessengerEXT',
-                   'vkSubmitDebugUtilsMessageEXT']
-
-DEVICE_CMDS_NEED_TERM = ['vkGetDeviceProcAddr',
-                         'vkCreateSwapchainKHR',
-                         'vkCreateSharedSwapchainsKHR',
-                         'vkGetDeviceGroupSurfacePresentModesKHR',
-                         'vkDebugMarkerSetObjectTagEXT',
-                         'vkDebugMarkerSetObjectNameEXT',
-                         'vkSetDebugUtilsObjectNameEXT',
-                         'vkSetDebugUtilsObjectTagEXT',
-                         'vkQueueBeginDebugUtilsLabelEXT',
-                         'vkQueueEndDebugUtilsLabelEXT',
-                         'vkQueueInsertDebugUtilsLabelEXT',
-                         'vkCmdBeginDebugUtilsLabelEXT',
-                         'vkCmdEndDebugUtilsLabelEXT',
-                         'vkCmdInsertDebugUtilsLabelEXT',
-                         'vkGetDeviceGroupSurfacePresentModes2EXT']
-
-DEVICE_CMDS_MUST_USE_TRAMP = ['vkSetDebugUtilsObjectNameEXT',
-                              'vkSetDebugUtilsObjectTagEXT',
-                              'vkDebugMarkerSetObjectNameEXT',
-                              'vkDebugMarkerSetObjectTagEXT']
-
-# These are the aliased functions that use the same terminator for both extension and core versions
-# Generally, this is only applies to physical device level functions in instance extensions
-SHARED_ALIASES = {
-    # 1.1 aliases
-    'vkEnumeratePhysicalDeviceGroupsKHR':                   'vkEnumeratePhysicalDeviceGroups',
-    'vkGetPhysicalDeviceFeatures2KHR':                      'vkGetPhysicalDeviceFeatures2',
-    'vkGetPhysicalDeviceProperties2KHR':                    'vkGetPhysicalDeviceProperties2',
-    'vkGetPhysicalDeviceFormatProperties2KHR':              'vkGetPhysicalDeviceFormatProperties2',
-    'vkGetPhysicalDeviceImageFormatProperties2KHR':         'vkGetPhysicalDeviceImageFormatProperties2',
-    'vkGetPhysicalDeviceQueueFamilyProperties2KHR':         'vkGetPhysicalDeviceQueueFamilyProperties2',
-    'vkGetPhysicalDeviceMemoryProperties2KHR':              'vkGetPhysicalDeviceMemoryProperties2',
-    'vkGetPhysicalDeviceSparseImageFormatProperties2KHR':   'vkGetPhysicalDeviceSparseImageFormatProperties2',
-    'vkGetPhysicalDeviceExternalBufferPropertiesKHR':       'vkGetPhysicalDeviceExternalBufferProperties',
-    'vkGetPhysicalDeviceExternalSemaphorePropertiesKHR':    'vkGetPhysicalDeviceExternalSemaphoreProperties',
-    'vkGetPhysicalDeviceExternalFencePropertiesKHR':        'vkGetPhysicalDeviceExternalFenceProperties',
-}
-
-PRE_INSTANCE_FUNCTIONS = ['vkEnumerateInstanceExtensionProperties',
-                          'vkEnumerateInstanceLayerProperties',
-                          'vkEnumerateInstanceVersion']
-
-#
-# API Version
-class APIVersion:
-    def __init__(self, token, apiname = 'Vulkan', supported = True):
-        self.token = token
-        self.constant = token.replace('_VERSION_', '_API_VERSION_')
-        self.number = token[token.find('_VERSION_') + len('_VERSION_'):].replace('_', '.')
-        self.name = f'{apiname} {self.number}'
-        self.supported = supported
-
-#
-# LoaderExtensionGeneratorOptions - subclass of GeneratorOptions.
-class LoaderExtensionGeneratorOptions(GeneratorOptions):
-    def __init__(self,
-                 conventions = None,
-                 filename = None,
-                 directory = '.',
-                 genpath = None,
-                 apiname = None,
-                 profile = None,
-                 versions = '.*',
-                 emitversions = '.*',
-                 defaultExtensions = None,
-                 addExtensions = None,
-                 removeExtensions = None,
-                 emitExtensions = None,
-                 sortProcedure = regSortFeatures,
-                 prefixText = "",
-                 genFuncPointers = True,
-                 protectFile = True,
-                 protectFeature = True,
-                 apicall = '',
-                 apientry = '',
-                 apientryp = '',
-                 indentFuncProto = True,
-                 indentFuncPointer = False,
-                 alignFuncParam = 0,
-                 expandEnumerants = True):
-        GeneratorOptions.__init__(self,
-                conventions = conventions,
-                filename = filename,
-                directory = directory,
-                genpath = genpath,
-                apiname = apiname,
-                profile = profile,
-                versions = versions,
-                emitversions = emitversions,
-                defaultExtensions = defaultExtensions,
-                addExtensions = addExtensions,
-                removeExtensions = removeExtensions,
-                emitExtensions = emitExtensions,
-                sortProcedure = sortProcedure)
-        self.prefixText      = prefixText
-        self.prefixText      = None
-        self.apicall         = apicall
-        self.apientry        = apientry
-        self.apientryp       = apientryp
-        self.alignFuncParam  = alignFuncParam
-        self.expandEnumerants = expandEnumerants
-
-#
-# LoaderExtensionOutputGenerator - subclass of OutputGenerator.
-# Generates dispatch table helper header files for LVL
-class LoaderExtensionOutputGenerator(OutputGenerator):
-    """Generate dispatch table helper header based on XML element attributes"""
-    def __init__(self,
-                 errFile = sys.stderr,
-                 warnFile = sys.stderr,
-                 diagFile = sys.stdout):
-        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
-
-        # Internal state - accumulators for different inner block text
-        self.ext_instance_dispatch_list = []  # List of extension entries for instance dispatch list
-        self.ext_device_dispatch_list = []    # List of extension entries for device dispatch list
-        self.core_commands = []               # List of CommandData records for core Vulkan commands
-        self.ext_commands = []                # List of CommandData records for extension Vulkan commands
-        self.CommandParam = namedtuple('CommandParam', ['type', 'name', 'cdecl'])
-        self.CommandData = namedtuple('CommandData', ['name', 'ext_name', 'ext_type', 'require', 'protect', 'return_type', 'handle_type', 'params', 'cdecl'])
-        self.instanceExtensions = []
-        self.ExtensionData = namedtuple('ExtensionData', ['name', 'type', 'protect', 'define', 'num_commands'])
-
-    #
-    # Called once at the beginning of each run
-    def beginFile(self, genOpts):
-        OutputGenerator.beginFile(self, genOpts)
-
-        # User-supplied prefix text, if any (list of strings)
-        if genOpts.prefixText:
-            for s in genOpts.prefixText:
-                write(s, file=self.outFile)
-
-        # File Comment
-        file_comment = '// *** THIS FILE IS GENERATED - DO NOT EDIT ***\n'
-        file_comment += '// See loader_extension_generator.py for modifications\n'
-        write(file_comment, file=self.outFile)
-
-        # Copyright Notice
-        copyright =  '/*\n'
-        copyright += ' * Copyright (c) 2015-2022 The Khronos Group Inc.\n'
-        copyright += ' * Copyright (c) 2015-2022 Valve Corporation\n'
-        copyright += ' * Copyright (c) 2015-2022 LunarG, Inc.\n'
-        copyright += ' * Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n'
-        copyright += ' * Copyright (c) 2023-2023 RasterGrid Kft.\n'
-        copyright += ' *\n'
-        copyright += ' * Licensed under the Apache License, Version 2.0 (the "License");\n'
-        copyright += ' * you may not use this file except in compliance with the License.\n'
-        copyright += ' * You may obtain a copy of the License at\n'
-        copyright += ' *\n'
-        copyright += ' *     http://www.apache.org/licenses/LICENSE-2.0\n'
-        copyright += ' *\n'
-        copyright += ' * Unless required by applicable law or agreed to in writing, software\n'
-        copyright += ' * distributed under the License is distributed on an "AS IS" BASIS,\n'
-        copyright += ' * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n'
-        copyright += ' * See the License for the specific language governing permissions and\n'
-        copyright += ' * limitations under the License.\n'
-        copyright += ' *\n'
-        copyright += ' * Author: Mark Lobodzinski <mark@lunarg.com>\n'
-        copyright += ' * Author: Mark Young <marky@lunarg.com>\n'
-        copyright += ' */\n'
-
-        preamble = ''
-
-        preamble += '// clang-format off\n'
-
-        if self.genOpts.filename == 'vk_loader_extensions.h':
-            preamble += '#pragma once\n'
-            preamble += '\n'
-            preamble += '#include <stdbool.h>\n'
-            preamble += '#include <vulkan/vulkan.h>\n'
-            preamble += '#include <vulkan/vk_layer.h>\n'
-            preamble += '#include "vk_layer_dispatch_table.h"\n'
-            preamble += '\n'
-
-
-        elif self.genOpts.filename == 'vk_loader_extensions.c':
-            preamble += '#include <stdio.h>\n'
-            preamble += '#include <stdlib.h>\n'
-            preamble += '#include <string.h>\n'
-            preamble += '#include "loader.h"\n'
-            preamble += '#include "vk_loader_extensions.h"\n'
-            preamble += '#include <vulkan/vk_icd.h>\n'
-            preamble += '#include "wsi.h"\n'
-            preamble += '#include "debug_utils.h"\n'
-            preamble += '#include "extension_manual.h"\n'
-
-        elif self.genOpts.filename == 'vk_layer_dispatch_table.h':
-            preamble += '#pragma once\n'
-            preamble += '\n'
-            preamble += '#include <vulkan/vulkan.h>\n'
-            preamble += '\n'
-            preamble += '#if !defined(PFN_GetPhysicalDeviceProcAddr)\n'
-            preamble += 'typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName);\n'
-            preamble += '#endif\n'
-
-        write(copyright, file=self.outFile)
-        write(preamble, file=self.outFile)
-
-    #
-    # Write generate and write dispatch tables to output file
-    def endFile(self):
-        file_data = ''
-
-        if self.genOpts.filename == 'vk_loader_extensions.h':
-            file_data += self.OutputPrototypesInHeader()
-            file_data += self.OutputLoaderTerminators()
-            file_data += self.OutputIcdDispatchTable()
-            file_data += self.OutputIcdExtensionEnableUnion()
-            file_data += self.OutputDeviceFunctionTerminatorDispatchTable()
-
-        elif self.genOpts.filename == 'vk_loader_extensions.c':
-            file_data += self.OutputUtilitiesInSource()
-            file_data += self.OutputIcdDispatchTableInit()
-            file_data += self.OutputLoaderDispatchTables()
-            file_data += self.InitDeviceFunctionTerminatorDispatchTable()
-            file_data += self.OutputDeviceFunctionTrampolinePrototypes()
-            file_data += self.OutputLoaderLookupFunc()
-            file_data += self.CreateTrampTermFuncs()
-            file_data += self.InstExtensionGPA()
-            file_data += self.InstantExtensionCreate()
-            file_data += self.DeviceExtensionGetTerminator()
-            file_data += self.InitInstLoaderExtensionDispatchTable()
-            file_data += self.OutputInstantExtensionWhitelistArray()
-
-        elif self.genOpts.filename == 'vk_layer_dispatch_table.h':
-            file_data += self.OutputLayerInstanceDispatchTable()
-            file_data += self.OutputLayerDeviceDispatchTable()
-
-        file_data += '// clang-format on'
-
-        write(file_data, file=self.outFile)
-
-        # Finish processing in superclass
-        OutputGenerator.endFile(self)
-
-    def beginFeature(self, interface, emit):
-        # Start processing in superclass
-        OutputGenerator.beginFeature(self, interface, emit)
-        self.featureExtraProtect = GetFeatureProtect(interface)
-
-        enums = interface[0].findall('enum')
-        self.currentExtension = ''
-        self.name_definition = ''
-
-        for item in enums:
-            name_definition = item.get('name')
-            if 'EXTENSION_NAME' in name_definition:
-                self.name_definition = name_definition
-
-        self.type = interface.get('type')
-        self.num_commands = 0
-        name = interface.get('name')
-        self.currentExtension = name
-
-    #
-    # Process commands, adding to appropriate dispatch tables
-    def genCmd(self, cmdinfo, name, alias):
-        OutputGenerator.genCmd(self, cmdinfo, name, alias)
-
-        # Get first param type
-        params = cmdinfo.elem.findall('param')
-        info = self.getTypeNameTuple(params[0])
-
-        self.num_commands += 1
-
-        if 'android' not in name:
-            self.AddCommandToDispatchList(self.currentExtension, self.type, name, cmdinfo, info[0])
-
-    def endFeature(self):
-
-        if 'android' not in self.currentExtension:
-            self.instanceExtensions.append(self.ExtensionData(name=self.currentExtension,
-                                                              type=self.type,
-                                                              protect=self.featureExtraProtect,
-                                                              define=self.name_definition,
-                                                              num_commands=self.num_commands))
-
-        # Finish processing in superclass
-        OutputGenerator.endFeature(self)
-
-    #
-    # Retrieve the value of the len tag
-    def getLen(self, param):
-        result = None
-        length = param.attrib.get('len')
-        if length and length != 'null-terminated':
-            # For string arrays, 'len' can look like 'count,null-terminated',
-            # indicating that we have a null terminated array of strings.  We
-            # strip the null-terminated from the 'len' field and only return
-            # the parameter specifying the string count
-            if 'null-terminated' in length:
-                result = length.split(',')[0]
-            else:
-                result = length
-            result = str(result).replace('::', '->')
-        return result
-
-    #
-    # Returns an APIVersion object corresponding to the specified version token or None
-    def getAPIVersion(self, token):
-        if self.genOpts.apiname == 'vulkansc':
-            if token in ['VK_VERSION_1_0', 'VK_VERSION_1_1', 'VK_VERSION_1_2']:
-                # Vulkan 1.0-1.2 is included in Vulkan SC 1.0
-                token = 'VKSC_VERSION_1_0'
-
-            if token.startswith('VKSC_VERSION_'):
-                return APIVersion(token, 'Vulkan SC', True)
-            elif token.startswith('VK_VERSION_'):
-                # Unsupported Vulkan version
-                return APIVersion(token, 'Vulkan', False)
-            else:
-                return None
-
-        if token.startswith('VK_VERSION_'):
-            return APIVersion(token)
-        return None
-
-    #
-    # Determine if this API should be ignored or added to the instance or device dispatch table
-    def AddCommandToDispatchList(self, extension_name, extension_type, name, cmdinfo, handle_type):
-        handle = self.registry.tree.find("types/type/[name='" + handle_type + "'][@category='handle']")
-
-        return_type =  cmdinfo.elem.find('proto/type')
-        if (return_type is not None and return_type.text == 'void'):
-            return_type = None
-
-        require = None
-        if name == 'vkGetDeviceGroupSurfacePresentModes2EXT':
-            require_node = self.registry.tree.find(f"./extensions/extension[@name='{extension_name}']/require/command[@name='{name}']/..")
-            if 'depends' in require_node.attrib:
-                require = require_node.attrib['depends']
-
-        cmd_params = []
-
-        # Generate a list of commands for use in printing the necessary
-        # core instance terminator prototypes
-        params = cmdinfo.elem.findall('param')
-        lens = set()
-        for param in params:
-            length = self.getLen(param)
-            if length:
-                lens.add(length)
-
-        for param in params:
-            paramInfo = self.getTypeNameTuple(param)
-            param_type = paramInfo[0]
-            param_name = paramInfo[1]
-            param_cdecl = self.makeCParamDecl(param, 0)
-            cmd_params.append(self.CommandParam(type=param_type, name=param_name,
-                                                cdecl=param_cdecl))
-
-        version = self.getAPIVersion(extension_name)
-        if version and not version.supported:
-            # Skip commands in unsupported versions
-            return
-
-        if handle is not None and handle_type != 'VkInstance' and handle_type != 'VkPhysicalDevice':
-            # The Core Vulkan code will be wrapped in a feature called VK_VERSION_#_#
-            # For example: VK_VERSION_1_0 wraps the core 1.0 Vulkan functionality
-            if version:
-                self.core_commands.append(
-                    self.CommandData(name=name, ext_name=version.token,
-                                     ext_type='device',
-                                     require=require,
-                                     protect=self.featureExtraProtect,
-                                     return_type = return_type,
-                                     handle_type = handle_type,
-                                     params = cmd_params,
-                                     cdecl=self.makeCDecls(cmdinfo.elem)[0]))
-            else:
-                self.ext_device_dispatch_list.append((name, self.featureExtraProtect))
-                self.ext_commands.append(
-                    self.CommandData(name=name, ext_name=extension_name,
-                                     ext_type=extension_type,
-                                     require=require,
-                                     protect=self.featureExtraProtect,
-                                     return_type = return_type,
-                                     handle_type = handle_type,
-                                     params = cmd_params,
-                                     cdecl=self.makeCDecls(cmdinfo.elem)[0]))
-        else:
-            # The Core Vulkan code will be wrapped in a feature called VK_VERSION_#_#
-            # For example: VK_VERSION_1_0 wraps the core 1.0 Vulkan functionality
-            if version:
-                self.core_commands.append(
-                    self.CommandData(name=name, ext_name=version.token,
-                                     ext_type='instance',
-                                     require=require,
-                                     protect=self.featureExtraProtect,
-                                     return_type = return_type,
-                                     handle_type = handle_type,
-                                     params = cmd_params,
-                                     cdecl=self.makeCDecls(cmdinfo.elem)[0]))
-
-            else:
-                self.ext_instance_dispatch_list.append((name, self.featureExtraProtect))
-                self.ext_commands.append(
-                    self.CommandData(name=name, ext_name=extension_name,
-                                     ext_type=extension_type,
-                                     require=require,
-                                     protect=self.featureExtraProtect,
-                                     return_type = return_type,
-                                     handle_type = handle_type,
-                                     params = cmd_params,
-                                     cdecl=self.makeCDecls(cmdinfo.elem)[0]))
-
-    #
-    # Retrieve the type and name for a parameter
-    def getTypeNameTuple(self, param):
-        t = ''
-        n = ''
-        for elem in param:
-            if elem.tag == 'type':
-                t = noneStr(elem.text)
-            elif elem.tag == 'name':
-                n = noneStr(elem.text)
-        return (t, n)
-
-    # Convert an XML dependency expression to a C expression, taking a callback to replace extension names
-    # See https://registry.khronos.org/vulkan/specs/1.4/registry.html#depends-expressions
-    @staticmethod
-    def ConvertDependencyExpression(expr, replace_func):
-        # '(' and ')' can pass through unchanged
-        expr = re.sub(',', ' || ', expr)
-        expr = re.sub(r'\+', ' && ', expr)
-        expr = re.sub(r'\w+', lambda match: replace_func(match.group()), expr)
-        return expr
-
-    def OutputPrototypesInHeader(self):
-        protos = ''
-        protos += '// Structures defined externally, but used here\n'
-        protos += 'struct loader_instance;\n'
-        protos += 'struct loader_device;\n'
-        protos += 'struct loader_icd_term;\n'
-        protos += 'struct loader_dev_dispatch_table;\n'
-        protos += '\n'
-        protos += '// Device extension error function\n'
-        protos += 'VKAPI_ATTR VkResult VKAPI_CALL vkDevExtError(VkDevice dev);\n'
-        protos += '\n'
-        protos += '// Extension interception for vkGetInstanceProcAddr function, so we can return\n'
-        protos += '// the appropriate information for any instance extensions we know about.\n'
-        protos += 'bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr);\n'
-        protos += '\n'
-        protos += '// Extension interception for vkCreateInstance function, so we can properly\n'
-        protos += '// detect and enable any instance extension information for extensions we know\n'
-        protos += '// about.\n'
-        protos += 'void extensions_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo);\n'
-        protos += '\n'
-        protos += '// Extension interception for vkGetDeviceProcAddr function, so we can return\n'
-        protos += '// an appropriate terminator if this is one of those few device commands requiring\n'
-        protos += '// a terminator.\n'
-        protos += 'PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *name, bool* found_name);\n'
-        protos += '\n'
-        protos += '// Dispatch table properly filled in with appropriate terminators for the\n'
-        protos += '// supported extensions.\n'
-        protos += 'extern const VkLayerInstanceDispatchTable instance_disp;\n'
-        protos += '\n'
-        protos += '// Array of extension strings for instance extensions we support.\n'
-        protos += 'extern const char *const LOADER_INSTANCE_EXTENSIONS[];\n'
-        protos += '\n'
-        protos += 'VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_instance* inst, struct loader_icd_term *icd_term);\n'
-        protos += '\n'
-        protos += '// Init Device function pointer dispatch table with core commands\n'
-        protos += 'VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_dispatch_table *dev_table, PFN_vkGetDeviceProcAddr gpa,\n'
-        protos += '                                                             VkDevice dev);\n'
-        protos += '\n'
-        protos += '// Init Device function pointer dispatch table with extension commands\n'
-        protos += 'VKAPI_ATTR void VKAPI_CALL loader_init_device_extension_dispatch_table(struct loader_dev_dispatch_table *dev_table,\n'
-        protos += '                                                                       PFN_vkGetInstanceProcAddr gipa,\n'
-        protos += '                                                                       PFN_vkGetDeviceProcAddr gdpa,\n'
-        protos += '                                                                       VkInstance inst,\n'
-        protos += '                                                                       VkDevice dev);\n'
-        protos += '\n'
-        protos += '// Init Instance function pointer dispatch table with core commands\n'
-        protos += 'VKAPI_ATTR void VKAPI_CALL loader_init_instance_core_dispatch_table(VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,\n'
-        protos += '                                                                    VkInstance inst);\n'
-        protos += '\n'
-        protos += '// Init Instance function pointer dispatch table with core commands\n'
-        protos += 'VKAPI_ATTR void VKAPI_CALL loader_init_instance_extension_dispatch_table(VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,\n'
-        protos += '                                                                         VkInstance inst);\n'
-        protos += '\n'
-        protos += '// Device command lookup function\n'
-        protos += 'VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDispatchTable *table, const char *name, bool* name_found);\n'
-        protos += '\n'
-        protos += '// Instance command lookup function\n'
-        protos += 'VKAPI_ATTR void* VKAPI_CALL loader_lookup_instance_dispatch_table(const VkLayerInstanceDispatchTable *table, const char *name,\n'
-        protos += '                                                                  bool *found_name);\n'
-        protos += '\n'
-        return protos
-
-    def OutputUtilitiesInSource(self):
-        protos = ''
-        protos += '// Device extension error function\n'
-        protos += 'VKAPI_ATTR VkResult VKAPI_CALL vkDevExtError(VkDevice dev) {\n'
-        protos += '    struct loader_device *found_dev;\n'
-        protos += '    // The device going in is a trampoline device\n'
-        protos += '    struct loader_icd_term *icd_term = loader_get_icd_and_device(dev, &found_dev);\n'
-        protos += '\n'
-        protos += '    if (icd_term)\n'
-        protos += '        loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,\n'
-        protos += '                   "Bad destination in loader trampoline dispatch,"\n'
-        protos += '                   "Are layers and extensions that you are calling enabled?");\n'
-        protos += '    return VK_ERROR_EXTENSION_NOT_PRESENT;\n'
-        protos += '}\n\n'
-        return protos
-
-    #
-    # Create a layer instance dispatch table from the appropriate list and return it as a string
-    def OutputLayerInstanceDispatchTable(self):
-        commands = []
-        table = ''
-        cur_extension_name = ''
-
-        table += '// Instance function pointer dispatch table\n'
-        table += 'typedef struct VkLayerInstanceDispatchTable_ {\n'
-
-        # First add in an entry for GetPhysicalDeviceProcAddr.  This will not
-        # ever show up in the XML or header, so we have to manually add it.
-        table += '    // Manually add in GetPhysicalDeviceProcAddr entry\n'
-        table += '    PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr;\n'
-
-        for x in range(0, 2):
-            if x == 0:
-                commands = self.core_commands
-            else:
-                commands = self.ext_commands
-
-            for cur_cmd in commands:
-                version = self.getAPIVersion(cur_cmd.ext_name)
-                is_inst_handle_type = cur_cmd.name in ADD_INST_CMDS or cur_cmd.handle_type == 'VkInstance' or cur_cmd.handle_type == 'VkPhysicalDevice'
-                if is_inst_handle_type:
-
-                    if cur_cmd.ext_name != cur_extension_name:
-                        if version:
-                            table += f'\n    // ---- Core {version.name} commands\n'
-                        else:
-                            table += f'\n    // ---- {cur_cmd.ext_name} extension commands\n'
-                        cur_extension_name = cur_cmd.ext_name
-
-                    # Remove 'vk' from proto name
-                    base_name = cur_cmd.name[2:]
-
-                    if cur_cmd.protect is not None:
-                        table += f'#if defined({cur_cmd.protect})\n'
-
-                    table += f'    PFN_{cur_cmd.name} {base_name};\n'
-
-                    if cur_cmd.protect is not None:
-                        table += f'#endif // {cur_cmd.protect}\n'
-
-        table += '} VkLayerInstanceDispatchTable;\n\n'
-        return table
-
-    #
-    # Create a layer device dispatch table from the appropriate list and return it as a string
-    def OutputLayerDeviceDispatchTable(self):
-        commands = []
-        table = ''
-        cur_extension_name = ''
-
-        table += '// Device function pointer dispatch table\n'
-        table += '#define DEVICE_DISP_TABLE_MAGIC_NUMBER 0x10ADED040410ADEDUL\n'
-        table += 'typedef struct VkLayerDispatchTable_ {\n'
-        table += '    uint64_t magic; // Should be DEVICE_DISP_TABLE_MAGIC_NUMBER\n'
-
-        for x in range(0, 2):
-            if x == 0:
-                commands = self.core_commands
-            else:
-                commands = self.ext_commands
-
-            for cur_cmd in commands:
-                version = self.getAPIVersion(cur_cmd.ext_name)
-                is_inst_handle_type = cur_cmd.name in ADD_INST_CMDS or cur_cmd.handle_type == 'VkInstance' or cur_cmd.handle_type == 'VkPhysicalDevice'
-                if not is_inst_handle_type:
-
-                    if cur_cmd.ext_name != cur_extension_name:
-                        if version:
-                            table += f'\n    // ---- Core {version.name} commands\n'
-                        else:
-                            table += f'\n    // ---- {cur_cmd.ext_name} extension commands\n'
-                        cur_extension_name = cur_cmd.ext_name
-
-                    # Remove 'vk' from proto name
-                    base_name = cur_cmd.name[2:]
-
-                    if cur_cmd.protect is not None:
-                        table += f'#if defined({cur_cmd.protect})\n'
-
-                    table += f'    PFN_{cur_cmd.name} {base_name};\n'
-                    if cur_cmd.protect is not None:
-                        table += f'#endif // {cur_cmd.protect}\n'
-
-        table += '} VkLayerDispatchTable;\n\n'
-        return table
-
-    #
-    # Common code between the dispatch table struct and the function filling out said struct
-    def ShouldPrintInIcdDispatchTable(self, cur_cmd, skip_list):
-        return cur_cmd.name == 'vkGetDeviceProcAddr' or \
-            (cur_cmd.handle_type not in ['VkDevice', 'VkCommandBuffer', 'VkQueue'] and cur_cmd.name not in skip_list)
-
-    #
-    # Create a dispatch table from the appropriate list and return it as a string
-    def OutputIcdDispatchTable(self):
-        commands = []
-        table = ''
-        cur_extension_name = ''
-
-        skip_commands = ['vkGetInstanceProcAddr',
-                         'vkEnumerateDeviceLayerProperties',
-                        ]
-
-        table += '// ICD function pointer dispatch table\n'
-        table += 'struct loader_icd_term_dispatch {\n'
-
-        for x in range(0, 2):
-            if x == 0:
-                commands = self.core_commands
-            else:
-                commands = self.ext_commands
-
-            for cur_cmd in commands:
-                version = self.getAPIVersion(cur_cmd.ext_name)
-                if self.ShouldPrintInIcdDispatchTable(cur_cmd, skip_commands):
-                    if cur_cmd.ext_name != cur_extension_name:
-                        if version:
-                            table += f'\n    // ---- Core {version.name} commands\n'
-                        else:
-                            table += f'\n    // ---- {cur_cmd.ext_name} extension commands\n'
-                        cur_extension_name = cur_cmd.ext_name
-
-                    # Remove 'vk' from proto name
-                    base_name = cur_cmd.name[2:]
-
-                    if cur_cmd.protect is not None:
-                        table += f'#if defined({cur_cmd.protect})\n'
-
-                    table += f'    PFN_{cur_cmd.name} {base_name};\n'
-
-                    if cur_cmd.protect is not None:
-                        table += f'#endif // {cur_cmd.protect}\n'
-
-        table += '};\n\n'
-        return table
-
-    #
-    # Init a dispatch table from the appropriate list and return it as a string
-    def OutputIcdDispatchTableInit(self):
-        commands = []
-        cur_extension_name = ''
-
-        table = ''
-        table += 'VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_instance* inst, struct loader_icd_term *icd_term) {\n'
-        table += '    const PFN_vkGetInstanceProcAddr fp_gipa = icd_term->scanned_icd->GetInstanceProcAddr;\n'
-        table += '\n'
-        table += '#define LOOKUP_GIPA(func) icd_term->dispatch.func = (PFN_vk##func)fp_gipa(icd_term->instance, "vk" #func);\n'
-        table += '\n'
-        table += '#define LOOKUP_REQUIRED_GIPA(func)                                                      \\\n'
-        table += '    do {                                                                                \\\n'
-        table += '        LOOKUP_GIPA(func);                                                              \\\n'
-        table += '        if (!icd_term->dispatch.func) {                                                 \\\n'
-        table += '            loader_log(inst, VULKAN_LOADER_WARN_BIT, 0, "Unable to load %s from ICD %s",\\\n'
-        table += '                       "vk"#func, icd_term->scanned_icd->lib_name);                     \\\n'
-        table += '            return false;                                                               \\\n'
-        table += '        }                                                                               \\\n'
-        table += '    } while (0)\n'
-        table += '\n'
-
-
-        skip_gipa_commands = ['vkGetInstanceProcAddr',
-                              'vkEnumerateDeviceLayerProperties',
-                              'vkCreateInstance',
-                              'vkEnumerateInstanceExtensionProperties',
-                              'vkEnumerateInstanceLayerProperties',
-                              'vkEnumerateInstanceVersion',
-                             ]
-
-        for x in range(0, 2):
-            if x == 0:
-                commands = self.core_commands
-            else:
-                commands = self.ext_commands
-
-            required = False
-            for cur_cmd in commands:
-                version = self.getAPIVersion(cur_cmd.ext_name)
-                if self.ShouldPrintInIcdDispatchTable(cur_cmd, skip_gipa_commands):
-
-                    if cur_cmd.ext_name != cur_extension_name:
-                        if version:
-                            table += f'\n    // ---- Core {version.name}\n'
-                            required = version.number == '1.0'
-                        else:
-                            table += f'\n    // ---- {cur_cmd.ext_name} extension commands\n'
-                            required = False
-                        cur_extension_name = cur_cmd.ext_name
-
-                    # Remove 'vk' from proto name
-                    base_name = cur_cmd.name[2:]
-
-                    if cur_cmd.protect is not None:
-                        table += f'#if defined({cur_cmd.protect})\n'
-
-                    if required:
-                        # The Core Vulkan code will be wrapped in a feature called VK_VERSION_#_#
-                        # For example: VK_VERSION_1_0 wraps the core 1.0 Vulkan functionality
-                        table += f'    LOOKUP_REQUIRED_GIPA({base_name});\n'
-                    else:
-                        table += f'    LOOKUP_GIPA({base_name});\n'
-                    if cur_cmd.protect is not None:
-                        table += f'#endif // {cur_cmd.protect}\n'
-
-        table += '\n'
-        table += '#undef LOOKUP_REQUIRED_GIPA\n'
-        table += '#undef LOOKUP_GIPA\n'
-        table += '\n'
-        table += '    return true;\n'
-        table += '};\n\n'
-        return table
-
-    #
-    # Create the extension enable union
-    def OutputIcdExtensionEnableUnion(self):
-        extensions = self.instanceExtensions
-
-        union = ''
-        union += 'struct loader_instance_extension_enables {\n'
-        for ext in extensions:
-            if (self.getAPIVersion(ext.name) or ext.name in WSI_EXT_NAMES or
-                ext.type == 'device' or ext.num_commands == 0):
-                continue
-
-            union += f'    uint8_t {ext.name[3:].lower()};\n'
-
-        union += '};\n\n'
-        return union
-
-    #
-    # Creates the prototypes for the loader's core instance command terminators
-    def OutputLoaderTerminators(self):
-        terminators = ''
-        terminators += '// Loader core instance terminators\n'
-
-        for cur_cmd in self.core_commands:
-            is_inst_handle_type = cur_cmd.name in ADD_INST_CMDS or cur_cmd.handle_type == 'VkInstance' or cur_cmd.handle_type == 'VkPhysicalDevice'
-            if is_inst_handle_type:
-                mod_string = ''
-                new_terminator = cur_cmd.cdecl
-                mod_string = new_terminator.replace("VKAPI_CALL vk", "VKAPI_CALL terminator_")
-
-                if cur_cmd.name in PRE_INSTANCE_FUNCTIONS:
-                    pre_instance_basic_version = mod_string
-                    mod_string = mod_string.replace("terminator_", "terminator_pre_instance_")
-                    mod_string = mod_string.replace(cur_cmd.name[2:] + '(\n', cur_cmd.name[2:] + '(\n    const Vk' + cur_cmd.name[2:] + 'Chain* chain,\n')
-
-                if cur_cmd.protect is not None:
-                    terminators += f'#if defined({cur_cmd.protect})\n'
-
-                if cur_cmd.name in PRE_INSTANCE_FUNCTIONS:
-                    terminators += pre_instance_basic_version
-                    terminators += '\n'
-
-                terminators += mod_string
-                terminators += '\n'
-
-                if cur_cmd.protect is not None:
-                    terminators += f'#endif // {cur_cmd.protect}\n'
-
-        terminators += '\n'
-        return terminators
-
-    #
-    # Creates code to initialize the various dispatch tables
-    def OutputLoaderDispatchTables(self):
-        commands = []
-        tables = ''
-        gpa_param = ''
-        cur_type = ''
-        cur_extension_name = ''
-
-        for x in range(0, 4):
-            if x == 0:
-                cur_type = 'device'
-                gpa_param = 'dev'
-                commands = self.core_commands
-
-                tables += '// Init Device function pointer dispatch table with core commands\n'
-                tables += 'VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_dispatch_table *dev_table, PFN_vkGetDeviceProcAddr gpa,\n'
-                tables += '                                                             VkDevice dev) {\n'
-                tables += '    VkLayerDispatchTable *table = &dev_table->core_dispatch;\n'
-                tables += '    if (table->magic != DEVICE_DISP_TABLE_MAGIC_NUMBER) { abort(); }\n'
-                tables += '    for (uint32_t i = 0; i < MAX_NUM_UNKNOWN_EXTS; i++) dev_table->ext_dispatch[i] = (PFN_vkDevExt)vkDevExtError;\n'
-
-            elif x == 1:
-                cur_type = 'device'
-                gpa_param = 'dev'
-                commands = self.ext_commands
-
-                tables += '// Init Device function pointer dispatch table with extension commands\n'
-                tables += 'VKAPI_ATTR void VKAPI_CALL loader_init_device_extension_dispatch_table(struct loader_dev_dispatch_table *dev_table,\n'
-                tables += '                                                                       PFN_vkGetInstanceProcAddr gipa,\n'
-                tables += '                                                                       PFN_vkGetDeviceProcAddr gdpa,\n'
-                tables += '                                                                       VkInstance inst,\n'
-                tables += '                                                                       VkDevice dev) {\n'
-                tables += '    VkLayerDispatchTable *table = &dev_table->core_dispatch;\n'
-                tables += '    table->magic = DEVICE_DISP_TABLE_MAGIC_NUMBER;\n'
-
-            elif x == 2:
-                cur_type = 'instance'
-                gpa_param = 'inst'
-                commands = self.core_commands
-
-                tables += '// Init Instance function pointer dispatch table with core commands\n'
-                tables += 'VKAPI_ATTR void VKAPI_CALL loader_init_instance_core_dispatch_table(VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,\n'
-                tables += '                                                                    VkInstance inst) {\n'
-
-            else:
-                cur_type = 'instance'
-                gpa_param = 'inst'
-                commands = self.ext_commands
-
-                tables += '// Init Instance function pointer dispatch table with core commands\n'
-                tables += 'VKAPI_ATTR void VKAPI_CALL loader_init_instance_extension_dispatch_table(VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,\n'
-                tables += '                                                                        VkInstance inst) {\n'
-
-            for cur_cmd in commands:
-                version = self.getAPIVersion(cur_cmd.ext_name)
-                is_inst_handle_type = cur_cmd.handle_type == 'VkInstance' or cur_cmd.handle_type == 'VkPhysicalDevice'
-                if ((cur_type == 'instance' and is_inst_handle_type) or (cur_type == 'device' and not is_inst_handle_type)):
-                    if cur_cmd.ext_name != cur_extension_name:
-                        if version:
-                            tables += f'\n    // ---- Core {version.name} commands\n'
-                        else:
-                            tables += f'\n    // ---- {cur_cmd.ext_name} extension commands\n'
-                        cur_extension_name = cur_cmd.ext_name
-
-                    # Remove 'vk' from proto name
-                    base_name = cur_cmd.name[2:]
-
-                    # Names to skip
-                    if (base_name == 'CreateInstance' or base_name == 'CreateDevice' or
-                        base_name == 'EnumerateInstanceExtensionProperties' or
-                        base_name == 'EnumerateInstanceLayerProperties' or
-                        base_name == 'EnumerateInstanceVersion'):
-                        continue
-
-                    if cur_cmd.protect is not None:
-                        tables += f'#if defined({cur_cmd.protect})\n'
-
-                    # If we're looking for the proc we are passing in, just point the table to it.  This fixes the issue where
-                    # a layer overrides the function name for the loader.
-                    if x == 1:
-                        if base_name == 'GetDeviceProcAddr':
-                            tables += '    table->GetDeviceProcAddr = gdpa;\n'
-                        elif cur_cmd.ext_type == 'instance':
-                            tables += f'    table->{base_name} = (PFN_{cur_cmd.name})gipa(inst, "{cur_cmd.name}");\n'
-                        else:
-                            tables += f'    table->{base_name} = (PFN_{cur_cmd.name})gdpa(dev, "{cur_cmd.name}");\n'
-                    elif (x < 1 and base_name == 'GetDeviceProcAddr'):
-                        tables += '    table->GetDeviceProcAddr = gpa;\n'
-                    elif (x > 1 and base_name == 'GetInstanceProcAddr'):
-                        tables += '    table->GetInstanceProcAddr = gpa;\n'
-                    else:
-                        tables += f'    table->{base_name} = (PFN_{cur_cmd.name})gpa({gpa_param}, "{cur_cmd.name}");\n'
-
-                    if cur_cmd.protect is not None:
-                        tables += f'#endif // {cur_cmd.protect}\n'
-
-            tables += '}\n\n'
-        return tables
-
-    #
-    # Create a lookup table function from the appropriate list of entrypoints and
-    # return it as a string
-    def OutputLoaderLookupFunc(self):
-        commands = []
-        tables = ''
-        cur_type = ''
-        cur_extension_name = ''
-
-        for x in range(0, 2):
-            if x == 0:
-                cur_type = 'device'
-
-                tables += '// Device command lookup function\n'
-                tables += 'VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDispatchTable *table, const char *name, bool* found_name) {\n'
-                tables += '    if (!name || name[0] != \'v\' || name[1] != \'k\') {\n'
-                tables += '        *found_name = false;\n'
-                tables += '        return NULL;\n'
-                tables += '    }\n'
-                tables += '\n'
-                tables += '    name += 2;\n'
-                tables += '    *found_name = true;\n'
-                tables += '    struct loader_device* dev = (struct loader_device *)table;\n'
-                tables += '    const struct loader_instance* inst = dev->phys_dev_term->this_icd_term->this_instance;\n'
-                tables += '    uint32_t api_version = VK_MAKE_API_VERSION(0, inst->app_api_version.major, inst->app_api_version.minor, inst->app_api_version.patch);\n'
-                tables += '\n'
-            else:
-                cur_type = 'instance'
-
-                tables += '// Instance command lookup function\n'
-                tables += 'VKAPI_ATTR void* VKAPI_CALL loader_lookup_instance_dispatch_table(const VkLayerInstanceDispatchTable *table, const char *name,\n'
-                tables += '                                                                 bool *found_name) {\n'
-                tables += '    if (!name || name[0] != \'v\' || name[1] != \'k\') {\n'
-                tables += '        *found_name = false;\n'
-                tables += '        return NULL;\n'
-                tables += '    }\n'
-                tables += '\n'
-                tables += '    *found_name = true;\n'
-                tables += '    name += 2;\n'
-
-
-            for y in range(0, 2):
-                if y == 0:
-                    commands = self.core_commands
-                else:
-                    commands = self.ext_commands
-
-                for cur_cmd in commands:
-                    version = self.getAPIVersion(cur_cmd.ext_name)
-                    is_inst_handle_type = cur_cmd.handle_type == 'VkInstance' or cur_cmd.handle_type == 'VkPhysicalDevice'
-                    if ((cur_type == 'instance' and is_inst_handle_type) or (cur_type == 'device' and not is_inst_handle_type)):
-                        if cur_cmd.ext_name != cur_extension_name:
-                            if version:
-                                tables += f'\n    // ---- Core {version.name} commands\n'
-                                if cur_type == 'device':
-                                    version_check = f'        if (dev->should_ignore_device_commands_from_newer_version && api_version < {version.constant}) return NULL;\n'
-                            else:
-
-                                tables += f'\n    // ---- {cur_cmd.ext_name} extension commands\n'
-                                version_check = ''
-                            cur_extension_name = cur_cmd.ext_name
-
-                        # Remove 'vk' from proto name
-                        base_name = cur_cmd.name[2:]
-
-                        if (base_name == 'CreateInstance' or base_name == 'CreateDevice' or
-                            base_name == 'EnumerateInstanceExtensionProperties' or
-                            base_name == 'EnumerateInstanceLayerProperties' or
-                            base_name == 'EnumerateInstanceVersion'):
-                            continue
-
-                        if cur_cmd.protect is not None:
-                            tables += f'#if defined({cur_cmd.protect})\n'
-
-                        tables += f'    if (!strcmp(name, "{base_name}")) '
-                        if cur_cmd.name in DEVICE_CMDS_MUST_USE_TRAMP:
-                            if version_check != '':
-                                tables += f'{{\n{version_check}        return dev->layer_extensions.{cur_cmd.ext_name[3:].lower()}_enabled ? (void *){base_name} : NULL;\n    }}\n'
-                            else:
-                                tables += f'return dev->layer_extensions.{cur_cmd.ext_name[3:].lower()}_enabled ? (void *){base_name} : NULL;\n'
-
-                        else:
-                            if version_check != '':
-                                tables += f'{{\n{version_check}        return (void *)table->{base_name};\n    }}\n'
-                            else:
-                                tables += f'return (void *)table->{base_name};\n'
-
-                        if cur_cmd.protect is not None:
-                            tables += f'#endif // {cur_cmd.protect}\n'
-
-            tables += '\n'
-            tables += '    *found_name = false;\n'
-            tables += '    return NULL;\n'
-            tables += '}\n\n'
-        return tables
-
-    #
-    # Create the appropriate trampoline (and possibly terminator) functions
-    def CreateTrampTermFuncs(self):
-        funcs = ''
-        cur_extension_name = ''
-
-        # Some extensions have to be manually added.  Skip those in the automatic
-        # generation.  They will be manually added later.
-        manual_ext_commands = ['vkEnumeratePhysicalDeviceGroupsKHR',
-                               'vkGetPhysicalDeviceExternalImageFormatPropertiesNV',
-                               'vkGetPhysicalDeviceFeatures2KHR',
-                               'vkGetPhysicalDeviceProperties2KHR',
-                               'vkGetPhysicalDeviceFormatProperties2KHR',
-                               'vkGetPhysicalDeviceImageFormatProperties2KHR',
-                               'vkGetPhysicalDeviceQueueFamilyProperties2KHR',
-                               'vkGetPhysicalDeviceMemoryProperties2KHR',
-                               'vkGetPhysicalDeviceSparseImageFormatProperties2KHR',
-                               'vkGetPhysicalDeviceSurfaceCapabilities2KHR',
-                               'vkGetPhysicalDeviceSurfaceFormats2KHR',
-                               'vkGetPhysicalDeviceSurfaceCapabilities2EXT',
-                               'vkReleaseDisplayEXT',
-                               'vkAcquireXlibDisplayEXT',
-                               'vkGetRandROutputDisplayEXT',
-                               'vkGetPhysicalDeviceExternalBufferPropertiesKHR',
-                               'vkGetPhysicalDeviceExternalSemaphorePropertiesKHR',
-                               'vkGetPhysicalDeviceExternalFencePropertiesKHR',
-                               'vkGetPhysicalDeviceDisplayProperties2KHR',
-                               'vkGetPhysicalDeviceDisplayPlaneProperties2KHR',
-                               'vkGetDisplayModeProperties2KHR',
-                               'vkGetDisplayPlaneCapabilities2KHR',
-                               'vkGetPhysicalDeviceSurfacePresentModes2EXT',
-                               'vkGetDeviceGroupSurfacePresentModes2EXT',
-                               'vkGetPhysicalDeviceToolPropertiesEXT']
-
-        for ext_cmd in self.ext_commands:
-            if (ext_cmd.ext_name in WSI_EXT_NAMES or
-                ext_cmd.ext_name in AVOID_EXT_NAMES or
-                ext_cmd.name in AVOID_CMD_NAMES or
-                ext_cmd.name in manual_ext_commands):
-                continue
-
-            version = self.getAPIVersion(ext_cmd.ext_name)
-            if ext_cmd.ext_name != cur_extension_name:
-                if version:
-                    funcs += f'\n// ---- Core {version.name} trampoline/terminators\n\n'
-                else:
-                    funcs += f'\n// ---- {ext_cmd.ext_name} extension trampoline/terminators\n\n'
-                cur_extension_name = ext_cmd.ext_name
-
-            if ext_cmd.protect is not None:
-                funcs += f'#if defined({ext_cmd.protect})\n'
-
-            func_header = ext_cmd.cdecl.replace(";", " {\n")
-            tramp_header = func_header.replace("VKAPI_CALL vk", "VKAPI_CALL ")
-            return_prefix = '    '
-            base_name = ext_cmd.name[2:]
-            has_surface = 0
-            update_structure_surface = 0
-            update_structure_string = ''
-            requires_terminator = 0
-            surface_var_name = ''
-            phys_dev_var_name = ''
-            instance_var_name = ''
-            has_return_type = False
-            always_use_param_name = True
-            surface_type_to_replace = ''
-            surface_name_replacement = ''
-            physdev_type_to_replace = ''
-            physdev_name_replacement = ''
-
-            for param in ext_cmd.params:
-                if param.type == 'VkSurfaceKHR':
-                    has_surface = 1
-                    surface_var_name = param.name
-                    requires_terminator = 1
-                    always_use_param_name = False
-                    surface_type_to_replace = 'VkSurfaceKHR'
-                    surface_name_replacement = 'icd_term->surface_list[icd_surface->surface_index]'
-                if param.type == 'VkPhysicalDeviceSurfaceInfo2KHR':
-                    has_surface = 1
-                    surface_var_name = param.name + '->surface'
-                    requires_terminator = 1
-                    update_structure_surface = 1
-                    update_structure_string = '        VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;\n'
-                    update_structure_string += '        info_copy.surface = icd_term->surface_list[icd_surface->surface_index];\n'
-                    always_use_param_name = False
-                    surface_type_to_replace = 'VkPhysicalDeviceSurfaceInfo2KHR'
-                    surface_name_replacement = '&info_copy'
-                if param.type == 'VkPhysicalDevice':
-                    requires_terminator = 1
-                    phys_dev_var_name = param.name
-                    always_use_param_name = False
-                    physdev_type_to_replace = 'VkPhysicalDevice'
-                    physdev_name_replacement = 'phys_dev_term->phys_dev'
-                if param.type == 'VkInstance':
-                    requires_terminator = 1
-                    instance_var_name = param.name
-
-            if ext_cmd.return_type is not None:
-                return_prefix += 'return '
-                has_return_type = True
-
-            if (ext_cmd.handle_type == 'VkInstance' or ext_cmd.handle_type == 'VkPhysicalDevice' or
-                'DebugMarkerSetObject' in ext_cmd.name or 'SetDebugUtilsObject' in ext_cmd.name or
-                ext_cmd.name in DEVICE_CMDS_NEED_TERM):
-                requires_terminator = 1
-
-            if requires_terminator == 1:
-                term_header = tramp_header.replace("VKAPI_CALL ", "VKAPI_CALL terminator_")
-
-                funcs += tramp_header
-
-                if ext_cmd.handle_type == 'VkPhysicalDevice':
-                    funcs += '    const VkLayerInstanceDispatchTable *disp;\n'
-                    funcs += f'    VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device({phys_dev_var_name});\n'
-                    funcs += '    if (VK_NULL_HANDLE == unwrapped_phys_dev) {\n'
-                    funcs += '        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n'
-                    funcs += f'                   "{ext_cmd.name}: Invalid {phys_dev_var_name} "\n'
-                    funcs += f'                   "[VUID-{ext_cmd.name}-{phys_dev_var_name}-parameter]");\n'
-                    funcs += '        abort(); /* Intentionally fail so user can correct issue. */\n'
-                    funcs += '    }\n'
-                    funcs += f'    disp = loader_get_instance_layer_dispatch({phys_dev_var_name});\n'
-                elif ext_cmd.handle_type == 'VkInstance':
-                    funcs += f'    struct loader_instance *inst = loader_get_instance({instance_var_name});\n'
-                    funcs += '    if (NULL == inst) {\n'
-                    funcs += '        loader_log(\n'
-                    funcs += '            NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n'
-                    funcs += f'            "{ext_cmd.name}: Invalid instance [VUID-{ext_cmd.name}-{instance_var_name}-parameter]");\n'
-                    funcs += '        abort(); /* Intentionally fail so user can correct issue. */\n'
-                    funcs += '    }\n'
-                    funcs += '#error("Not implemented. Likely needs to be manually generated!");\n'
-                else:
-                    funcs += '    const VkLayerDispatchTable *disp = loader_get_dispatch('
-                    funcs += ext_cmd.params[0].name
-                    funcs += ');\n'
-                    funcs += '    if (NULL == disp) {\n'
-                    funcs += '        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n'
-                    funcs += f'                   "{ext_cmd.name}: Invalid {ext_cmd.params[0].name} "\n'
-                    funcs += f'                   "[VUID-{ext_cmd.name}-{ext_cmd.params[0].name}-parameter]");\n'
-                    funcs += '        abort(); /* Intentionally fail so user can correct issue. */\n'
-                    funcs += '    }\n'
-
-                if 'DebugMarkerSetObjectName' in ext_cmd.name:
-                    funcs += '    VkDebugMarkerObjectNameInfoEXT local_name_info;\n'
-                    funcs += '    memcpy(&local_name_info, pNameInfo, sizeof(VkDebugMarkerObjectNameInfoEXT));\n'
-                    funcs += '    // If this is a physical device, we have to replace it with the proper one for the next call.\n'
-                    funcs += '    if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {\n'
-                    funcs += '        struct loader_physical_device_tramp *phys_dev_tramp = (struct loader_physical_device_tramp *)(uintptr_t)pNameInfo->object;\n'
-                    funcs += '        local_name_info.object = (uint64_t)(uintptr_t)phys_dev_tramp->phys_dev;\n'
-                    funcs += '    }\n'
-                    funcs += '    if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) {\n'
-                    funcs += '        struct loader_instance* instance = (struct loader_instance *)(uintptr_t)pNameInfo->object;\n'
-                    funcs += '        local_name_info.object = (uint64_t)(uintptr_t)instance->instance;\n'
-                    funcs += '    }\n'
-                elif 'DebugMarkerSetObjectTag' in ext_cmd.name:
-                    funcs += '    VkDebugMarkerObjectTagInfoEXT local_tag_info;\n'
-                    funcs += '    memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugMarkerObjectTagInfoEXT));\n'
-                    funcs += '    // If this is a physical device, we have to replace it with the proper one for the next call.\n'
-                    funcs += '    if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {\n'
-                    funcs += '        struct loader_physical_device_tramp *phys_dev_tramp = (struct loader_physical_device_tramp *)(uintptr_t)pTagInfo->object;\n'
-                    funcs += '        local_tag_info.object = (uint64_t)(uintptr_t)phys_dev_tramp->phys_dev;\n'
-                    funcs += '    }\n'
-                    funcs += '    if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) {\n'
-                    funcs += '        struct loader_instance* instance = (struct loader_instance *)(uintptr_t)pTagInfo->object;\n'
-                    funcs += '        local_tag_info.object = (uint64_t)(uintptr_t)instance->instance;\n'
-                    funcs += '    }\n'
-                elif 'SetDebugUtilsObjectName' in ext_cmd.name:
-                    funcs += '    VkDebugUtilsObjectNameInfoEXT local_name_info;\n'
-                    funcs += '    memcpy(&local_name_info, pNameInfo, sizeof(VkDebugUtilsObjectNameInfoEXT));\n'
-                    funcs += '    // If this is a physical device, we have to replace it with the proper one for the next call.\n'
-                    funcs += '    if (pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {\n'
-                    funcs += '        struct loader_physical_device_tramp *phys_dev_tramp = (struct loader_physical_device_tramp *)(uintptr_t)pNameInfo->objectHandle;\n'
-                    funcs += '        local_name_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_tramp->phys_dev;\n'
-                    funcs += '    }\n'
-                    funcs += '    if (pNameInfo->objectType == VK_OBJECT_TYPE_INSTANCE) {\n'
-                    funcs += '        struct loader_instance* instance = (struct loader_instance *)(uintptr_t)pNameInfo->objectHandle;\n'
-                    funcs += '        local_name_info.objectHandle = (uint64_t)(uintptr_t)instance->instance;\n'
-                    funcs += '    }\n'
-                elif 'SetDebugUtilsObjectTag' in ext_cmd.name:
-                    funcs += '    VkDebugUtilsObjectTagInfoEXT local_tag_info;\n'
-                    funcs += '    memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugUtilsObjectTagInfoEXT));\n'
-                    funcs += '    // If this is a physical device, we have to replace it with the proper one for the next call.\n'
-                    funcs += '    if (pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {\n'
-                    funcs += '        struct loader_physical_device_tramp *phys_dev_tramp = (struct loader_physical_device_tramp *)(uintptr_t)pTagInfo->objectHandle;\n'
-                    funcs += '        local_tag_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_tramp->phys_dev;\n'
-                    funcs += '    }\n'
-                    funcs += '    if (pTagInfo->objectType == VK_OBJECT_TYPE_INSTANCE) {\n'
-                    funcs += '        struct loader_instance* instance = (struct loader_instance *)(uintptr_t)pTagInfo->objectHandle;\n'
-                    funcs += '        local_tag_info.objectHandle = (uint64_t)(uintptr_t)instance->instance;\n'
-                    funcs += '    }\n'
-
-                if ext_cmd.ext_name in NULL_CHECK_EXT_NAMES:
-                    funcs += '    if (disp->' + base_name + ' != NULL) {\n'
-                    funcs += '    '
-                funcs += return_prefix
-                if ext_cmd.handle_type == 'VkInstance':
-                    funcs += 'inst->'
-                funcs += 'disp->'
-                funcs += base_name
-                funcs += '('
-                count = 0
-                for param in ext_cmd.params:
-                    if count != 0:
-                        funcs += ', '
-
-                    if param.type == 'VkPhysicalDevice':
-                        funcs += 'unwrapped_phys_dev'
-                    elif ('DebugMarkerSetObject' in ext_cmd.name or 'SetDebugUtilsObject' in ext_cmd.name) and param.name == 'pNameInfo':
-                        funcs += '&local_name_info'
-                    elif ('DebugMarkerSetObject' in ext_cmd.name or 'SetDebugUtilsObject' in ext_cmd.name) and param.name == 'pTagInfo':
-                        funcs += '&local_tag_info'
-                    else:
-                        funcs += param.name
-
-                    count += 1
-                funcs += ');\n'
-                if ext_cmd.ext_name in NULL_CHECK_EXT_NAMES:
-                    if ext_cmd.return_type is not None:
-                        funcs += '    } else {\n'
-                        funcs += '        return VK_SUCCESS;\n'
-                    funcs += '    }\n'
-                funcs += '}\n\n'
-
-                funcs += term_header
-                if ext_cmd.handle_type == 'VkPhysicalDevice':
-                    funcs += f'    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *){phys_dev_var_name};\n'
-                    funcs += '    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;\n'
-                    funcs += '    if (NULL == icd_term->dispatch.'
-                    funcs += base_name
-                    funcs += ') {\n'
-                    fatal_error_bit = '' if ext_cmd.ext_type =='instance' and has_return_type else 'VULKAN_LOADER_FATAL_ERROR_BIT | '
-                    funcs += f'        loader_log(icd_term->this_instance, {fatal_error_bit}VULKAN_LOADER_ERROR_BIT, 0,\n'
-                    funcs += '                   "ICD associated with VkPhysicalDevice does not support '
-                    funcs += base_name
-                    funcs += '");\n'
-
-                    # If this is an instance function taking a physical device (i.e. pre Vulkan 1.1), we need to behave and not crash so return an
-                    # error here.
-                    if ext_cmd.ext_type =='instance' and has_return_type:
-                        funcs += '        return VK_ERROR_EXTENSION_NOT_PRESENT;\n'
-                    else:
-                        funcs += '        abort(); /* Intentionally fail so user can correct issue. */\n'
-                    funcs += '    }\n'
-
-                    if has_surface == 1:
-                        funcs += f'    VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)({surface_var_name});\n'
-                        funcs += '    if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && icd_term->surface_list[icd_surface->surface_index]) {\n'
-
-                        # If there's a structure with a surface, we need to update its internals with the correct surface for the ICD
-                        if update_structure_surface == 1:
-                            funcs += update_structure_string
-
-                        funcs += '    ' + return_prefix + 'icd_term->dispatch.'
-                        funcs += base_name
-                        funcs += '('
-                        count = 0
-                        for param in ext_cmd.params:
-                            if count != 0:
-                                funcs += ', '
-
-                            if not always_use_param_name:
-                                if surface_type_to_replace and surface_type_to_replace == param.type:
-                                    funcs += surface_name_replacement
-                                elif physdev_type_to_replace and physdev_type_to_replace == param.type:
-                                    funcs += physdev_name_replacement
-                                else:
-                                    funcs += param.name
-                            else:
-                                funcs += param.name
-
-                            count += 1
-                        funcs += ');\n'
-                        if not has_return_type:
-                            funcs += '        return;\n'
-                        funcs += '    }\n'
-
-                    funcs += return_prefix
-                    funcs += 'icd_term->dispatch.'
-                    funcs += base_name
-                    funcs += '('
-                    count = 0
-                    for param in ext_cmd.params:
-                        if count != 0:
-                            funcs += ', '
-
-                        if param.type == 'VkPhysicalDevice':
-                            funcs += 'phys_dev_term->phys_dev'
-                        else:
-                            funcs += param.name
-
-                        count += 1
-                    funcs += ');\n'
-
-
-                elif ext_cmd.handle_type == 'VkInstance':
-                    funcs += f'    struct loader_instance *inst = loader_get_instance({instance_var_name});\n'
-                    funcs += '    if (NULL == inst) {\n'
-                    funcs += '        loader_log(\n'
-                    funcs += '            NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n'
-                    funcs += f'            "{ext_cmd.name}: Invalid instance [VUID-{ext_cmd.name}-{instance_var_name}-parameter]");\n'
-                    funcs += '        abort(); /* Intentionally fail so user can correct issue. */\n'
-                    funcs += '    }\n'
-                    funcs += '#error("Not implemented. Likely needs to be manually generated!");\n'
-                elif ext_cmd.ext_name in ['VK_EXT_debug_utils', 'VK_EXT_debug_marker']:
-                    if ext_cmd.name in ['vkDebugMarkerSetObjectNameEXT', 'vkDebugMarkerSetObjectTagEXT', 'vkSetDebugUtilsObjectNameEXT' , 'vkSetDebugUtilsObjectTagEXT']:
-
-                        is_debug_utils = ext_cmd.ext_name == "VK_EXT_debug_utils"
-                        debug_struct_name = ext_cmd.params[1].name
-                        local_struct = 'local_name_info' if 'ObjectName' in ext_cmd.name else 'local_tag_info'
-                        member_name = 'objectHandle' if is_debug_utils else 'object'
-                        phys_dev_check = 'VK_OBJECT_TYPE_PHYSICAL_DEVICE' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT'
-                        surf_check = 'VK_OBJECT_TYPE_SURFACE_KHR' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT'
-                        inst_check = 'VK_OBJECT_TYPE_INSTANCE' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT'
-                        funcs += '    struct loader_device *dev;\n'
-                        funcs += f'    struct loader_icd_term *icd_term = loader_get_icd_and_device({ ext_cmd.params[0].name}, &dev);\n'
-                        funcs += '    if (NULL == icd_term || NULL == dev) {\n'
-                        funcs += f'        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "{ext_cmd.name[2:]}: Invalid device handle");\n'
-                        funcs += '        abort(); /* Intentionally fail so user can correct issue. */\n'
-                        funcs += '    }\n'
-                        funcs += f'    { ext_cmd.params[1].type} {local_struct};\n'
-                        funcs += f'    memcpy(&{local_struct}, {debug_struct_name}, sizeof({ ext_cmd.params[1].type}));\n'
-                        funcs += '    // If this is a physical device, we have to replace it with the proper one for the next call.\n'
-                        funcs += f'    if ({debug_struct_name}->objectType == {phys_dev_check}) {{\n'
-                        funcs += f'        struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t){debug_struct_name}->{member_name};\n'
-                        funcs += f'        {local_struct}.{member_name} = (uint64_t)(uintptr_t)phys_dev_term->phys_dev;\n'
-                        funcs += '    // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.\n'
-                        funcs += f'    }} else if ({debug_struct_name}->objectType == {surf_check}) {{\n'
-                        funcs += '        if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) {\n'
-                        funcs += f'            VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t){debug_struct_name}->{member_name};\n'
-                        funcs += '            if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR)\n'
-                        funcs += '                && icd_term->surface_list.list[icd_surface->surface_index]) {\n'
-                        funcs += f'                {local_struct}.{member_name} = (uint64_t)icd_term->surface_list.list[icd_surface->surface_index];\n'
-                        funcs += '            }\n'
-                        funcs += '        }\n'
-                        funcs += '    // If this is an instance we have to replace it with the proper one for the next call.\n'
-                        funcs += f'    }} else if ({debug_struct_name}->objectType == {inst_check}) {{\n'
-                        funcs += f'        {local_struct}.{member_name} = (uint64_t)(uintptr_t)icd_term->instance;\n'
-                        funcs += '    }\n'
-                        funcs += '    // Exit early if the driver does not support the function - this can happen as a layer or the loader itself supports\n'
-                        funcs += '    // debug utils but the driver does not.\n'
-                        funcs += f'    if (NULL == dev->loader_dispatch.extension_terminator_dispatch.{ext_cmd.name[2:]})\n        return VK_SUCCESS;\n'
-                        dispatch = 'dev->loader_dispatch.'
-                    else:
-                        funcs += f'    struct loader_dev_dispatch_table *dispatch_table = loader_get_dev_dispatch({ext_cmd.params[0].name});\n'
-                        funcs += '    if (NULL == dispatch_table) {\n'
-                        funcs += f'        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "{ext_cmd.ext_name}: Invalid device handle");\n'
-                        funcs += '        abort(); /* Intentionally fail so user can correct issue. */\n'
-                        funcs += '    }\n'
-                        funcs += '    // Only call down if the device supports the function\n'
-                        funcs += f'    if (NULL != dispatch_table->extension_terminator_dispatch.{base_name})\n    '
-                        dispatch = 'dispatch_table->'
-                    funcs += '    '
-                    if has_return_type:
-                        funcs += 'return '
-                    funcs += f'{dispatch}extension_terminator_dispatch.{base_name}('
-                    count = 0
-                    for param in ext_cmd.params:
-                        if count != 0:
-                            funcs += ', '
-
-                        if param.type == 'VkPhysicalDevice':
-                            funcs += 'phys_dev_term->phys_dev'
-                        elif param.type == 'VkSurfaceKHR':
-                            funcs += 'icd_term->surface_list[icd_surface->surface_index]'
-                        elif ('DebugMarkerSetObject' in ext_cmd.name or 'SetDebugUtilsObject' in ext_cmd.name) and param.name == 'pNameInfo':
-                            funcs += '&local_name_info'
-                        elif ('DebugMarkerSetObject' in ext_cmd.name or 'SetDebugUtilsObject' in ext_cmd.name) and param.name == 'pTagInfo':
-                            funcs += '&local_tag_info'
-                        else:
-                            funcs += param.name
-                        count += 1
-
-                    funcs += ');\n'
-
-                else:
-                    funcs += '#error("Unknown error path!");\n'
-
-                funcs += '}\n\n'
-            else:
-                funcs += tramp_header
-
-                funcs += '    const VkLayerDispatchTable *disp = loader_get_dispatch('
-                funcs += ext_cmd.params[0].name
-                funcs += ');\n'
-                funcs += '    if (NULL == disp) {\n'
-                funcs += '        loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n'
-                funcs += f'                   "{ext_cmd.name}: Invalid {ext_cmd.params[0].name} "\n'
-                funcs += f'                   "[VUID-{ext_cmd.name}-{ext_cmd.params[0].name}-parameter]");\n'
-                funcs += '        abort(); /* Intentionally fail so user can correct issue. */\n'
-                funcs += '    }\n'
-
-                if ext_cmd.ext_name in NULL_CHECK_EXT_NAMES:
-                    funcs += '    if (disp->' + base_name + ' != NULL) {\n'
-                    funcs += '    '
-                funcs += return_prefix
-                funcs += 'disp->'
-                funcs += base_name
-                funcs += '('
-                count = 0
-                for param in ext_cmd.params:
-                    if count != 0:
-                        funcs += ', '
-                    funcs += param.name
-                    count += 1
-                funcs += ');\n'
-                if ext_cmd.ext_name in NULL_CHECK_EXT_NAMES:
-                    if ext_cmd.return_type is not None:
-                        funcs += '    } else {\n'
-                        funcs += '        return VK_SUCCESS;\n'
-                    funcs += '    }\n'
-                funcs += '}\n\n'
-
-            if ext_cmd.protect is not None:
-                funcs += f'#endif // {ext_cmd.protect}\n'
-
-        return funcs
-
-
-    #
-    # Create a function for the extension GPA call
-    def InstExtensionGPA(self):
-        gpa_func = ''
-        cur_extension_name = ''
-
-        gpa_func += '// GPA helpers for extensions\n'
-        gpa_func += 'bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr) {\n'
-        gpa_func += '    *addr = NULL;\n\n'
-
-        for cur_cmd in self.ext_commands:
-            if (self.getAPIVersion(cur_cmd.ext_name) or
-                cur_cmd.ext_name in WSI_EXT_NAMES or
-                cur_cmd.ext_name in AVOID_EXT_NAMES or
-                cur_cmd.name in AVOID_CMD_NAMES ):
-                continue
-
-            if cur_cmd.ext_name != cur_extension_name:
-                gpa_func += f'\n    // ---- {cur_cmd.ext_name} extension commands\n'
-                cur_extension_name = cur_cmd.ext_name
-
-            if cur_cmd.protect is not None:
-                gpa_func += f'#if defined({cur_cmd.protect})\n'
-
-            #base_name = cur_cmd.name[2:]
-            base_name = SHARED_ALIASES[cur_cmd.name] if cur_cmd.name in SHARED_ALIASES else cur_cmd.name[2:]
-
-            if cur_cmd.ext_type == 'instance':
-                gpa_func += f'    if (!strcmp("{cur_cmd.name}", name)) {{\n'
-                gpa_func += '        *addr = (ptr_instance->enabled_known_extensions.'
-                gpa_func += cur_cmd.ext_name[3:].lower()
-                gpa_func += ' == 1)\n'
-                gpa_func += f'                     ? (void *){base_name}\n'
-                gpa_func += '                     : NULL;\n'
-                gpa_func += '        return true;\n'
-                gpa_func += '    }\n'
-            else:
-                gpa_func += f'    if (!strcmp("{cur_cmd.name}", name)) {{\n'
-                gpa_func += f'        *addr = (void *){base_name};\n'
-                gpa_func += '        return true;\n'
-                gpa_func += '    }\n'
-
-            if cur_cmd.protect is not None:
-                gpa_func += f'#endif // {cur_cmd.protect}\n'
-
-        gpa_func += '    return false;\n'
-        gpa_func += '}\n\n'
-
-        return gpa_func
-
-    #
-    # Create the extension name init function
-    def InstantExtensionCreate(self):
-        entries = []
-        entries = self.instanceExtensions
-        count = 0
-        cur_extension_name = ''
-
-        create_func = ''
-        create_func += '// A function that can be used to query enabled extensions during a vkCreateInstance call\n'
-        create_func += 'void extensions_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) {\n'
-        create_func += '    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {\n'
-        for ext in entries:
-            if (self.getAPIVersion(ext.name) or ext.name in WSI_EXT_NAMES or
-                ext.name in AVOID_EXT_NAMES or ext.name in AVOID_CMD_NAMES or
-                ext.type == 'device' or ext.num_commands == 0):
-                continue
-
-            if ext.name != cur_extension_name:
-                create_func += f'\n    // ---- {ext.name} extension commands\n'
-                cur_extension_name = ext.name
-
-            if ext.protect is not None:
-                create_func += f'#if defined({ext.protect})\n'
-            if count == 0:
-                create_func += '        if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], '
-            else:
-                create_func += '        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], '
-
-            create_func += ext.define + ')) {\n'
-            create_func += '            ptr_instance->enabled_known_extensions.'
-            create_func += ext.name[3:].lower()
-            create_func += ' = 1;\n'
-
-            if ext.protect is not None:
-                create_func += f'#endif // {ext.protect}\n'
-            count += 1
-
-        create_func += '        }\n'
-        create_func += '    }\n'
-        create_func += '}\n\n'
-        return create_func
-
-    #
-    # Create code to initialize a dispatch table from the appropriate list of
-    # extension entrypoints and return it as a string
-    def DeviceExtensionGetTerminator(self):
-        term_func = ''
-
-        term_func += '// Some device commands still need a terminator because the loader needs to unwrap something about them.\n'
-        term_func += '// In many cases, the item needing unwrapping is a VkPhysicalDevice or VkSurfaceKHR object.  But there may be other items\n'
-        term_func += '// in the future.\n'
-        term_func += 'PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *name, bool* found_name) {\n'
-        term_func += '''    *found_name = false;
-    if (!name || name[0] != 'v' || name[1] != 'k') {
-        return NULL;
-    }
-    name += 2;
-'''
-        last_protect = None
-        last_ext = None
-        for ext_cmd in self.ext_commands:
-            version = self.getAPIVersion(ext_cmd.ext_name)
-            if ext_cmd.name in DEVICE_CMDS_NEED_TERM:
-                if version:
-                    term_func += f'    // ---- Core {version.name} commands\n'
-                else:
-                    last_protect = ext_cmd.protect
-                    if ext_cmd.protect is not None:
-                        term_func += f'#if defined({ext_cmd.protect})\n'
-                    if last_ext != ext_cmd.ext_name:
-                        term_func += f'    // ---- {ext_cmd.ext_name} extension commands\n'
-                        last_ext = ext_cmd.ext_name
-
-                term_func += f'    if (!strcmp(name, "{ext_cmd.name[2:]}")) {{\n'
-                term_func += '        *found_name = true;\n'
-                if ext_cmd.require:
-                    dep_expr = self.ConvertDependencyExpression(ext_cmd.require, lambda ext_name: f'dev->driver_extensions.{ext_name[3:].lower()}_enabled')
-                    term_func += f'        return (dev->driver_extensions.{ext_cmd.ext_name[3:].lower()}_enabled && ({dep_expr})) ?\n'
-                else:
-                    term_func += f'        return dev->driver_extensions.{ext_cmd.ext_name[3:].lower()}_enabled ?\n'
-                term_func += f'            (PFN_vkVoidFunction)terminator_{(ext_cmd.name[2:])} : NULL;\n'
-                term_func += '    }\n'
-
-        if last_protect is not None:
-            term_func += f'#endif // {last_protect}\n'
-
-        term_func += '    return NULL;\n'
-        term_func += '}\n\n'
-
-        return term_func
-
-    #
-    # Create a dispatch table solely for device functions which have custom terminators
-    def OutputDeviceFunctionTerminatorDispatchTable(self):
-        term_func = ''
-        term_func += '// Functions that required a terminator need to have a separate dispatch table which contains their corresponding\n'
-        term_func += '// device function. This is used in the terminators themselves.\n'
-        term_func += 'struct loader_device_terminator_dispatch {\n'
-
-        last_protect = None
-        last_ext = None
-        for ext_cmd in self.ext_commands:
-            version = self.getAPIVersion(ext_cmd.ext_name)
-            if ext_cmd.name in DEVICE_CMDS_NEED_TERM:
-                if version:
-                    term_func += f'    // ---- Core {version.name} commands\n'
-                else:
-                    last_protect = ext_cmd.protect
-                    if ext_cmd.protect is not None:
-                        term_func += f'#if defined({ext_cmd.protect})\n'
-                    if last_ext != ext_cmd.ext_name:
-                        term_func += f'    // ---- {ext_cmd.ext_name} extension commands\n'
-                        last_ext = ext_cmd.ext_name
-
-                term_func += f'    PFN_{ext_cmd.name} {ext_cmd.name[2:]};\n'
-
-        if last_protect is not None:
-            term_func += f'#endif // {last_protect}\n'
-
-        term_func += '};\n\n'
-
-        return term_func
-
-    def OutputDeviceFunctionTrampolinePrototypes(self):
-        tramp_protos = ''
-        tramp_protos += '// These are prototypes for functions that need their trampoline called in all circumstances.\n'
-        tramp_protos += '// They are used in loader_lookup_device_dispatch_table but are defined afterwards.\n'
-        last_protect = None
-        last_ext = None
-        for ext_cmd in self.ext_commands:
-            version = self.getAPIVersion(ext_cmd.ext_name)
-            if ext_cmd.name in DEVICE_CMDS_MUST_USE_TRAMP:
-                if version:
-                    tramp_protos += f'    // ---- Core {version.name} commands\n'
-                else:
-                    last_protect = ext_cmd.protect
-                    if ext_cmd.protect is not None:
-                        tramp_protos += f'#if defined({ext_cmd.protect})\n'
-                    if last_ext != ext_cmd.ext_name:
-                        tramp_protos += f'    // ---- {ext_cmd.ext_name} extension commands\n'
-                        last_ext = ext_cmd.ext_name
-
-                tramp_protos += f'{ext_cmd.cdecl.replace("VKAPI_CALL vk", "VKAPI_CALL ")}\n'
-
-        if last_protect is not None:
-            tramp_protos += f'#endif // {last_protect}\n'
-        tramp_protos += '\n'
-        return tramp_protos
-
-    #
-    # Create code to initialize a dispatch table from the appropriate list of
-    # extension entrypoints and return it as a string
-    def InitDeviceFunctionTerminatorDispatchTable(self):
-        term_func = ''
-
-        term_func += '// Functions that required a terminator need to have a separate dispatch table which contains their corresponding\n'
-        term_func += '// device function. This is used in the terminators themselves.\n'
-        term_func += 'void init_extension_device_proc_terminator_dispatch(struct loader_device *dev) {\n'
-        term_func += '    struct loader_device_terminator_dispatch* dispatch = &dev->loader_dispatch.extension_terminator_dispatch;\n'
-        term_func += '    PFN_vkGetDeviceProcAddr gpda = (PFN_vkGetDeviceProcAddr)dev->phys_dev_term->this_icd_term->dispatch.GetDeviceProcAddr;\n'
-        last_protect = None
-        last_ext = None
-        for ext_cmd in self.ext_commands:
-            version = self.getAPIVersion(ext_cmd.ext_name)
-            if ext_cmd.name in DEVICE_CMDS_NEED_TERM:
-                if version:
-                    term_func += f'    // ---- Core {version.name} commands\n'
-                else:
-                    last_protect = ext_cmd.protect
-                    if ext_cmd.protect is not None:
-                        term_func += f'#if defined({ext_cmd.protect})\n'
-                    if last_ext != ext_cmd.ext_name:
-                        term_func += f'    // ---- {ext_cmd.ext_name} extension commands\n'
-                        last_ext = ext_cmd.ext_name
-
-
-                if ext_cmd.require:
-                    dep_expr = self.ConvertDependencyExpression(ext_cmd.require, lambda ext_name: f'dev->driver_extensions.{ext_name[3:].lower()}_enabled')
-                    term_func += f'    if (dev->driver_extensions.{ext_cmd.ext_name[3:].lower()}_enabled && ({dep_expr}))\n'
-                    term_func += f'       dispatch->{ext_cmd.name[2:]} = (PFN_{(ext_cmd.name)})gpda(dev->icd_device, "{(ext_cmd.name)}");\n'
-                else:
-                    term_func += f'    if (dev->driver_extensions.{ext_cmd.ext_name[3:].lower()}_enabled)\n'
-                    term_func += f'       dispatch->{ext_cmd.name[2:]} = (PFN_{(ext_cmd.name)})gpda(dev->icd_device, "{(ext_cmd.name)}");\n'
-
-        if last_protect is not None:
-            term_func += f'#endif // {last_protect}\n'
-
-        term_func += '}\n\n'
-
-        return term_func
-
-    #
-    # Create code to initialize a dispatch table from the appropriate list of
-    # core and extension entrypoints and return it as a string
-    def InitInstLoaderExtensionDispatchTable(self):
-        commands = []
-        table = ''
-        cur_extension_name = ''
-
-        table += '// This table contains the loader\'s instance dispatch table, which contains\n'
-        table += '// default functions if no instance layers are activated.  This contains\n'
-        table += '// pointers to "terminator functions".\n'
-        table += 'const VkLayerInstanceDispatchTable instance_disp = {\n'
-
-        for x in range(0, 2):
-            if x == 0:
-                commands = self.core_commands
-            else:
-                commands = self.ext_commands
-
-            for cur_cmd in commands:
-                version = self.getAPIVersion(cur_cmd.ext_name)
-                if cur_cmd.handle_type == 'VkInstance' or cur_cmd.handle_type == 'VkPhysicalDevice':
-                    if cur_cmd.ext_name != cur_extension_name:
-                        if version:
-                            table += f'\n    // ---- Core {version.name} commands\n'
-                        else:
-                            table += f'\n    // ---- {cur_cmd.ext_name} extension commands\n'
-                        cur_extension_name = cur_cmd.ext_name
-
-                    # Remove 'vk' from proto name
-                    base_name = cur_cmd.name[2:]
-                    aliased_name = SHARED_ALIASES[cur_cmd.name][2:] if cur_cmd.name in SHARED_ALIASES else base_name
-
-                    if (base_name == 'CreateInstance' or base_name == 'CreateDevice' or
-                        base_name == 'EnumerateInstanceExtensionProperties' or
-                        base_name == 'EnumerateInstanceLayerProperties' or
-                        base_name == 'EnumerateInstanceVersion'):
-                        continue
-
-                    if cur_cmd.protect is not None:
-                        table += f'#if defined({cur_cmd.protect})\n'
-
-                    if base_name == 'GetInstanceProcAddr':
-                        table += f'    .{base_name} = {cur_cmd.name},\n'
-                    else:
-                        table += f'    .{base_name} = terminator_{aliased_name},\n'
-
-                    if cur_cmd.protect is not None:
-                        table += f'#endif // {cur_cmd.protect}\n'
-        table += '};\n\n'
-
-        return table
-
-    #
-    # Create the extension name whitelist array
-    def OutputInstantExtensionWhitelistArray(self):
-        extensions = self.instanceExtensions
-
-        table = ''
-        table += '// A null-terminated list of all of the instance extensions supported by the loader.\n'
-        table += '// If an instance extension name is not in this list, but it is exported by one or more of the\n'
-        table += '// ICDs detected by the loader, then the extension name not in the list will be filtered out\n'
-        table += '// before passing the list of extensions to the application.\n'
-        table += 'const char *const LOADER_INSTANCE_EXTENSIONS[] = {\n'
-        for ext in extensions:
-            if ext.type == 'device' or self.getAPIVersion(ext.name):
-                continue
-
-            if ext.protect is not None:
-                table += f'#if defined({ext.protect})\n'
-            table += '                                                  '
-            table += ext.define + ',\n'
-
-            if ext.protect is not None:
-                table += f'#endif // {ext.protect}\n'
-        table += '                                                  NULL };\n'
-        return table
diff --git a/scripts/loader_genvk.py b/scripts/loader_genvk.py
index 1cdd6d8..2a467f1 100644
--- a/scripts/loader_genvk.py
+++ b/scripts/loader_genvk.py
@@ -1,6 +1,6 @@
 #!/usr/bin/python3
 #
-# Copyright (c) 2013-2019 The Khronos Group Inc.
+# Copyright (c) 2013-2025 The Khronos Group Inc.
 # Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 # Copyright (c) 2023-2023 RasterGrid Kft.
 #
@@ -16,411 +16,36 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import argparse, cProfile, pdb, string, sys, time, os
+import argparse
+import os
+import common_codegen
+from generate_source import RunGenerators
 
-# Simple timer functions
-startTime = None
-
-def startTimer(timeit):
-    global startTime
-    if timeit:
-        startTime = time.process_time()
-
-def endTimer(timeit, msg):
-    global startTime
-    if timeit:
-        endTime = time.process_time()
-        write(msg, endTime - startTime, file=sys.stderr)
-        startTime = None
-
-# Turn a list of strings into a regexp string matching exactly those strings
-def makeREstring(list, default = None):
-    if len(list) > 0 or default is None:
-        return '^(' + '|'.join(list) + ')$'
-    else:
-        return default
-
-# Returns a directory of [ generator function, generator options ] indexed
-# by specified short names. The generator options incorporate the following
-# parameters:
-#
-# args is an parsed argument object; see below for the fields that are used.
-def makeGenOpts(args):
-    global genOpts
-    genOpts = {}
-
-    # API to generate sources for
-    apiname = args.api
-
-    # Default class of extensions to include, or None
-    if args.defaultExtensions is not None:
-        defaultExtensions = args.defaultExtensions
-    else:
-        defaultExtensions = apiname
-
-    # Additional extensions to include (list of extensions)
-    extensions = args.extension
-
-    # Extensions to remove (list of extensions)
-    removeExtensions = args.removeExtensions
-
-    # Extensions to emit (list of extensions)
-    emitExtensions = args.emitExtensions
-
-    # Features to include (list of features)
-    features = args.feature
-
-    # Whether to disable inclusion protect in headers
-    protect = args.protect
-
-    # Output target directory
-    directory = args.directory
-
-    # Path to generated files, particularly api.py
-    genpath = args.genpath
-
-    # Descriptive names for various regexp patterns used to select
-    # versions and extensions
-    allFeatures     = allExtensions = '.*'
-    noFeatures      = noExtensions = None
-
-    # Turn lists of names/patterns into matching regular expressions
-    addExtensionsPat     = makeREstring(extensions, None)
-    removeExtensionsPat  = makeREstring(removeExtensions, None)
-    emitExtensionsPat    = makeREstring(emitExtensions, allExtensions)
-    featuresPat          = makeREstring(features, allFeatures)
-
-    # Copyright text prefixing all headers (list of strings).
-    prefixStrings = [
-        '/*',
-        '** Copyright (c) 2015-2019 The Khronos Group Inc.',
-        '**',
-        '** Licensed under the Apache License, Version 2.0 (the "License");',
-        '** you may not use this file except in compliance with the License.',
-        '** You may obtain a copy of the License at',
-        '**',
-        '**     http://www.apache.org/licenses/LICENSE-2.0',
-        '**',
-        '** Unless required by applicable law or agreed to in writing, software',
-        '** distributed under the License is distributed on an "AS IS" BASIS,',
-        '** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
-        '** See the License for the specific language governing permissions and',
-        '** limitations under the License.',
-        '*/',
-        ''
-    ]
-
-    # Text specific to Vulkan headers
-    vkPrefixStrings = [
-        '/*',
-        '** This header is generated from the Khronos Vulkan XML API Registry.',
-        '**',
-        '*/',
-        ''
-    ]
-
-    # Defaults for generating re-inclusion protection wrappers (or not)
-    protectFeature = protect
-
-    # An API style conventions object
-    conventions = VulkanConventions()
-
-    # Loader Generators
-    # Options for dispatch table helper generator
-    genOpts['vk_dispatch_table_helper.h'] = [
-          DispatchTableHelperOutputGenerator,
-          DispatchTableHelperOutputGeneratorOptions(
-            conventions       = conventions,
-            filename          = 'vk_dispatch_table_helper.h',
-            directory         = directory,
-            genpath           = None,
-            apiname           = apiname,
-            profile           = None,
-            versions          = featuresPat,
-            emitversions      = featuresPat,
-            defaultExtensions = defaultExtensions,
-            addExtensions     = addExtensionsPat,
-            removeExtensions  = removeExtensionsPat,
-            emitExtensions    = emitExtensionsPat,
-            prefixText        = prefixStrings + vkPrefixStrings,
-            apicall           = 'VKAPI_ATTR ',
-            apientry          = 'VKAPI_CALL ',
-            apientryp         = 'VKAPI_PTR *',
-            alignFuncParam    = 48,
-            expandEnumerants = False)
-        ]
-
-    # Options for Layer dispatch table generator
-    genOpts['vk_layer_dispatch_table.h'] = [
-          LoaderExtensionOutputGenerator,
-          LoaderExtensionGeneratorOptions(
-            conventions       = conventions,
-            filename          = 'vk_layer_dispatch_table.h',
-            directory         = directory,
-            genpath           = None,
-            apiname           = apiname,
-            profile           = None,
-            versions          = featuresPat,
-            emitversions      = featuresPat,
-            defaultExtensions = defaultExtensions,
-            addExtensions     = addExtensionsPat,
-            removeExtensions  = removeExtensionsPat,
-            emitExtensions    = emitExtensionsPat,
-            prefixText        = prefixStrings + vkPrefixStrings,
-            apicall           = 'VKAPI_ATTR ',
-            apientry          = 'VKAPI_CALL ',
-            apientryp         = 'VKAPI_PTR *',
-            alignFuncParam    = 48,
-            expandEnumerants = False)
-        ]
-
-    # Options for loader extension source generator
-    genOpts['vk_loader_extensions.h'] = [
-          LoaderExtensionOutputGenerator,
-          LoaderExtensionGeneratorOptions(
-            conventions       = conventions,
-            filename          = 'vk_loader_extensions.h',
-            directory         = directory,
-            genpath           = None,
-            apiname           = apiname,
-            profile           = None,
-            versions          = featuresPat,
-            emitversions      = featuresPat,
-            defaultExtensions = defaultExtensions,
-            addExtensions     = addExtensionsPat,
-            removeExtensions  = removeExtensionsPat,
-            emitExtensions    = emitExtensionsPat,
-            prefixText        = prefixStrings + vkPrefixStrings,
-            apicall           = 'VKAPI_ATTR ',
-            apientry          = 'VKAPI_CALL ',
-            apientryp         = 'VKAPI_PTR *',
-            alignFuncParam    = 48,
-            expandEnumerants = False)
-        ]
-
-    # Options for loader extension source generator
-    genOpts['vk_loader_extensions.c'] = [
-          LoaderExtensionOutputGenerator,
-          LoaderExtensionGeneratorOptions(
-            conventions       = conventions,
-            filename          = 'vk_loader_extensions.c',
-            directory         = directory,
-            genpath           = None,
-            apiname           = apiname,
-            profile           = None,
-            versions          = featuresPat,
-            emitversions      = featuresPat,
-            defaultExtensions = defaultExtensions,
-            addExtensions     = addExtensionsPat,
-            removeExtensions  = removeExtensionsPat,
-            emitExtensions    = emitExtensionsPat,
-            prefixText        = prefixStrings + vkPrefixStrings,
-            apicall           = 'VKAPI_ATTR ',
-            apientry          = 'VKAPI_CALL ',
-            apientryp         = 'VKAPI_PTR *',
-            alignFuncParam    = 48,
-            expandEnumerants = False)
-        ]
-
-    # Helper file generator options for vk_object_types.h
-    genOpts['vk_object_types.h'] = [
-          HelperFileOutputGenerator,
-          HelperFileOutputGeneratorOptions(
-            conventions       = conventions,
-            filename          = 'vk_object_types.h',
-            directory         = directory,
-            genpath           = None,
-            apiname           = apiname,
-            profile           = None,
-            versions          = featuresPat,
-            emitversions      = featuresPat,
-            defaultExtensions = defaultExtensions,
-            addExtensions     = addExtensionsPat,
-            removeExtensions  = removeExtensionsPat,
-            emitExtensions    = emitExtensionsPat,
-            prefixText        = prefixStrings + vkPrefixStrings,
-            apicall           = 'VKAPI_ATTR ',
-            apientry          = 'VKAPI_CALL ',
-            apientryp         = 'VKAPI_PTR *',
-            alignFuncParam    = 48,
-            expandEnumerants  = False,
-            helper_file_type  = 'object_types_header')
-        ]
-
-# Create an API generator and corresponding generator options based on
-# the requested target and command line options.
-# This is encapsulated in a function so it can be profiled and/or timed.
-# The args parameter is an parsed argument object containing the following
-# fields that are used:
-#   target - target to generate
-#   directory - directory to generate it in
-#   protect - True if re-inclusion wrappers should be created
-#   extensions - list of additional extensions to include in generated
-#   interfaces
-def genTarget(args):
-    global genOpts
-
-    # Create generator options with parameters specified on command line
-    makeGenOpts(args)
-
-    # Select a generator matching the requested target
-    if (args.target in genOpts.keys()):
-        createGenerator = genOpts[args.target][0]
-        options = genOpts[args.target][1]
-
-        if not args.quiet:
-            write('* Building', options.filename, file=sys.stderr)
-            write('* options.apiname           =', options.apiname, file=sys.stderr)
-            write('* options.versions          =', options.versions, file=sys.stderr)
-            write('* options.emitversions      =', options.emitversions, file=sys.stderr)
-            write('* options.defaultExtensions =', options.defaultExtensions, file=sys.stderr)
-            write('* options.addExtensions     =', options.addExtensions, file=sys.stderr)
-            write('* options.removeExtensions  =', options.removeExtensions, file=sys.stderr)
-            write('* options.emitExtensions    =', options.emitExtensions, file=sys.stderr)
-
-        gen = createGenerator(errFile=errWarn,
-                              warnFile=errWarn,
-                              diagFile=diag)
-        if not args.quiet:
-            write('* Generated', options.filename, file=sys.stderr)
-        return (gen, options)
-    else:
-        write('No generator options for unknown target:', args.target, file=sys.stderr)
-        return none
-
-# -feature name
-# -extension name
-# For both, "name" may be a single name, or a space-separated list
-# of names, or a regular expression.
+# This is a legacy way to run the code gen
+# Should call generate_source.py instead
 if __name__ == '__main__':
     parser = argparse.ArgumentParser()
 
+    parser.add_argument('target', metavar='target', nargs='?', help='Specify target')
     parser.add_argument('-api', action='store',
                         default='vulkan',
                         choices=['vulkan'],
                         help='Specify API name to generate')
-    parser.add_argument('-defaultExtensions', action='store',
-                        default=None,
-                        help='Specify a single class of extensions to add to targets')
-    parser.add_argument('-extension', action='append',
-                        default=[],
-                        help='Specify an extension or extensions to add to targets')
-    parser.add_argument('-removeExtensions', action='append',
-                        default=[],
-                        help='Specify an extension or extensions to remove from targets')
-    parser.add_argument('-emitExtensions', action='append',
-                        default=[],
-                        help='Specify an extension or extensions to emit in targets')
-    parser.add_argument('-feature', action='append',
-                        default=[],
-                        help='Specify a core API feature name or names to add to targets')
-    parser.add_argument('-debug', action='store_true',
-                        help='Enable debugging')
-    parser.add_argument('-dump', action='store_true',
-                        help='Enable dump to stderr')
-    parser.add_argument('-diagfile', action='store',
-                        default=None,
-                        help='Write diagnostics to specified file')
-    parser.add_argument('-errfile', action='store',
-                        default=None,
-                        help='Write errors and warnings to specified file instead of stderr')
-    parser.add_argument('-noprotect', dest='protect', action='store_false',
-                        help='Disable inclusion protection in output headers')
-    parser.add_argument('-profile', action='store_true',
-                        help='Enable profiling')
     parser.add_argument('-registry', action='store',
                         default='vk.xml',
                         help='Use specified registry file instead of vk.xml')
-    parser.add_argument('-time', action='store_true',
-                        help='Enable timing')
-    parser.add_argument('-validate', action='store_true',
-                        help='Enable XML group validation')
-    parser.add_argument('-genpath', action='store', default='gen',
-                        help='Path to generated files')
     parser.add_argument('-o', action='store', dest='directory',
                         default='.',
                         help='Create target and related files in specified directory')
-    parser.add_argument('target', metavar='target', nargs='?',
-                        help='Specify target')
-    parser.add_argument('-quiet', action='store_true', default=True,
-                        help='Suppress script output during normal execution.')
-    parser.add_argument('-verbose', action='store_false', dest='quiet', default=True,
-                        help='Enable script output during normal execution.')
-
     # This argument tells us where to load the script from the Vulkan-Headers registry
     parser.add_argument('-scripts', action='store',
                         help='Find additional scripts in this directory')
 
     args = parser.parse_args()
 
-    # default scripts path to be same as registry
-    if not args.scripts:
-        args.scripts = os.path.dirname(args.registry)
-        print(args.scripts)
+    # Currently don't run clang format
+    # repo_dir = common_codegen.repo_relative('.')
+    # style_file = os.path.join(repo_dir, '.clang-format')
 
-    scripts_dir = os.path.dirname(os.path.abspath(__file__))
-    registry_dir = os.path.join(scripts_dir, args.scripts)
-    sys.path.insert(0, registry_dir)
+    RunGenerators(api=args.api,registry=args.registry, directory=args.directory, styleFile=None, targetFilter=[args.target], flatOutput=True)
 
-    # The imports need to be done here so that they can be picked up from Vulkan-Headers
-    from reg import *
-    from generator import write
-    from cgenerator import CGeneratorOptions, COutputGenerator
-
-    from dispatch_table_helper_generator import DispatchTableHelperOutputGenerator, DispatchTableHelperOutputGeneratorOptions
-    from helper_file_generator import HelperFileOutputGenerator, HelperFileOutputGeneratorOptions
-    from loader_extension_generator import LoaderExtensionOutputGenerator, LoaderExtensionGeneratorOptions
-
-    # Temporary workaround for vkconventions python2 compatibility
-    import abc; abc.ABC = abc.ABCMeta('ABC', (object,), {})
-    from vkconventions import VulkanConventions
-
-    # This splits arguments which are space-separated lists
-    args.feature = [name for arg in args.feature for name in arg.split()]
-    args.extension = [name for arg in args.extension for name in arg.split()]
-
-    # create error/warning & diagnostic files
-    if args.errfile:
-        errWarn = open(args.errfile, 'w', encoding='utf-8')
-    else:
-        errWarn = sys.stderr
-
-    if args.diagfile:
-        diag = open(args.diagfile, 'w', encoding='utf-8')
-    else:
-        diag = None
-
-    # Create the API generator & generator options
-    (gen, options) = genTarget(args)
-
-    # Create the registry object with the specified generator and generator
-    # options. The options are set before XML loading as they may affect it.
-    reg = Registry(gen, options)
-
-    # Parse the specified registry XML into an ElementTree objec
-    startTimer(args.time)
-    tree = etree.parse(args.registry)
-    endTimer(args.time, '* Time to make ElementTree =')
-
-    # Load the XML tree into the registry object
-    startTimer(args.time)
-    reg.loadElementTree(tree)
-    endTimer(args.time, '* Time to parse ElementTree =')
-
-    if (args.validate):
-        reg.validateGroups()
-
-    if (args.dump):
-        write('* Dumping registry to regdump.txt', file=sys.stderr)
-        reg.dumpReg(filehandle = open('regdump.txt', 'w', encoding='utf-8'))
-
-    # Finally, use the output generator to create the requested targe
-    if (args.debug):
-        pdb.run('reg.apiGen()')
-    else:
-        startTimer(args.time)
-        reg.apiGen()
-        endTimer(args.time, '* Time to generate ' + options.filename + ' =')
-
-    if not args.quiet:
-        write('* Generated', options.filename, file=sys.stderr)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 7020df5..939ccad 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -19,20 +19,16 @@
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
+
 
 # Make sure tests uses the dynamic runtime instead
 set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
 
-# For MSVC/Windows, replace /GR with an empty string, this prevents warnings of /GR being overriden by /GR-
-# Newer CMake versions (3.20) have better solutions for this through policy - using the old
-# way while waiting for when updating can occur
-string(REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
-
 if (IS_DIRECTORY "${GOOGLETEST_INSTALL_DIR}/googletest")
     set(BUILD_GTEST ON)
     set(BUILD_GMOCK OFF)
     set(gtest_force_shared_crt ON)
-    set(BUILD_SHARED_LIBS ON)
     set(INSTALL_GTEST OFF)
     add_subdirectory("${GOOGLETEST_INSTALL_DIR}" ${CMAKE_CURRENT_BINARY_DIR}/gtest)
 else()
@@ -74,6 +70,8 @@
 
 option(ENABLE_LIVE_VERIFICATION_TESTS "Enable tests which expect to run on live drivers. Meant for manual verification only" OFF)
 
+set(TEST_EXECUTION_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/executing_tests")
+
 include(GoogleTest)
 add_subdirectory(framework)
 
@@ -84,7 +82,6 @@
         loader_envvar_tests.cpp
         loader_get_proc_addr_tests.cpp
         loader_debug_ext_tests.cpp
-        loader_fuzz_tests.cpp
         loader_handle_validation_tests.cpp
         loader_layer_tests.cpp
         loader_regression_tests.cpp
@@ -96,6 +93,18 @@
 target_link_libraries(test_regression PUBLIC testing_dependencies)
 target_compile_definitions(test_regression PUBLIC VK_NO_PROTOTYPES)
 
+add_executable(
+    test_fuzzing
+        loader_testing_main.cpp
+        loader_fuzz_tests.cpp
+)
+target_link_libraries(test_fuzzing PUBLIC testing_dependencies)
+# testing_dependencies already links to vulkan when linking statically
+if (NOT APPLE_STATIC_LOADER)
+    target_link_libraries(test_fuzzing PUBLIC vulkan)
+endif()
+target_include_directories(test_fuzzing PUBLIC ${CMAKE_SOURCE_DIR}/loader ${CMAKE_SOURCE_DIR}/loader/generated)
+
 # Threading tests live in separate executabe just for threading tests as it'll need support
 # in the test harness to enable in CI, as thread sanitizer doesn't work with address sanitizer enabled.
 add_executable(
@@ -111,19 +120,10 @@
 endif()
 
 if(WIN32)
-    # Copy loader and googletest (gtest) libs to test dir so the test executable can find them.
-    add_custom_command(TARGET test_regression POST_BUILD
-                       COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:gtest> $<TARGET_FILE_DIR:test_regression>)
-    # Copy the loader shared lib (if built) to the test application directory so the test app finds it.
+    # Copy vulkan-1.dll to the test_fuzzing build directory so that the test_fuzzing exe can find it.
     if(TARGET vulkan)
-        add_custom_command(TARGET test_regression POST_BUILD
-                           COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:vulkan> $<TARGET_FILE_DIR:test_regression>)
-    endif()
-
-    # Copy the gtest shared lib (if built) to the live verification tests directory so the tests finds it.
-    if(ENABLE_LIVE_VERIFICATION_TESTS)
-        add_custom_command(TARGET test_regression POST_BUILD
-                           COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:gtest> $<TARGET_FILE_DIR:dynamic_rendering_get_proc_addr>)
+        add_custom_command(TARGET test_fuzzing POST_BUILD
+                           COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:vulkan> $<TARGET_FILE_DIR:test_fuzzing>)
     endif()
 endif()
 
@@ -138,8 +138,12 @@
 # must happen after the dll's get copied over
 if(NOT CMAKE_CROSSCOMPILING)
     gtest_discover_tests(test_regression PROPERTIES DISCOVERY_TIMEOUT 100)
+    gtest_discover_tests(test_fuzzing PROPERTIES DISCOVERY_TIMEOUT 100)
+    gtest_discover_tests(test_threading PROPERTIES DISCOVERY_TIMEOUT 100)
 else()
     gtest_add_tests(TARGET test_regression)
+    gtest_add_tests(TARGET test_fuzzing)
+    gtest_add_tests(TARGET test_threading)
 endif()
 
 # When APPLE_STATIC_LOADER is ON installation is disabled
@@ -173,4 +177,5 @@
 
 if (CODE_COVERAGE)
     target_code_coverage(test_regression AUTO ALL )
+    target_code_coverage(test_fuzzing AUTO ALL )
 endif()
diff --git a/tests/framework/CMakeLists.txt b/tests/framework/CMakeLists.txt
index 38c7813..0e6bff1 100644
--- a/tests/framework/CMakeLists.txt
+++ b/tests/framework/CMakeLists.txt
@@ -15,42 +15,15 @@
 # limitations under the License.
 # ~~~
 
-add_library(testing_framework_util STATIC test_util.cpp)
-target_link_libraries(testing_framework_util PUBLIC loader_common_options Vulkan::Headers)
+#configure the framework_config.h.in file - used to locate all the binaries generated so that it can be used in the tests
+#setup framework_config_temp.h.in in the current binary directory
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/framework_config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/framework_config_temp.h.in")
 
-if(UNIX OR APPLE)
-    target_link_libraries(testing_framework_util PUBLIC ${CMAKE_DL_LIBS})
-endif()
+# setup framework_config_$<CONFIG> using framework_config_temp.h.in as a source
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/framework_config_$<CONFIG>.h" INPUT "${CMAKE_CURRENT_BINARY_DIR}/framework_config_temp.h.in")
 
-if(UNIX)
-    target_compile_options(testing_framework_util PUBLIC -fPIC)
-endif()
-# Gives access to all headers in the framework folder, in the framework binary, and in the whole project (mainly for loader/generated)
-target_include_directories(testing_framework_util PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})
-
-if (UNIX)
-    if (LOADER_ENABLE_ADDRESS_SANITIZER)
-        target_compile_options(testing_framework_util PUBLIC -fsanitize=address)
-        target_link_options(testing_framework_util PUBLIC -fsanitize=address)
-    endif()
-    if (LOADER_ENABLE_THREAD_SANITIZER)
-        target_compile_options(testing_framework_util PUBLIC -fsanitize=thread)
-        target_link_options(testing_framework_util PUBLIC -fsanitize=thread)
-        target_compile_options(gtest PUBLIC -fsanitize=thread)
-        target_link_options(gtest PUBLIC -fsanitize=thread)
-    endif()
-    if (LOADER_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER)
-        target_compile_options(testing_framework_util PUBLIC -fsanitize=undefined)
-        target_link_options(testing_framework_util PUBLIC -fsanitize=undefined)
-    endif()
-endif()
-
-if (MSVC)
-    # silence hidden class member warnings in test framework
-    target_compile_options(testing_framework_util PUBLIC /wd4458)
-    # Make sure exception handling is enabled for the test framework
-    target_compile_options(testing_framework_util PUBLIC /EHsc)
-endif()
+# Create a variable to hold the path to the correct header file, used as a compiler definition in the utils target
+set(FRAMEWORK_CONFIG_HEADER_PATH "${CMAKE_CURRENT_BINARY_DIR}/framework_config_$<CONFIG>.h")
 
 function(AddSharedLibrary LIBRARY_NAME)
     set(singleValueArgs DEF_FILE)
@@ -67,27 +40,14 @@
     endif()
 endfunction()
 
+add_subdirectory(util)
 add_subdirectory(data)
 add_subdirectory(shim)
 add_subdirectory(icd)
 add_subdirectory(layer)
 
-#configure the framework_config.h.in file - used to locate all the binaries generated so that it can be used in the tests
-#setup framework_config_temp.h.in in the current binary directory
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/framework_config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/framework_config_temp.h.in")
-
-# setup framework_config_$<CONFIG> using framework_config_temp.h.in as a source
-file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/framework_config_$<CONFIG>.h" INPUT "${CMAKE_CURRENT_BINARY_DIR}/framework_config_temp.h.in")
-
-# Add a compiler definition for the path to framework_config.h with the correct config
-target_compile_definitions(testing_framework_util PUBLIC FRAMEWORK_CONFIG_HEADER="framework_config_$<CONFIG>.h")
-
 add_library(testing_dependencies STATIC test_environment.cpp test_environment.h)
 target_link_libraries(testing_dependencies
     PUBLIC gtest Vulkan::Headers testing_framework_util shim-library)
 target_include_directories(testing_dependencies PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
-target_compile_definitions(testing_dependencies PUBLIC "GTEST_LINKED_AS_SHARED_LIBRARY=1")
-if (APPLE_STATIC_LOADER)
-    target_compile_definitions(testing_dependencies PUBLIC "APPLE_STATIC_LOADER=1")
-    target_link_libraries(testing_dependencies PUBLIC vulkan)
-endif()
+
diff --git a/tests/framework/README.md b/tests/framework/README.md
index 1dc5b73..20e1209 100644
--- a/tests/framework/README.md
+++ b/tests/framework/README.md
@@ -136,8 +136,7 @@
 * Environment Variable Wrapper: `EnvVarWrapper` for creating, setting, getting, and removing environment variables in a RAII manner
 * Windows API error handling helpers
 * filesystem abstractions:
-  * `create_folder`/`delete_folder`
-  * `FolderManager`
+  * `Folder`
     * Creates a new folder with the given name at construction time.
     * Allows writing manifests and files (eg, icd or layer binaries)
     * Automatically destroys the folder and all contained files at destruction
diff --git a/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-instance_create_fuzzer-5817896795701248 b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-instance_create_fuzzer-5817896795701248
new file mode 100644
index 0000000..7098959
--- /dev/null
+++ b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-instance_create_fuzzer-5817896795701248
Binary files differ
diff --git a/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-instance_create_fuzzer-6541440380895232 b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-instance_create_fuzzer-6541440380895232
new file mode 100644
index 0000000..e748a3c
--- /dev/null
+++ b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-instance_create_fuzzer-6541440380895232
Binary files differ
diff --git a/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_create_advanced_fuzzer-4788849181261824 b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_create_advanced_fuzzer-4788849181261824
new file mode 100644
index 0000000..703cc9c
--- /dev/null
+++ b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_create_advanced_fuzzer-4788849181261824
Binary files differ
diff --git a/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_create_advanced_fuzzer-5612556809207808 b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_create_advanced_fuzzer-5612556809207808
new file mode 100644
index 0000000..a492827
--- /dev/null
+++ b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_create_advanced_fuzzer-5612556809207808
Binary files differ
diff --git a/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6470575830925312 b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6470575830925312
new file mode 100644
index 0000000..a38496a
--- /dev/null
+++ b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6470575830925312
Binary files differ
diff --git a/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6740380288876544 b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6740380288876544
new file mode 100644
index 0000000..c5a8b7b
--- /dev/null
+++ b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6740380288876544
Binary files differ
diff --git a/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-settings_fuzzer-4626669072875520 b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-settings_fuzzer-4626669072875520
new file mode 100644
index 0000000..ad9eccc
--- /dev/null
+++ b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-settings_fuzzer-4626669072875520
Binary files differ
diff --git a/tests/framework/data/fuzzer_output.json b/tests/framework/data/fuzzer_output.json
index 5713780..6032f80 100644
--- a/tests/framework/data/fuzzer_output.json
+++ b/tests/framework/data/fuzzer_output.json
@@ -6,7 +6,7 @@
                 "/out/settings_fuzzer",
                 "/work/settings_fuzzer"
             ],
-            "stderr_log": [
+            "stderr_logg": [
                 "all",
                 "info",
                 "warn",
@@ -15,7 +15,8 @@
                 "debug",
                 "layer",
                 "driver",
-                "validation"
+                "validation",
+                "not_real"
             ],
             "log_locations": [
                 {
diff --git a/tests/framework/framework_config.h.in b/tests/framework/framework_config.h.in
index d8d21b9..8c0c1f7 100644
--- a/tests/framework/framework_config.h.in
+++ b/tests/framework/framework_config.h.in
@@ -26,7 +26,7 @@
  */
 
 #pragma once
-#define FRAMEWORK_BUILD_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+#define TEST_EXECUTION_DIRECTORY "${TEST_EXECUTION_DIRECTORY}"
 
 #define FRAMEWORK_VULKAN_LIBRARY_PATH "$<TARGET_FILE:vulkan>"
 
@@ -77,8 +77,8 @@
 #if _WIN32 || _WIN64
 #define DUMMY_BINARY_WINDOWS_64 "${CMAKE_CURRENT_SOURCE_DIR}/data/binaries/dummy_library_pe_64.dll"
 #define DUMMY_BINARY_WINDOWS_32 "${CMAKE_CURRENT_SOURCE_DIR}/data/binaries/dummy_library_pe_32.dll"
-#define BAD_DUMMY_BINARY_WINDOWS_64 "${CMAKE_CURRENT_SOURCE_DIR}/data/binaries/libdummy_library_elf_64.dll"
-#define BAD_DUMMY_BINARY_WINDOWS_32 "${CMAKE_CURRENT_SOURCE_DIR}/data/binaries/libdummy_library_elf_32.dll"
+#define BAD_DUMMY_BINARY_WINDOWS_64 "${CMAKE_CURRENT_SOURCE_DIR}/data/binaries/dummy_library_elf_64.dll"
+#define BAD_DUMMY_BINARY_WINDOWS_32 "${CMAKE_CURRENT_SOURCE_DIR}/data/binaries/dummy_library_elf_32.dll"
 #endif
 #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__GNU__) || defined(__QNX__)
 #define DUMMY_BINARY_LINUX_64 "${CMAKE_CURRENT_SOURCE_DIR}/data/binaries/libdummy_library_elf_64.so"
diff --git a/tests/framework/generated/vk_result_to_string_helper.h b/tests/framework/generated/vk_result_to_string_helper.h
new file mode 100644
index 0000000..b2c8659
--- /dev/null
+++ b/tests/framework/generated/vk_result_to_string_helper.h
@@ -0,0 +1,135 @@
+#pragma once
+// *** THIS FILE IS GENERATED - DO NOT EDIT ***
+// See vk_result_to_string_generator.py for modifications
+
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+
+ */
+
+#include <ostream>
+#include <string>
+
+#include <vulkan/vulkan.h>
+
+inline std::ostream& operator<<(std::ostream& os, const VkResult& result) {
+    switch (result) {
+        case (VK_SUCCESS):
+            return os << "VK_SUCCESS";
+        case (VK_NOT_READY):
+            return os << "VK_NOT_READY";
+        case (VK_TIMEOUT):
+            return os << "VK_TIMEOUT";
+        case (VK_EVENT_SET):
+            return os << "VK_EVENT_SET";
+        case (VK_EVENT_RESET):
+            return os << "VK_EVENT_RESET";
+        case (VK_INCOMPLETE):
+            return os << "VK_INCOMPLETE";
+        case (VK_ERROR_OUT_OF_HOST_MEMORY):
+            return os << "VK_ERROR_OUT_OF_HOST_MEMORY";
+        case (VK_ERROR_OUT_OF_DEVICE_MEMORY):
+            return os << "VK_ERROR_OUT_OF_DEVICE_MEMORY";
+        case (VK_ERROR_INITIALIZATION_FAILED):
+            return os << "VK_ERROR_INITIALIZATION_FAILED";
+        case (VK_ERROR_DEVICE_LOST):
+            return os << "VK_ERROR_DEVICE_LOST";
+        case (VK_ERROR_MEMORY_MAP_FAILED):
+            return os << "VK_ERROR_MEMORY_MAP_FAILED";
+        case (VK_ERROR_LAYER_NOT_PRESENT):
+            return os << "VK_ERROR_LAYER_NOT_PRESENT";
+        case (VK_ERROR_EXTENSION_NOT_PRESENT):
+            return os << "VK_ERROR_EXTENSION_NOT_PRESENT";
+        case (VK_ERROR_FEATURE_NOT_PRESENT):
+            return os << "VK_ERROR_FEATURE_NOT_PRESENT";
+        case (VK_ERROR_INCOMPATIBLE_DRIVER):
+            return os << "VK_ERROR_INCOMPATIBLE_DRIVER";
+        case (VK_ERROR_TOO_MANY_OBJECTS):
+            return os << "VK_ERROR_TOO_MANY_OBJECTS";
+        case (VK_ERROR_FORMAT_NOT_SUPPORTED):
+            return os << "VK_ERROR_FORMAT_NOT_SUPPORTED";
+        case (VK_ERROR_FRAGMENTED_POOL):
+            return os << "VK_ERROR_FRAGMENTED_POOL";
+        case (VK_ERROR_UNKNOWN):
+            return os << "VK_ERROR_UNKNOWN";
+        case (VK_ERROR_VALIDATION_FAILED):
+            return os << "VK_ERROR_VALIDATION_FAILED";
+        case (VK_ERROR_OUT_OF_POOL_MEMORY):
+            return os << "VK_ERROR_OUT_OF_POOL_MEMORY";
+        case (VK_ERROR_INVALID_EXTERNAL_HANDLE):
+            return os << "VK_ERROR_INVALID_EXTERNAL_HANDLE";
+        case (VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS):
+            return os << "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS";
+        case (VK_ERROR_FRAGMENTATION):
+            return os << "VK_ERROR_FRAGMENTATION";
+        case (VK_PIPELINE_COMPILE_REQUIRED):
+            return os << "VK_PIPELINE_COMPILE_REQUIRED";
+        case (VK_ERROR_NOT_PERMITTED):
+            return os << "VK_ERROR_NOT_PERMITTED";
+        case (VK_ERROR_SURFACE_LOST_KHR):
+            return os << "VK_ERROR_SURFACE_LOST_KHR";
+        case (VK_ERROR_NATIVE_WINDOW_IN_USE_KHR):
+            return os << "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
+        case (VK_SUBOPTIMAL_KHR):
+            return os << "VK_SUBOPTIMAL_KHR";
+        case (VK_ERROR_OUT_OF_DATE_KHR):
+            return os << "VK_ERROR_OUT_OF_DATE_KHR";
+        case (VK_ERROR_INCOMPATIBLE_DISPLAY_KHR):
+            return os << "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
+        case (VK_ERROR_INVALID_SHADER_NV):
+            return os << "VK_ERROR_INVALID_SHADER_NV";
+        case (VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR):
+            return os << "VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR";
+        case (VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR):
+            return os << "VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR";
+        case (VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR):
+            return os << "VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR";
+        case (VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR):
+            return os << "VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR";
+        case (VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR):
+            return os << "VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR";
+        case (VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR):
+            return os << "VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR";
+        case (VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT):
+            return os << "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
+        case (VK_ERROR_PRESENT_TIMING_QUEUE_FULL_EXT):
+            return os << "VK_ERROR_PRESENT_TIMING_QUEUE_FULL_EXT";
+        case (VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT):
+            return os << "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
+        case (VK_THREAD_IDLE_KHR):
+            return os << "VK_THREAD_IDLE_KHR";
+        case (VK_THREAD_DONE_KHR):
+            return os << "VK_THREAD_DONE_KHR";
+        case (VK_OPERATION_DEFERRED_KHR):
+            return os << "VK_OPERATION_DEFERRED_KHR";
+        case (VK_OPERATION_NOT_DEFERRED_KHR):
+            return os << "VK_OPERATION_NOT_DEFERRED_KHR";
+        case (VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR):
+            return os << "VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR";
+        case (VK_ERROR_COMPRESSION_EXHAUSTED_EXT):
+            return os << "VK_ERROR_COMPRESSION_EXHAUSTED_EXT";
+        case (VK_INCOMPATIBLE_SHADER_BINARY_EXT):
+            return os << "VK_INCOMPATIBLE_SHADER_BINARY_EXT";
+        case (VK_PIPELINE_BINARY_MISSING_KHR):
+            return os << "VK_PIPELINE_BINARY_MISSING_KHR";
+        case (VK_ERROR_NOT_ENOUGH_SPACE_KHR):
+            return os << "VK_ERROR_NOT_ENOUGH_SPACE_KHR";
+        default:
+            return os << static_cast<int32_t>(result);
+    }
+}
diff --git a/tests/framework/icd/test_icd.cpp b/tests/framework/icd/test_icd.cpp
index f42012c..8a89d5d 100644
--- a/tests/framework/icd/test_icd.cpp
+++ b/tests/framework/icd/test_icd.cpp
@@ -29,6 +29,13 @@
 
 #include "test_icd.h"
 
+#include <assert.h>
+#include <cstring>
+
+#include <iostream>
+
+#include "equality_helpers.h"
+
 // export vk_icdGetInstanceProcAddr
 #if !defined(TEST_ICD_EXPORT_ICD_GIPA)
 #define TEST_ICD_EXPORT_ICD_GIPA 0
@@ -80,19 +87,21 @@
 }
 
 bool IsInstanceExtensionSupported(const char* extension_name) {
+    std::lock_guard lg(icd.mutex);
     return icd.instance_extensions.end() !=
            std::find_if(icd.instance_extensions.begin(), icd.instance_extensions.end(),
                         [extension_name](Extension const& ext) { return string_eq(&ext.extensionName[0], extension_name); });
 }
 
 bool IsInstanceExtensionEnabled(const char* extension_name) {
+    std::lock_guard lg(icd.mutex);
     return icd.enabled_instance_extensions.end() !=
            std::find_if(icd.enabled_instance_extensions.begin(), icd.enabled_instance_extensions.end(),
                         [extension_name](Extension const& ext) { return string_eq(&ext.extensionName[0], extension_name); });
 }
 
 bool IsPhysicalDeviceExtensionAvailable(const char* extension_name) {
-    for (auto& phys_dev : icd.physical_devices) {
+    for (auto const& [phys_dev_handle, phys_dev] : icd.physical_devices) {
         if (phys_dev.extensions.end() !=
             std::find_if(phys_dev.extensions.begin(), phys_dev.extensions.end(),
                          [extension_name](Extension const& ext) { return ext.extensionName == extension_name; })) {
@@ -102,6 +111,44 @@
     return false;
 }
 
+PhysicalDevice& GetPhysDevice(VkPhysicalDevice physicalDevice) {
+    if (icd.physical_devices.count(physicalDevice) > 0) {
+        return icd.physical_devices.at(physicalDevice);
+    }
+    assert(false && "vkPhysicalDevice not found!");
+    return icd.physical_devices.at(icd.physical_devices.begin()->first);
+}
+
+bool is_valid_surface(VkSurfaceKHR surface_to_check) {
+    uint64_t surf_handle = (uint64_t)(surface_to_check);
+    auto found = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), surf_handle);
+    return found != icd.surface_handles.end();
+}
+
+struct FindDevice {
+    bool found = false;
+    VkPhysicalDevice phys_dev = 0;
+    uint32_t dev_index = 0;
+};
+
+FindDevice lookup_device(VkDevice device) {
+    FindDevice fd{};
+    auto it = icd.device_to_physical_device_map.find(device);
+    if (it != icd.device_to_physical_device_map.end()) {
+        auto& phys_dev = icd.physical_devices.at(it->second);
+        fd.found = true;
+        fd.phys_dev = phys_dev.vk_physical_device.handle;
+        for (uint32_t d = 0; d < phys_dev.device_handles.size(); d++) {
+            if (phys_dev.device_handles.at(d) == device) {
+                fd.dev_index = d;
+                break;
+            }
+        }
+        return fd;
+    }
+    return fd;
+}
+
 // typename T must have '.get()' function that returns a type U
 template <typename T, typename U>
 VkResult FillCountPtr(std::vector<T> const& data_vec, uint32_t* pCount, U* pData) {
@@ -155,11 +202,21 @@
     return VK_SUCCESS;
 }
 
+void check_allocator_handle(const VkAllocationCallbacks* pAllocator) {
+    if (pAllocator) {
+        if (nullptr == pAllocator->pfnAllocation || nullptr == pAllocator->pfnFree || nullptr == pAllocator->pfnReallocation) {
+            std::cout << "pAllocator functions are NULL!\n";
+            abort();
+        }
+    }
+}
+
 //// Instance Functions ////
 
 // VK_SUCCESS,VK_INCOMPLETE
 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount,
                                                                            VkExtensionProperties* pProperties) {
+    std::lock_guard lg(icd.mutex);
     if (pLayerName != nullptr) {
         auto& layer = FindLayer(icd.instance_layers, std::string(pLayerName));
         return FillCountPtr(layer.extensions, pPropertyCount, pProperties);
@@ -171,10 +228,12 @@
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount, VkLayerProperties* pProperties) {
+    std::lock_guard lg(icd.mutex);
     return FillCountPtr(icd.instance_layers, pPropertyCount, pProperties);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceVersion(uint32_t* pApiVersion) {
+    std::lock_guard lg(icd.mutex);
     if (pApiVersion != nullptr) {
         *pApiVersion = icd.icd_api_version;
     }
@@ -182,11 +241,12 @@
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
-                                                     [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                     VkInstance* pInstance) {
+                                                     const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
+    std::lock_guard lg(icd.mutex);
     if (pCreateInfo == nullptr) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
+    check_allocator_handle(pAllocator);
 
     uint32_t default_api_version = VK_API_VERSION_1_0;
     uint32_t api_version =
@@ -214,29 +274,38 @@
     return VK_SUCCESS;
 }
 
-VKAPI_ATTR void VKAPI_CALL test_vkDestroyInstance([[maybe_unused]] VkInstance instance,
-                                                  [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
+VKAPI_ATTR void VKAPI_CALL test_vkDestroyInstance([[maybe_unused]] VkInstance instance, const VkAllocationCallbacks* pAllocator) {
+    std::lock_guard lg(icd.mutex);
     icd.enabled_instance_extensions.clear();
+    check_allocator_handle(pAllocator);
 }
 
 // VK_SUCCESS,VK_INCOMPLETE
 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices([[maybe_unused]] VkInstance instance, uint32_t* pPhysicalDeviceCount,
                                                                VkPhysicalDevice* pPhysicalDevices) {
+    std::lock_guard lg(icd.mutex);
     if (icd.enum_physical_devices_return_code != VK_SUCCESS) {
         return icd.enum_physical_devices_return_code;
     }
     if (pPhysicalDevices == nullptr) {
         *pPhysicalDeviceCount = static_cast<uint32_t>(icd.physical_devices.size());
     } else {
+        using SortPair = std::pair<size_t, VkPhysicalDevice>;
+        std::vector<SortPair> in_order_phys_dev;
+        for (auto const& [phys_dev_handle, phys_dev] : icd.physical_devices) {
+            in_order_phys_dev.push_back({phys_dev.iteration_order, phys_dev_handle});
+        }
+
+        std::sort(in_order_phys_dev.begin(), in_order_phys_dev.end(),
+                  [](SortPair const& a, SortPair const& b) { return a.first < b.first; });
+
         uint32_t handles_written = 0;
-        for (size_t i = 0; i < icd.physical_devices.size(); i++) {
-            if (i < *pPhysicalDeviceCount) {
-                handles_written++;
-                pPhysicalDevices[i] = icd.physical_devices[i].vk_physical_device.handle;
-            } else {
+        for (auto const& phys_dev : in_order_phys_dev) {
+            if (handles_written + 1 > *pPhysicalDeviceCount) {
                 *pPhysicalDeviceCount = handles_written;
                 return VK_INCOMPLETE;
             }
+            pPhysicalDevices[handles_written++] = phys_dev.second;
         }
         *pPhysicalDeviceCount = handles_written;
     }
@@ -247,6 +316,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL
 test_vkEnumeratePhysicalDeviceGroups([[maybe_unused]] VkInstance instance, uint32_t* pPhysicalDeviceGroupCount,
                                      VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
+    std::lock_guard lg(icd.mutex);
     VkResult result = VK_SUCCESS;
 
     if (pPhysicalDeviceGroupProperties == nullptr) {
@@ -276,10 +346,15 @@
                     result = VK_INCOMPLETE;
                     break;
                 }
+
                 pPhysicalDeviceGroupProperties[device_group].subsetAllocation = false;
                 pPhysicalDeviceGroupProperties[device_group].physicalDeviceCount = 1;
-                pPhysicalDeviceGroupProperties[device_group].physicalDevices[0] =
-                    icd.physical_devices[device_group].vk_physical_device.handle;
+                for (auto const& [phys_dev_handle, phys_dev] : icd.physical_devices) {
+                    if (phys_dev.iteration_order == device_group) {
+                        pPhysicalDeviceGroupProperties[device_group].physicalDevices[0] = phys_dev_handle;
+                        break;
+                    }
+                }
                 for (size_t i = 1; i < VK_MAX_DEVICE_GROUP_SIZE; i++) {
                     pPhysicalDeviceGroupProperties[device_group].physicalDevices[i] = {};
                 }
@@ -325,6 +400,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDebugUtilsMessengerEXT(
     [[maybe_unused]] VkInstance instance, [[maybe_unused]] const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
     const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pMessenger) {
         uint8_t* new_handle_ptr = nullptr;
         if (pAllocator) {
@@ -348,6 +424,7 @@
 VKAPI_ATTR void VKAPI_CALL test_vkDestroyDebugUtilsMessengerEXT([[maybe_unused]] VkInstance instance,
                                                                 VkDebugUtilsMessengerEXT messenger,
                                                                 const VkAllocationCallbacks* pAllocator) {
+    std::lock_guard lg(icd.mutex);
     if (messenger != VK_NULL_HANDLE) {
         uint64_t fake_msgr_handle = (uint64_t)(messenger);
         auto found_iter = std::find(icd.messenger_handles.begin(), icd.messenger_handles.end(), fake_msgr_handle);
@@ -372,6 +449,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDebugReportCallbackEXT(
     [[maybe_unused]] VkInstance instance, [[maybe_unused]] const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
     const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pCallback) {
         uint8_t* new_handle_ptr = nullptr;
         if (pAllocator) {
@@ -395,6 +473,7 @@
 VKAPI_ATTR void VKAPI_CALL test_vkDestroyDebugReportCallbackEXT([[maybe_unused]] VkInstance instance,
                                                                 VkDebugReportCallbackEXT callback,
                                                                 const VkAllocationCallbacks* pAllocator) {
+    std::lock_guard lg(icd.mutex);
     if (callback != VK_NULL_HANDLE) {
         uint64_t fake_msgr_handle = (uint64_t)(callback);
         auto found_iter = std::find(icd.callback_handles.begin(), icd.callback_handles.end(), fake_msgr_handle);
@@ -416,10 +495,10 @@
 
 // Debug utils & debug marker ext stubs
 VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectTagEXT(VkDevice dev, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) {
+    std::lock_guard lg(icd.mutex);
     if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
         VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pTagInfo->object);
-        if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
-            return VK_ERROR_DEVICE_LOST;
+        if (pd != lookup_device(dev).phys_dev) return VK_ERROR_DEVICE_LOST;
     }
     if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
         if (pTagInfo->object != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
@@ -430,10 +509,10 @@
     return VK_SUCCESS;
 }
 VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectNameEXT(VkDevice dev, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) {
+    std::lock_guard lg(icd.mutex);
     if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
         VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pNameInfo->object);
-        if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
-            return VK_ERROR_DEVICE_LOST;
+        if (pd != lookup_device(dev).phys_dev) return VK_ERROR_DEVICE_LOST;
     }
     if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
         if (pNameInfo->object != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
@@ -448,10 +527,10 @@
 VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerInsertEXT(VkCommandBuffer, const VkDebugMarkerMarkerInfoEXT*) {}
 
 VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectNameEXT(VkDevice dev, const VkDebugUtilsObjectNameInfoEXT* pNameInfo) {
+    std::lock_guard lg(icd.mutex);
     if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
         VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pNameInfo->objectHandle);
-        if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
-            return VK_ERROR_DEVICE_LOST;
+        if (pd != lookup_device(dev).phys_dev) return VK_ERROR_DEVICE_LOST;
     }
     if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
         if (pNameInfo->objectHandle != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
@@ -462,10 +541,10 @@
     return VK_SUCCESS;
 }
 VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectTagEXT(VkDevice dev, const VkDebugUtilsObjectTagInfoEXT* pTagInfo) {
+    std::lock_guard lg(icd.mutex);
     if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
         VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pTagInfo->objectHandle);
-        if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
-            return VK_ERROR_DEVICE_LOST;
+        if (pd != lookup_device(dev).phys_dev) return VK_ERROR_DEVICE_LOST;
     }
     if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
         if (pTagInfo->objectHandle != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
@@ -494,7 +573,8 @@
 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName,
                                                                          uint32_t* pPropertyCount,
                                                                          VkExtensionProperties* pProperties) {
-    auto& phys_dev = icd.GetPhysDevice(physicalDevice);
+    std::lock_guard lg(icd.mutex);
+    auto& phys_dev = GetPhysDevice(physicalDevice);
     if (pLayerName != nullptr) {
         assert(false && "Drivers don't contain layers???");
         return VK_SUCCESS;
@@ -506,41 +586,47 @@
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
                                                                          uint32_t* pQueueFamilyPropertyCount,
                                                                          VkQueueFamilyProperties* pQueueFamilyProperties) {
-    auto& phys_dev = icd.GetPhysDevice(physicalDevice);
+    std::lock_guard lg(icd.mutex);
+    auto& phys_dev = GetPhysDevice(physicalDevice);
     FillCountPtr(phys_dev.queue_family_properties, pQueueFamilyPropertyCount, pQueueFamilyProperties);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo,
-                                                   [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) {
-    // VK_SUCCESS
-    auto found = std::find_if(icd.physical_devices.begin(), icd.physical_devices.end(), [physicalDevice](PhysicalDevice& phys_dev) {
-        return phys_dev.vk_physical_device.handle == physicalDevice;
-    });
-    if (found == icd.physical_devices.end()) return VK_ERROR_INITIALIZATION_FAILED;
+                                                   const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
+    if (icd.physical_devices.count(physicalDevice) == 0) {
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+    auto& found = icd.physical_devices.at(physicalDevice);
     auto device_handle = DispatchableHandle<VkDevice>();
     *pDevice = device_handle.handle;
-    found->device_handles.push_back(device_handle.handle);
-    found->device_create_infos.push_back(DeviceCreateInfo{pCreateInfo});
+    found.device_handles.push_back(device_handle.handle);
+    found.device_create_infos.emplace_back(pCreateInfo);
     for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
-        found->queue_handles.emplace_back();
+        found.queue_handles.emplace_back();
     }
+    icd.device_to_physical_device_map.emplace(device_handle.handle, physicalDevice);
     icd.device_handles.emplace_back(std::move(device_handle));
-
     return VK_SUCCESS;
 }
 
-VKAPI_ATTR void VKAPI_CALL test_vkDestroyDevice(VkDevice device, [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
+VKAPI_ATTR void VKAPI_CALL test_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
     auto found = std::find(icd.device_handles.begin(), icd.device_handles.end(), device);
     if (found != icd.device_handles.end()) icd.device_handles.erase(found);
-    auto fd = icd.lookup_device(device);
+    auto fd = lookup_device(device);
     if (!fd.found) return;
-    auto& phys_dev = icd.physical_devices.at(fd.phys_dev_index);
+    auto& phys_dev = icd.physical_devices.at(fd.phys_dev);
     phys_dev.device_handles.erase(phys_dev.device_handles.begin() + fd.dev_index);
     phys_dev.device_create_infos.erase(phys_dev.device_create_infos.begin() + fd.dev_index);
+    icd.device_to_physical_device_map.erase(device);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL generic_tool_props_function([[maybe_unused]] VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
                                                            VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
+    std::lock_guard lg(icd.mutex);
     if (icd.tooling_properties.size() == 0) {
         return VK_SUCCESS;
     }
@@ -559,11 +645,13 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceToolPropertiesEXT(VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
                                                                          VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
+    std::lock_guard lg(icd.mutex);
     return generic_tool_props_function(physicalDevice, pToolCount, pToolProperties);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceToolProperties(VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
                                                                       VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
+    std::lock_guard lg(icd.mutex);
     return generic_tool_props_function(physicalDevice, pToolCount, pToolProperties);
 }
 
@@ -602,6 +690,7 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
                                                               const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    std::lock_guard lg(icd.mutex);
     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
     return VK_SUCCESS;
 }
@@ -610,9 +699,12 @@
 #if defined(VK_USE_PLATFORM_WIN32_KHR)
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateWin32SurfaceKHR([[maybe_unused]] VkInstance instance,
                                                             [[maybe_unused]] const VkWin32SurfaceCreateInfoKHR* pCreateInfo,
-                                                            [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                            VkSurfaceKHR* pSurface) {
-    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
+                                                            const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
+    if (IsInstanceExtensionSupported(VK_KHR_WIN32_SURFACE_EXTENSION_NAME)) {
+        common_nondispatch_handle_creation(icd.surface_handles, pSurface);
+    }
     return VK_SUCCESS;
 }
 
@@ -622,9 +714,12 @@
 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateWaylandSurfaceKHR([[maybe_unused]] VkInstance instance,
                                                               [[maybe_unused]] const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
-                                                              [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                              VkSurfaceKHR* pSurface) {
-    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
+                                                              const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
+    if (IsInstanceExtensionSupported(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME)) {
+        common_nondispatch_handle_creation(icd.surface_handles, pSurface);
+    }
     return VK_SUCCESS;
 }
 
@@ -636,9 +731,12 @@
 #if defined(VK_USE_PLATFORM_XCB_KHR)
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateXcbSurfaceKHR([[maybe_unused]] VkInstance instance,
                                                           [[maybe_unused]] const VkXcbSurfaceCreateInfoKHR* pCreateInfo,
-                                                          [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                          VkSurfaceKHR* pSurface) {
-    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
+                                                          const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
+    if (IsInstanceExtensionSupported(VK_KHR_XCB_SURFACE_EXTENSION_NAME)) {
+        common_nondispatch_handle_creation(icd.surface_handles, pSurface);
+    }
     return VK_SUCCESS;
 }
 
@@ -651,9 +749,12 @@
 #if defined(VK_USE_PLATFORM_XLIB_KHR)
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateXlibSurfaceKHR([[maybe_unused]] VkInstance instance,
                                                            [[maybe_unused]] const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
-                                                           [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                           VkSurfaceKHR* pSurface) {
-    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
+                                                           const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
+    if (IsInstanceExtensionSupported(VK_KHR_XCB_SURFACE_EXTENSION_NAME)) {
+        common_nondispatch_handle_creation(icd.surface_handles, pSurface);
+    }
     return VK_SUCCESS;
 }
 
@@ -665,8 +766,9 @@
 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDirectFBSurfaceEXT([[maybe_unused]] VkInstance instance,
                                                                [[maybe_unused]] const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo,
-                                                               [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                               VkSurfaceKHR* pSurface) {
+                                                               const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
     return VK_SUCCESS;
 }
@@ -680,8 +782,9 @@
 #if defined(VK_USE_PLATFORM_MACOS_MVK)
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateMacOSSurfaceMVK([[maybe_unused]] VkInstance instance,
                                                             [[maybe_unused]] const VkMacOSSurfaceCreateInfoMVK* pCreateInfo,
-                                                            [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                            VkSurfaceKHR* pSurface) {
+                                                            const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
     return VK_SUCCESS;
 }
@@ -690,8 +793,9 @@
 #if defined(VK_USE_PLATFORM_IOS_MVK)
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateIOSSurfaceMVK([[maybe_unused]] VkInstance instance,
                                                           [[maybe_unused]] const VkIOSSurfaceCreateInfoMVK* pCreateInfo,
-                                                          [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                          VkSurfaceKHR* pSurface) {
+                                                          const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
     return VK_SUCCESS;
 }
@@ -700,7 +804,9 @@
 #if defined(VK_USE_PLATFORM_GGP)
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateStreamDescriptorSurfaceGGP(
     [[maybe_unused]] VkInstance instance, [[maybe_unused]] const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo,
-    [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
     return VK_SUCCESS;
 }
@@ -709,8 +815,9 @@
 #if defined(VK_USE_PLATFORM_METAL_EXT)
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateMetalSurfaceEXT([[maybe_unused]] VkInstance instance,
                                                             [[maybe_unused]] const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
-                                                            [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                            VkSurfaceKHR* pSurface) {
+                                                            const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
     return VK_SUCCESS;
 }
@@ -719,8 +826,9 @@
 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateScreenSurfaceQNX([[maybe_unused]] VkInstance instance,
                                                              [[maybe_unused]] const VkScreenSurfaceCreateInfoQNX* pCreateInfo,
-                                                             [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                             VkSurfaceKHR* pSurface) {
+                                                             const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
     return VK_SUCCESS;
 }
@@ -733,17 +841,21 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateHeadlessSurfaceEXT([[maybe_unused]] VkInstance instance,
                                                                [[maybe_unused]] const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo,
-                                                               [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                               VkSurfaceKHR* pSurface) {
-    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
+                                                               const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
+    if (IsInstanceExtensionSupported(VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME)) {
+        common_nondispatch_handle_creation(icd.surface_handles, pSurface);
+    }
     return VK_SUCCESS;
 }
 
 VKAPI_ATTR void VKAPI_CALL test_vkDestroySurfaceKHR([[maybe_unused]] VkInstance instance, VkSurfaceKHR surface,
-                                                    [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
+                                                    const VkAllocationCallbacks* pAllocator) {
+    std::lock_guard lg(icd.mutex);
     if (surface != VK_NULL_HANDLE) {
-        uint64_t fake_surf_handle = from_nondispatch_handle(surface);
-        auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
+        uint64_t surf_handle = from_nondispatch_handle(surface);
+        auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), surf_handle);
         if (found_iter != icd.surface_handles.end()) {
             // Remove it from the list
             icd.surface_handles.erase(found_iter);
@@ -755,8 +867,9 @@
 // VK_KHR_swapchain
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateSwapchainKHR([[maybe_unused]] VkDevice device,
                                                          [[maybe_unused]] const VkSwapchainCreateInfoKHR* pCreateInfo,
-                                                         [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                         VkSwapchainKHR* pSwapchain) {
+                                                         const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
     common_nondispatch_handle_creation(icd.swapchain_handles, pSwapchain);
     return VK_SUCCESS;
 }
@@ -765,6 +878,7 @@
                                                             [[maybe_unused]] VkSwapchainKHR swapchain,
                                                             uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages) {
     std::vector<uint64_t> handles{123, 234, 345, 345, 456};
+    std::lock_guard lg(icd.mutex);
     if (pSwapchainImages == nullptr) {
         if (pSwapchainImageCount) *pSwapchainImageCount = static_cast<uint32_t>(handles.size());
     } else if (pSwapchainImageCount) {
@@ -777,7 +891,9 @@
 }
 
 VKAPI_ATTR void VKAPI_CALL test_vkDestroySwapchainKHR([[maybe_unused]] VkDevice device, VkSwapchainKHR swapchain,
-                                                      [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
+                                                      const VkAllocationCallbacks* pAllocator) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
     if (swapchain != VK_NULL_HANDLE) {
         uint64_t fake_swapchain_handle = from_nondispatch_handle(swapchain);
         auto found_iter = icd.swapchain_handles.erase(
@@ -800,94 +916,132 @@
 // VK_KHR_surface
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
                                                                          VkSurfaceKHR surface, VkBool32* pSupported) {
+    std::lock_guard lg(icd.mutex);
     if (surface != VK_NULL_HANDLE) {
-        uint64_t fake_surf_handle = (uint64_t)(surface);
-        auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
-        if (found_iter == icd.surface_handles.end()) {
-            assert(false && "Surface not found during GetPhysicalDeviceSurfaceSupportKHR query!");
-            return VK_ERROR_UNKNOWN;
+        if (!is_valid_surface(surface)) {
+            *pSupported = VK_FALSE;
+            return VK_SUCCESS;
         }
     }
     if (nullptr != pSupported) {
-        *pSupported = icd.GetPhysDevice(physicalDevice).queue_family_properties.at(queueFamilyIndex).support_present;
+        if (icd.physical_devices.count(physicalDevice) > 0) {
+            *pSupported = icd.physical_devices.at(physicalDevice).queue_family_properties.at(queueFamilyIndex).support_present;
+        } else {
+            *pSupported = VK_FALSE;
+            return VK_SUCCESS;
+        }
     }
     return VK_SUCCESS;
 }
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
                                                                               VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) {
+    std::lock_guard lg(icd.mutex);
     if (surface != VK_NULL_HANDLE) {
-        uint64_t fake_surf_handle = (uint64_t)(surface);
-        auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
-        if (found_iter == icd.surface_handles.end()) {
+        if (!is_valid_surface(surface)) {
             assert(false && "Surface not found during GetPhysicalDeviceSurfaceCapabilitiesKHR query!");
             return VK_ERROR_UNKNOWN;
         }
     }
     if (nullptr != pSurfaceCapabilities) {
-        *pSurfaceCapabilities = icd.GetPhysDevice(physicalDevice).surface_capabilities;
+        *pSurfaceCapabilities = GetPhysDevice(physicalDevice).surface_capabilities;
     }
     return VK_SUCCESS;
 }
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
                                                                          uint32_t* pSurfaceFormatCount,
                                                                          VkSurfaceFormatKHR* pSurfaceFormats) {
+    std::lock_guard lg(icd.mutex);
     if (surface != VK_NULL_HANDLE) {
-        uint64_t fake_surf_handle = (uint64_t)(surface);
-        auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
-        if (found_iter == icd.surface_handles.end()) {
+        if (!is_valid_surface(surface)) {
             assert(false && "Surface not found during GetPhysicalDeviceSurfaceFormatsKHR query!");
             return VK_ERROR_UNKNOWN;
         }
+    } else {
+        if (!IsInstanceExtensionEnabled(VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME)) {
+            assert(false && "Surface is NULL but VK_GOOGLE_surfaceless_query was not enabled!");
+            return VK_ERROR_UNKNOWN;
+        }
     }
-    FillCountPtr(icd.GetPhysDevice(physicalDevice).surface_formats, pSurfaceFormatCount, pSurfaceFormats);
+    FillCountPtr(GetPhysDevice(physicalDevice).surface_formats, pSurfaceFormatCount, pSurfaceFormats);
     return VK_SUCCESS;
 }
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
                                                                               uint32_t* pPresentModeCount,
                                                                               VkPresentModeKHR* pPresentModes) {
+    std::lock_guard lg(icd.mutex);
     if (surface != VK_NULL_HANDLE) {
-        uint64_t fake_surf_handle = (uint64_t)(surface);
-        auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
-        if (found_iter == icd.surface_handles.end()) {
+        if (!is_valid_surface(surface)) {
             assert(false && "Surface not found during GetPhysicalDeviceSurfacePresentModesKHR query!");
             return VK_ERROR_UNKNOWN;
         }
+    } else {
+        if (!IsInstanceExtensionEnabled(VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME)) {
+            assert(false && "Surface is NULL but VK_GOOGLE_surfaceless_query was not enabled!");
+            return VK_ERROR_UNKNOWN;
+        }
     }
-    FillCountPtr(icd.GetPhysDevice(physicalDevice).surface_present_modes, pPresentModeCount, pPresentModes);
+    FillCountPtr(GetPhysDevice(physicalDevice).surface_present_modes, pPresentModeCount, pPresentModes);
     return VK_SUCCESS;
 }
 
+#if defined(WIN32)
+VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfacePresentModes2EXT(VkPhysicalDevice physicalDevice,
+                                                                               const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+                                                                               uint32_t* pPresentModeCount,
+                                                                               VkPresentModeKHR* pPresentModes) {
+    std::lock_guard lg(icd.mutex);
+    if (pSurfaceInfo->surface != VK_NULL_HANDLE) {
+        if (!is_valid_surface(pSurfaceInfo->surface)) {
+            assert(false && "Surface not found during GetPhysicalDeviceSurfacePresentModesKHR query!");
+            return VK_ERROR_UNKNOWN;
+        }
+    } else {
+        if (!IsInstanceExtensionEnabled(VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME)) {
+            assert(false && "Surface is NULL but VK_GOOGLE_surfaceless_query was not enabled!");
+            return VK_ERROR_UNKNOWN;
+        }
+    }
+    FillCountPtr(GetPhysDevice(physicalDevice).surface_present_modes, pPresentModeCount, pPresentModes);
+    return VK_SUCCESS;
+}
+#endif
+
 // VK_KHR_display
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
                                                                             uint32_t* pPropertyCount,
                                                                             VkDisplayPropertiesKHR* pProperties) {
-    FillCountPtr(icd.GetPhysDevice(physicalDevice).display_properties, pPropertyCount, pProperties);
+    std::lock_guard lg(icd.mutex);
+    FillCountPtr(GetPhysDevice(physicalDevice).display_properties, pPropertyCount, pProperties);
     return VK_SUCCESS;
 }
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
                                                                                  uint32_t* pPropertyCount,
                                                                                  VkDisplayPlanePropertiesKHR* pProperties) {
-    FillCountPtr(icd.GetPhysDevice(physicalDevice).display_plane_properties, pPropertyCount, pProperties);
+    std::lock_guard lg(icd.mutex);
+    FillCountPtr(GetPhysDevice(physicalDevice).display_plane_properties, pPropertyCount, pProperties);
     return VK_SUCCESS;
 }
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
                                                                           [[maybe_unused]] uint32_t planeIndex,
                                                                           uint32_t* pDisplayCount, VkDisplayKHR* pDisplays) {
-    FillCountPtr(icd.GetPhysDevice(physicalDevice).displays, pDisplayCount, pDisplays);
+    std::lock_guard lg(icd.mutex);
+    FillCountPtr(GetPhysDevice(physicalDevice).displays, pDisplayCount, pDisplays);
     return VK_SUCCESS;
 }
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice,
                                                                   [[maybe_unused]] VkDisplayKHR display, uint32_t* pPropertyCount,
                                                                   VkDisplayModePropertiesKHR* pProperties) {
-    FillCountPtr(icd.GetPhysDevice(physicalDevice).display_mode_properties, pPropertyCount, pProperties);
+    std::lock_guard lg(icd.mutex);
+    FillCountPtr(GetPhysDevice(physicalDevice).display_mode_properties, pPropertyCount, pProperties);
     return VK_SUCCESS;
 }
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, [[maybe_unused]] VkDisplayKHR display,
                                                            [[maybe_unused]] const VkDisplayModeCreateInfoKHR* pCreateInfo,
-                                                           [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                           VkDisplayModeKHR* pMode) {
+                                                           const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode) {
+    std::lock_guard lg(icd.mutex);
+    check_allocator_handle(pAllocator);
     if (nullptr != pMode) {
-        *pMode = icd.GetPhysDevice(physicalDevice).display_mode;
+        *pMode = GetPhysDevice(physicalDevice).display_mode;
     }
     return VK_SUCCESS;
 }
@@ -895,15 +1049,20 @@
                                                                      [[maybe_unused]] VkDisplayModeKHR mode,
                                                                      [[maybe_unused]] uint32_t planeIndex,
                                                                      VkDisplayPlaneCapabilitiesKHR* pCapabilities) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pCapabilities) {
-        *pCapabilities = icd.GetPhysDevice(physicalDevice).display_plane_capabilities;
+        *pCapabilities = GetPhysDevice(physicalDevice).display_plane_capabilities;
     }
     return VK_SUCCESS;
 }
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDisplayPlaneSurfaceKHR(
     [[maybe_unused]] VkInstance instance, [[maybe_unused]] const VkDisplaySurfaceCreateInfoKHR* pCreateInfo,
-    [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
-    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
+    const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
+    check_allocator_handle(pAllocator);
+    std::lock_guard lg(icd.mutex);
+    if (IsInstanceExtensionSupported(VK_KHR_DISPLAY_EXTENSION_NAME)) {
+        common_nondispatch_handle_creation(icd.surface_handles, pSurface);
+    }
     return VK_SUCCESS;
 }
 
@@ -911,10 +1070,11 @@
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
                                                                                const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
                                                                                VkSurfaceCapabilities2KHR* pSurfaceCapabilities) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pSurfaceInfo && nullptr != pSurfaceCapabilities) {
         if (IsInstanceExtensionSupported("VK_EXT_surface_maintenance1") &&
             IsInstanceExtensionEnabled("VK_EXT_surface_maintenance1")) {
-            auto& phys_dev = icd.GetPhysDevice(physicalDevice);
+            auto& phys_dev = GetPhysDevice(physicalDevice);
             void* pNext = pSurfaceCapabilities->pNext;
             while (pNext) {
                 VkBaseOutStructure pNext_base_structure{};
@@ -977,10 +1137,11 @@
                                                                           const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
                                                                           uint32_t* pSurfaceFormatCount,
                                                                           VkSurfaceFormat2KHR* pSurfaceFormats) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pSurfaceFormatCount) {
         test_vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount, nullptr);
         if (nullptr != pSurfaceFormats) {
-            auto& phys_dev = icd.GetPhysDevice(physicalDevice);
+            auto& phys_dev = GetPhysDevice(physicalDevice);
             // Since the structures are different, we have to copy each item over seperately.  Since we have multiple, we
             // have to manually copy the data here instead of calling the next function
             for (uint32_t cnt = 0; cnt < *pSurfaceFormatCount; ++cnt) {
@@ -993,8 +1154,10 @@
 // VK_KHR_display_swapchain
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateSharedSwapchainsKHR([[maybe_unused]] VkDevice device, uint32_t swapchainCount,
                                                                 const VkSwapchainCreateInfoKHR* pCreateInfos,
-                                                                [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
+                                                                const VkAllocationCallbacks* pAllocator,
                                                                 VkSwapchainKHR* pSwapchains) {
+    std::lock_guard lg(icd.mutex);
+    check_allocator_handle(pAllocator);
     for (uint32_t i = 0; i < swapchainCount; i++) {
         uint64_t surface_integer_value = from_nondispatch_handle(pCreateInfos[i].surface);
         auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), surface_integer_value);
@@ -1009,8 +1172,8 @@
 //// misc
 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateCommandPool([[maybe_unused]] VkDevice device,
                                                         [[maybe_unused]] const VkCommandPoolCreateInfo* pCreateInfo,
-                                                        [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
-                                                        VkCommandPool* pCommandPool) {
+                                                        const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool) {
+    check_allocator_handle(pAllocator);
     if (pCommandPool != nullptr) {
         pCommandPool = reinterpret_cast<VkCommandPool*>(0xdeadbeefdeadbeef);
     }
@@ -1023,6 +1186,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL test_vkAllocateCommandBuffers([[maybe_unused]] VkDevice device,
                                                              const VkCommandBufferAllocateInfo* pAllocateInfo,
                                                              VkCommandBuffer* pCommandBuffers) {
+    std::lock_guard lg(icd.mutex);
     if (pAllocateInfo != nullptr && pCommandBuffers != nullptr) {
         for (size_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
             icd.allocated_command_buffers.push_back({});
@@ -1034,9 +1198,10 @@
 
 VKAPI_ATTR void VKAPI_CALL test_vkGetDeviceQueue([[maybe_unused]] VkDevice device, [[maybe_unused]] uint32_t queueFamilyIndex,
                                                  uint32_t queueIndex, VkQueue* pQueue) {
-    auto fd = icd.lookup_device(device);
+    std::lock_guard lg(icd.mutex);
+    auto fd = lookup_device(device);
     if (fd.found) {
-        *pQueue = icd.physical_devices.at(fd.phys_dev_index).queue_handles[queueIndex].handle;
+        *pQueue = icd.physical_devices.at(fd.phys_dev).queue_handles[queueIndex].handle;
     }
 }
 
@@ -1045,8 +1210,9 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDrmDisplayEXT(VkPhysicalDevice physicalDevice, [[maybe_unused]] int32_t drmFd,
                                                        [[maybe_unused]] uint32_t connectorId, VkDisplayKHR* display) {
-    if (nullptr != display && icd.GetPhysDevice(physicalDevice).displays.size() > 0) {
-        *display = icd.GetPhysDevice(physicalDevice).displays[0];
+    std::lock_guard lg(icd.mutex);
+    if (nullptr != display && GetPhysDevice(physicalDevice).displays.size() > 0) {
+        *display = GetPhysDevice(physicalDevice).displays[0];
     }
     return VK_SUCCESS;
 }
@@ -1054,14 +1220,16 @@
 //// stubs
 // 1.0
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pFeatures) {
-        memcpy(pFeatures, &icd.GetPhysDevice(physicalDevice).features, sizeof(VkPhysicalDeviceFeatures));
+        memcpy(pFeatures, &GetPhysDevice(physicalDevice).features, sizeof(VkPhysicalDeviceFeatures));
     }
 }
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
                                                               VkPhysicalDeviceProperties* pProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pProperties) {
-        auto& phys_dev = icd.GetPhysDevice(physicalDevice);
+        auto& phys_dev = GetPhysDevice(physicalDevice);
         memcpy(pProperties, &phys_dev.properties, sizeof(VkPhysicalDeviceProperties));
         size_t max_len = (phys_dev.deviceName.length() > VK_MAX_PHYSICAL_DEVICE_NAME_SIZE) ? VK_MAX_PHYSICAL_DEVICE_NAME_SIZE
                                                                                            : phys_dev.deviceName.length();
@@ -1071,20 +1239,23 @@
 }
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
                                                                     VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pMemoryProperties) {
-        memcpy(pMemoryProperties, &icd.GetPhysDevice(physicalDevice).memory_properties, sizeof(VkPhysicalDeviceMemoryProperties));
+        memcpy(pMemoryProperties, &GetPhysDevice(physicalDevice).memory_properties, sizeof(VkPhysicalDeviceMemoryProperties));
     }
 }
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceSparseImageFormatProperties(
     VkPhysicalDevice physicalDevice, [[maybe_unused]] VkFormat format, [[maybe_unused]] VkImageType type,
     [[maybe_unused]] VkSampleCountFlagBits samples, [[maybe_unused]] VkImageUsageFlags usage, [[maybe_unused]] VkImageTiling tiling,
     uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties) {
-    FillCountPtr(icd.GetPhysDevice(physicalDevice).sparse_image_format_properties, pPropertyCount, pProperties);
+    std::lock_guard lg(icd.mutex);
+    FillCountPtr(GetPhysDevice(physicalDevice).sparse_image_format_properties, pPropertyCount, pProperties);
 }
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
                                                                     VkFormatProperties* pFormatProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pFormatProperties) {
-        memcpy(pFormatProperties, &icd.GetPhysDevice(physicalDevice).format_properties[static_cast<uint32_t>(format)],
+        memcpy(pFormatProperties, &GetPhysDevice(physicalDevice).format_properties[static_cast<uint32_t>(format)],
                sizeof(VkFormatProperties));
     }
 }
@@ -1092,8 +1263,9 @@
     VkPhysicalDevice physicalDevice, [[maybe_unused]] VkFormat format, [[maybe_unused]] VkImageType type,
     [[maybe_unused]] VkImageTiling tiling, [[maybe_unused]] VkImageUsageFlags usage, [[maybe_unused]] VkImageCreateFlags flags,
     VkImageFormatProperties* pImageFormatProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pImageFormatProperties) {
-        memcpy(pImageFormatProperties, &icd.GetPhysDevice(physicalDevice).image_format_properties, sizeof(VkImageFormatProperties));
+        memcpy(pImageFormatProperties, &GetPhysDevice(physicalDevice).image_format_properties, sizeof(VkImageFormatProperties));
     }
     return VK_SUCCESS;
 }
@@ -1101,14 +1273,16 @@
 // 1.1
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
                                                              VkPhysicalDeviceFeatures2* pFeatures) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pFeatures) {
         test_vkGetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
     }
 }
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
                                                                VkPhysicalDeviceProperties2* pProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pProperties) {
-        auto& phys_dev = icd.GetPhysDevice(physicalDevice);
+        auto& phys_dev = GetPhysDevice(physicalDevice);
         test_vkGetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
         VkBaseInStructure* pNext = reinterpret_cast<VkBaseInStructure*>(pProperties->pNext);
         while (pNext) {
@@ -1120,12 +1294,27 @@
                 auto* layered_driver_props = reinterpret_cast<VkPhysicalDeviceLayeredDriverPropertiesMSFT*>(pNext);
                 layered_driver_props->underlyingAPI = phys_dev.layered_driver_underlying_api;
             }
+            if (pNext->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES) {
+                auto* vulkan_11_props = reinterpret_cast<VkPhysicalDeviceVulkan11Properties*>(pNext);
+                memcpy(vulkan_11_props->deviceUUID, phys_dev.deviceUUID.data(), VK_UUID_SIZE);
+                memcpy(vulkan_11_props->driverUUID, phys_dev.driverUUID.data(), VK_UUID_SIZE);
+            }
+            if (pNext->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES) {
+                auto* device_id_props = reinterpret_cast<VkPhysicalDeviceIDProperties*>(pNext);
+                memcpy(device_id_props->deviceUUID, phys_dev.deviceUUID.data(), VK_UUID_SIZE);
+                memcpy(device_id_props->driverUUID, phys_dev.driverUUID.data(), VK_UUID_SIZE);
+            }
+            if (pNext->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES) {
+                auto* device_driver_props = reinterpret_cast<VkPhysicalDeviceDriverProperties*>(pNext);
+                *device_driver_props = phys_dev.driver_properties;
+            }
             pNext = reinterpret_cast<VkBaseInStructure*>(const_cast<VkBaseInStructure*>(pNext->pNext));
         }
     }
 }
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,
                                                                      VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pMemoryProperties) {
         test_vkGetPhysicalDeviceMemoryProperties(physicalDevice, &pMemoryProperties->memoryProperties);
     }
@@ -1133,10 +1322,11 @@
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
                                                                           uint32_t* pQueueFamilyPropertyCount,
                                                                           VkQueueFamilyProperties2* pQueueFamilyProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pQueueFamilyPropertyCount) {
         test_vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, nullptr);
         if (nullptr != pQueueFamilyProperties) {
-            auto& phys_dev = icd.GetPhysDevice(physicalDevice);
+            auto& phys_dev = GetPhysDevice(physicalDevice);
             // Since the structures are different, we have to copy each item over seperately.  Since we have multiple, we
             // have to manually copy the data here instead of calling the next function
             for (uint32_t queue = 0; queue < *pQueueFamilyPropertyCount; ++queue) {
@@ -1149,12 +1339,13 @@
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceSparseImageFormatProperties2(
     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount,
     VkSparseImageFormatProperties2* pProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pPropertyCount) {
         test_vkGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, pFormatInfo->format, pFormatInfo->type,
                                                             pFormatInfo->samples, pFormatInfo->usage, pFormatInfo->tiling,
                                                             pPropertyCount, nullptr);
         if (nullptr != pProperties) {
-            auto& phys_dev = icd.GetPhysDevice(physicalDevice);
+            auto& phys_dev = GetPhysDevice(physicalDevice);
             // Since the structures are different, we have to copy each item over seperately.  Since we have multiple, we
             // have to manually copy the data here instead of calling the next function
             for (uint32_t cnt = 0; cnt < *pPropertyCount; ++cnt) {
@@ -1166,6 +1357,7 @@
 }
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
                                                                      VkFormatProperties2* pFormatProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pFormatProperties) {
         test_vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &pFormatProperties->formatProperties);
     }
@@ -1173,6 +1365,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceImageFormatProperties2(
     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
     VkImageFormatProperties2* pImageFormatProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pImageFormatInfo) {
         VkImageFormatProperties* ptr = nullptr;
         if (pImageFormatProperties) {
@@ -1187,8 +1380,9 @@
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceExternalBufferProperties(
     VkPhysicalDevice physicalDevice, [[maybe_unused]] const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
     VkExternalBufferProperties* pExternalBufferProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pExternalBufferProperties) {
-        auto& phys_dev = icd.GetPhysDevice(physicalDevice);
+        auto& phys_dev = GetPhysDevice(physicalDevice);
         memcpy(&pExternalBufferProperties->externalMemoryProperties, &phys_dev.external_memory_properties,
                sizeof(VkExternalMemoryProperties));
     }
@@ -1196,16 +1390,18 @@
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceExternalSemaphoreProperties(
     VkPhysicalDevice physicalDevice, [[maybe_unused]] const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
     VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pExternalSemaphoreProperties) {
-        auto& phys_dev = icd.GetPhysDevice(physicalDevice);
+        auto& phys_dev = GetPhysDevice(physicalDevice);
         memcpy(pExternalSemaphoreProperties, &phys_dev.external_semaphore_properties, sizeof(VkExternalSemaphoreProperties));
     }
 }
 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceExternalFenceProperties(
     VkPhysicalDevice physicalDevice, [[maybe_unused]] const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
     VkExternalFenceProperties* pExternalFenceProperties) {
+    std::lock_guard lg(icd.mutex);
     if (nullptr != pExternalFenceProperties) {
-        auto& phys_dev = icd.GetPhysDevice(physicalDevice);
+        auto& phys_dev = GetPhysDevice(physicalDevice);
         memcpy(pExternalFenceProperties, &phys_dev.external_fence_properties, sizeof(VkExternalFenceProperties));
     }
 }
@@ -1236,6 +1432,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL test_vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
                                                                           uint32_t* pPhysicalDeviceCount,
                                                                           VkPhysicalDevice* pPhysicalDevices) {
+    std::lock_guard lg(icd.mutex);
     if (icd.enum_adapter_physical_devices_return_code != VK_SUCCESS) {
         return icd.enum_adapter_physical_devices_return_code;
     }
@@ -1254,6 +1451,7 @@
 #endif  // defined(WIN32)
 
 VKAPI_ATTR VkResult VKAPI_CALL test_vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
+    std::lock_guard lg(icd.mutex);
     if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called &&
         icd.called_negotiate_interface == CalledNegotiateInterface::not_called)
         icd.called_negotiate_interface = CalledNegotiateInterface::vk_icd_negotiate;
@@ -1310,6 +1508,12 @@
         if (string_eq(pName, "vkGetPhysicalDeviceSurfacePresentModesKHR"))
             return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfacePresentModesKHR);
     }
+#if defined(WIN32)
+    if (IsPhysicalDeviceExtensionAvailable("VK_EXT_full_screen_exclusive")) {
+        if (string_eq(pName, "vkGetPhysicalDeviceSurfacePresentModes2EXT"))
+            return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfacePresentModes2EXT);
+    }
+#endif
     if (IsInstanceExtensionEnabled("VK_KHR_get_surface_capabilities2")) {
         if (string_eq(pName, "vkGetPhysicalDeviceSurfaceCapabilities2KHR"))
             return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceCapabilities2KHR);
@@ -1447,6 +1651,7 @@
     return nullptr;
 }
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_physical_device_func([[maybe_unused]] VkInstance instance, const char* pName) {
+    std::lock_guard lg(icd.mutex);
     if (string_eq(pName, "vkEnumerateDeviceLayerProperties")) return to_vkVoidFunction(test_vkEnumerateDeviceLayerProperties);
     if (string_eq(pName, "vkEnumerateDeviceExtensionProperties"))
         return to_vkVoidFunction(test_vkEnumerateDeviceExtensionProperties);
@@ -1554,7 +1759,7 @@
             return to_vkVoidFunction(test_vkGetPhysicalDeviceToolPropertiesEXT);
     }
 
-    for (auto& phys_dev : icd.physical_devices) {
+    for (auto const& [phys_dev_handle, phys_dev] : icd.physical_devices) {
         for (auto& func : phys_dev.custom_physical_device_functions) {
             if (func.name == pName) {
                 return to_vkVoidFunction(func.function);
@@ -1590,9 +1795,9 @@
     return nullptr;
 }
 
-bool should_check(std::vector<const char*> const& exts, VkDevice device, const char* ext_name) {
-    if (device == NULL) return true;  // always look if device is NULL
-    for (auto const& ext : exts) {
+bool should_check(std::vector<const char*>* exts, VkDevice device, const char* ext_name) {
+    if (exts == nullptr || device == VK_NULL_HANDLE) return true;  // always look if device is NULL
+    for (auto const& ext : *exts) {
         if (string_eq(ext, ext_name)) {
             return true;
         }
@@ -1601,19 +1806,22 @@
 }
 
 PFN_vkVoidFunction get_device_func(VkDevice device, const char* pName) {
-    TestICD::FindDevice fd{};
-    DeviceCreateInfo create_info{};
+    std::vector<const char*>* enabled_extensions = nullptr;
+    FindDevice found_device{};
+    std::lock_guard lg(icd.mutex);
     if (device != nullptr) {
-        fd = icd.lookup_device(device);
-        if (!fd.found) return NULL;
-        create_info = icd.physical_devices.at(fd.phys_dev_index).device_create_infos.at(fd.dev_index);
+        found_device = lookup_device(device);
+        if (!found_device.found) return NULL;
+        enabled_extensions =
+            &icd.physical_devices.at(found_device.phys_dev).device_create_infos.at(found_device.dev_index).enabled_extensions;
     }
+
     if (string_eq(pName, "vkCreateCommandPool")) return to_vkVoidFunction(test_vkCreateCommandPool);
     if (string_eq(pName, "vkAllocateCommandBuffers")) return to_vkVoidFunction(test_vkAllocateCommandBuffers);
     if (string_eq(pName, "vkDestroyCommandPool")) return to_vkVoidFunction(test_vkDestroyCommandPool);
     if (string_eq(pName, "vkGetDeviceQueue")) return to_vkVoidFunction(test_vkGetDeviceQueue);
     if (string_eq(pName, "vkDestroyDevice")) return to_vkVoidFunction(test_vkDestroyDevice);
-    if (should_check(create_info.enabled_extensions, device, "VK_KHR_swapchain")) {
+    if (should_check(enabled_extensions, device, "VK_KHR_swapchain")) {
         if (string_eq(pName, "vkCreateSwapchainKHR")) return to_vkVoidFunction(test_vkCreateSwapchainKHR);
         if (string_eq(pName, "vkGetSwapchainImagesKHR")) return to_vkVoidFunction(test_vkGetSwapchainImagesKHR);
         if (string_eq(pName, "vkDestroySwapchainKHR")) return to_vkVoidFunction(test_vkDestroySwapchainKHR);
@@ -1621,14 +1829,14 @@
         if (icd.icd_api_version >= VK_API_VERSION_1_1 && string_eq(pName, "vkGetDeviceGroupSurfacePresentModesKHR"))
             return to_vkVoidFunction(test_vkGetDeviceGroupSurfacePresentModesKHR);
     }
-    if (should_check(create_info.enabled_extensions, device, "VK_KHR_display_swapchain")) {
+    if (should_check(enabled_extensions, device, "VK_KHR_display_swapchain")) {
         if (string_eq(pName, "vkCreateSharedSwapchainsKHR")) return to_vkVoidFunction(test_vkCreateSharedSwapchainsKHR);
     }
-    if (should_check(create_info.enabled_extensions, device, "VK_KHR_device_group")) {
+    if (should_check(enabled_extensions, device, "VK_KHR_device_group")) {
         if (string_eq(pName, "vkGetDeviceGroupSurfacePresentModesKHR"))
             return to_vkVoidFunction(test_vkGetDeviceGroupSurfacePresentModesKHR);
     }
-    if (should_check(create_info.enabled_extensions, device, "VK_EXT_debug_marker")) {
+    if (should_check(enabled_extensions, device, "VK_EXT_debug_marker")) {
         if (string_eq(pName, "vkDebugMarkerSetObjectTagEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectTagEXT);
         if (string_eq(pName, "vkDebugMarkerSetObjectNameEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectNameEXT);
         if (string_eq(pName, "vkCmdDebugMarkerBeginEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerBeginEXT);
@@ -1645,22 +1853,32 @@
         if (string_eq(pName, "vkCmdEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdEndDebugUtilsLabelEXT);
         if (string_eq(pName, "vkCmdInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdInsertDebugUtilsLabelEXT);
     }
-    // look for device functions setup from a test
-    for (const auto& phys_dev : icd.physical_devices) {
-        for (const auto& function : phys_dev.known_device_functions) {
+    if (found_device.found) {
+        // look for device functions setup from a test
+        for (const auto& function : icd.physical_devices.at(found_device.phys_dev).known_device_functions) {
             if (function.name == pName) {
                 return to_vkVoidFunction(function.function);
             }
         }
+    } else {
+        for (const auto& [handle, phys_dev] : icd.physical_devices) {
+            for (const auto& function : phys_dev.known_device_functions) {
+                if (function.name == pName) {
+                    return to_vkVoidFunction(function.function);
+                }
+            }
+        }
     }
     return nullptr;
 }
 
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
+    std::lock_guard lg(icd.mutex);
     return get_instance_func(instance, pName);
 }
 
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_vkGetDeviceProcAddr(VkDevice device, const char* pName) {
+    std::lock_guard lg(icd.mutex);
     return get_device_func(device, pName);
 }
 
@@ -1706,33 +1924,39 @@
 extern "C" {
 #if TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION && TEST_ICD_EXPORT_VERSION_7
 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
+    std::lock_guard lg(icd.mutex);
     return test_vk_icdNegotiateLoaderICDInterfaceVersion(pSupportedVersion);
 }
 #endif  // TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION
 
 #if TEST_ICD_EXPORT_ICD_GPDPA && TEST_ICD_EXPORT_VERSION_7
 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName) {
+    std::lock_guard lg(icd.mutex);
     return get_physical_device_func(instance, pName);
 }
 #endif  // TEST_ICD_EXPORT_ICD_GPDPA
 
 #if TEST_ICD_EXPORT_ICD_GIPA
 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName) {
+    std::lock_guard lg(icd.mutex);
     if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called) icd.called_vk_icd_gipa = CalledICDGIPA::vk_icd_gipa;
     return base_get_instance_proc_addr(instance, pName);
 }
 #else   // !TEST_ICD_EXPORT_ICD_GIPA
 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
+    std::lock_guard lg(icd.mutex);
     if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called) icd.called_vk_icd_gipa = CalledICDGIPA::vk_gipa;
     return base_get_instance_proc_addr(instance, pName);
 }
 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
                                                                  const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
+    std::lock_guard lg(icd.mutex);
     return test_vkCreateInstance(pCreateInfo, pAllocator, pInstance);
 }
 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char* pLayerName,
                                                                                        uint32_t* pPropertyCount,
                                                                                        VkExtensionProperties* pProperties) {
+    std::lock_guard lg(icd.mutex);
     return test_vkEnumerateInstanceExtensionProperties(pLayerName, pPropertyCount, pProperties);
 }
 #endif  // TEST_ICD_EXPORT_ICD_GIPA
diff --git a/tests/framework/icd/test_icd.h b/tests/framework/icd/test_icd.h
index 2583189..f11ae18 100644
--- a/tests/framework/icd/test_icd.h
+++ b/tests/framework/icd/test_icd.h
@@ -27,7 +27,15 @@
 
 #pragma once
 
-#include "test_util.h"
+#include <array>
+#include <filesystem>
+#include <mutex>
+#include <ostream>
+#include <unordered_map>
+
+#include "util/dispatchable_handle.h"
+#include "util/platform_wsi.h"
+#include "util/functions.h"
 
 #include "layer/layer_util.h"
 
@@ -70,6 +78,9 @@
     }
     return os << static_cast<uint32_t>(result);
 }
+
+using VulkanUUID = std::array<uint8_t, VK_UUID_SIZE>;
+
 // clang-format on
 
 // Move only type because it holds a DispatchableHandle<VkPhysicalDevice>
@@ -79,39 +90,42 @@
     PhysicalDevice(const char* name) : deviceName(name) {}
 
     DispatchableHandle<VkPhysicalDevice> vk_physical_device;
-    BUILDER_VALUE(PhysicalDevice, std::string, deviceName, "")
-    BUILDER_VALUE(PhysicalDevice, VkPhysicalDeviceProperties, properties, {})
-    BUILDER_VALUE(PhysicalDevice, VkPhysicalDeviceFeatures, features, {})
-    BUILDER_VALUE(PhysicalDevice, VkPhysicalDeviceMemoryProperties, memory_properties, {})
-    BUILDER_VALUE(PhysicalDevice, VkImageFormatProperties, image_format_properties, {})
-    BUILDER_VALUE(PhysicalDevice, VkExternalMemoryProperties, external_memory_properties, {})
-    BUILDER_VALUE(PhysicalDevice, VkExternalSemaphoreProperties, external_semaphore_properties, {})
-    BUILDER_VALUE(PhysicalDevice, VkExternalFenceProperties, external_fence_properties, {})
-    BUILDER_VALUE(PhysicalDevice, uint32_t, pci_bus, {})
+    BUILDER_VALUE(std::string, deviceName)
+    BUILDER_VALUE(VulkanUUID, deviceUUID)
+    BUILDER_VALUE(VulkanUUID, driverUUID)
+    BUILDER_VALUE(VkPhysicalDeviceProperties, properties)
+    BUILDER_VALUE(VkPhysicalDeviceFeatures, features)
+    BUILDER_VALUE(VkPhysicalDeviceMemoryProperties, memory_properties)
+    BUILDER_VALUE(VkPhysicalDeviceDriverProperties, driver_properties)
+    BUILDER_VALUE(VkImageFormatProperties, image_format_properties)
+    BUILDER_VALUE(VkExternalMemoryProperties, external_memory_properties)
+    BUILDER_VALUE(VkExternalSemaphoreProperties, external_semaphore_properties)
+    BUILDER_VALUE(VkExternalFenceProperties, external_fence_properties)
+    BUILDER_VALUE(uint32_t, pci_bus)
 
-    BUILDER_VECTOR(PhysicalDevice, MockQueueFamilyProperties, queue_family_properties, queue_family_properties)
-    BUILDER_VECTOR(PhysicalDevice, VkFormatProperties, format_properties, format_properties)
-    BUILDER_VECTOR(PhysicalDevice, VkSparseImageFormatProperties, sparse_image_format_properties, sparse_image_format_properties)
+    BUILDER_VECTOR(MockQueueFamilyProperties, queue_family_properties, queue_family_properties)
+    BUILDER_VECTOR(VkFormatProperties, format_properties, format_properties)
+    BUILDER_VECTOR(VkSparseImageFormatProperties, sparse_image_format_properties, sparse_image_format_properties)
 
-    BUILDER_VECTOR(PhysicalDevice, Extension, extensions, extension)
+    BUILDER_VECTOR(Extension, extensions, extension)
 
-    BUILDER_VALUE(PhysicalDevice, VkSurfaceCapabilitiesKHR, surface_capabilities, {})
-    BUILDER_VECTOR(PhysicalDevice, VkSurfaceFormatKHR, surface_formats, surface_format)
-    BUILDER_VECTOR(PhysicalDevice, VkPresentModeKHR, surface_present_modes, surface_present_mode)
-    BUILDER_VALUE(PhysicalDevice, VkSurfacePresentScalingCapabilitiesEXT, surface_present_scaling_capabilities, {})
+    BUILDER_VALUE(VkSurfaceCapabilitiesKHR, surface_capabilities)
+    BUILDER_VECTOR(VkSurfaceFormatKHR, surface_formats, surface_format)
+    BUILDER_VECTOR(VkPresentModeKHR, surface_present_modes, surface_present_mode)
+    BUILDER_VALUE(VkSurfacePresentScalingCapabilitiesEXT, surface_present_scaling_capabilities)
     // No good way to make this a builder value. Each std::vector<VkPresentModeKHR> corresponds to each surface_present_modes
     // element
     std::vector<std::vector<VkPresentModeKHR>> surface_present_mode_compatibility{};
 
-    BUILDER_VECTOR(PhysicalDevice, VkDisplayPropertiesKHR, display_properties, display_properties)
-    BUILDER_VECTOR(PhysicalDevice, VkDisplayPlanePropertiesKHR, display_plane_properties, display_plane_properties)
-    BUILDER_VECTOR(PhysicalDevice, VkDisplayKHR, displays, displays)
-    BUILDER_VECTOR(PhysicalDevice, VkDisplayModePropertiesKHR, display_mode_properties, display_mode_properties)
-    BUILDER_VALUE(PhysicalDevice, VkDisplayModeKHR, display_mode, {})
-    BUILDER_VALUE(PhysicalDevice, VkDisplayPlaneCapabilitiesKHR, display_plane_capabilities, {})
+    BUILDER_VECTOR(VkDisplayPropertiesKHR, display_properties, display_properties)
+    BUILDER_VECTOR(VkDisplayPlanePropertiesKHR, display_plane_properties, display_plane_properties)
+    BUILDER_VECTOR(VkDisplayKHR, displays, displays)
+    BUILDER_VECTOR(VkDisplayModePropertiesKHR, display_mode_properties, display_mode_properties)
+    BUILDER_VALUE(VkDisplayModeKHR, display_mode)
+    BUILDER_VALUE(VkDisplayPlaneCapabilitiesKHR, display_plane_capabilities)
 
-    BUILDER_VALUE(PhysicalDevice, VkLayeredDriverUnderlyingApiMSFT, layered_driver_underlying_api,
-                  VK_LAYERED_DRIVER_UNDERLYING_API_NONE_MSFT)
+    BUILDER_VALUE_WITH_DEFAULT(VkLayeredDriverUnderlyingApiMSFT, layered_driver_underlying_api,
+                               VK_LAYERED_DRIVER_UNDERLYING_API_NONE_MSFT)
 
     PhysicalDevice& set_api_version(uint32_t version) {
         properties.apiVersion = version;
@@ -120,6 +134,9 @@
 
     PhysicalDevice&& finish() { return std::move(*this); }
 
+    // Defines the order this physical device appears in vkEnumeratePhysicalDevices
+    uint32_t iteration_order = 0;
+
     // Objects created from this physical device
     std::vector<VkDevice> device_handles;
     std::vector<DeviceCreateInfo> device_create_infos;
@@ -128,20 +145,25 @@
     // Unknown physical device functions. Add a `VulkanFunction` to this list which will be searched in
     // vkGetInstanceProcAddr for custom_instance_functions and vk_icdGetPhysicalDeviceProcAddr for custom_physical_device_functions.
     // To add unknown device functions, add it to the PhysicalDevice directly (in the known_device_functions member)
-    BUILDER_VECTOR(PhysicalDevice, VulkanFunction, custom_physical_device_functions, custom_physical_device_function)
+    BUILDER_VECTOR(VulkanFunction, custom_physical_device_functions, custom_physical_device_function)
 
     // List of function names which are 'known' to the physical device but have test defined implementations
     // The purpose of this list is so that vkGetDeviceProcAddr returns 'a real function pointer' in tests
     // without actually implementing any of the logic inside of it.
-    BUILDER_VECTOR(PhysicalDevice, VulkanFunction, known_device_functions, device_function)
+    BUILDER_VECTOR(VulkanFunction, known_device_functions, device_function)
 };
 
 struct PhysicalDeviceGroup {
     PhysicalDeviceGroup() {}
     PhysicalDeviceGroup(PhysicalDevice const& physical_device) { physical_device_handles.push_back(&physical_device); }
+    PhysicalDeviceGroup(PhysicalDevice const* physical_device) { physical_device_handles.push_back(physical_device); }
     PhysicalDeviceGroup(std::vector<PhysicalDevice*> const& physical_devices) {
         physical_device_handles.insert(physical_device_handles.end(), physical_devices.begin(), physical_devices.end());
     }
+    PhysicalDeviceGroup& use_physical_device(PhysicalDevice const* physical_device) {
+        physical_device_handles.push_back(physical_device);
+        return *this;
+    }
     PhysicalDeviceGroup& use_physical_device(PhysicalDevice const& physical_device) {
         physical_device_handles.push_back(&physical_device);
         return *this;
@@ -152,27 +174,28 @@
 };
 
 struct TestICD {
+    std::recursive_mutex mutex;
     std::filesystem::path manifest_file_path;
 
-    BUILDER_VALUE(TestICD, bool, exposes_vk_icdNegotiateLoaderICDInterfaceVersion, true)
-    BUILDER_VALUE(TestICD, bool, exposes_vkEnumerateInstanceExtensionProperties, true)
-    BUILDER_VALUE(TestICD, bool, exposes_vkCreateInstance, true)
-    BUILDER_VALUE(TestICD, bool, exposes_vk_icdGetPhysicalDeviceProcAddr, true)
+    BUILDER_VALUE_WITH_DEFAULT(bool, exposes_vk_icdNegotiateLoaderICDInterfaceVersion, true)
+    BUILDER_VALUE_WITH_DEFAULT(bool, exposes_vkEnumerateInstanceExtensionProperties, true)
+    BUILDER_VALUE_WITH_DEFAULT(bool, exposes_vkCreateInstance, true)
+    BUILDER_VALUE_WITH_DEFAULT(bool, exposes_vk_icdGetPhysicalDeviceProcAddr, true)
 #if defined(WIN32)
-    BUILDER_VALUE(TestICD, bool, exposes_vk_icdEnumerateAdapterPhysicalDevices, true)
+    BUILDER_VALUE_WITH_DEFAULT(bool, exposes_vk_icdEnumerateAdapterPhysicalDevices, true)
 #endif
 
     CalledICDGIPA called_vk_icd_gipa = CalledICDGIPA::not_called;
     CalledNegotiateInterface called_negotiate_interface = CalledNegotiateInterface::not_called;
 
     InterfaceVersionCheck interface_version_check = InterfaceVersionCheck::not_called;
-    BUILDER_VALUE(TestICD, uint32_t, min_icd_interface_version, 0)
-    BUILDER_VALUE(TestICD, uint32_t, max_icd_interface_version, 7)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, min_icd_interface_version, 0)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, max_icd_interface_version, 7)
     uint32_t icd_interface_version_received = 0;
 
     bool called_enumerate_adapter_physical_devices = false;
 
-    BUILDER_VALUE(TestICD, bool, enable_icd_wsi, false);
+    BUILDER_VALUE(bool, enable_icd_wsi);
     bool is_using_icd_wsi = false;
 
     TestICD& setup_WSI(const char* api_selection = nullptr) {
@@ -182,14 +205,38 @@
         return *this;
     }
 
-    BUILDER_VALUE(TestICD, uint32_t, icd_api_version, VK_API_VERSION_1_0)
-    BUILDER_VECTOR(TestICD, LayerDefinition, instance_layers, instance_layer)
-    BUILDER_VECTOR(TestICD, Extension, instance_extensions, instance_extension)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, icd_api_version, VK_API_VERSION_1_0)
+    BUILDER_VECTOR(LayerDefinition, instance_layers, instance_layer)
+    BUILDER_VECTOR(Extension, instance_extensions, instance_extension)
     std::vector<Extension> enabled_instance_extensions;
 
-    BUILDER_VECTOR_MOVE_ONLY(TestICD, PhysicalDevice, physical_devices, physical_device);
+    std::unordered_map<VkPhysicalDevice, PhysicalDevice> physical_devices;
+    TestICD& add_physical_device(PhysicalDevice&& physical_device) {
+        physical_device.iteration_order = physical_devices.size();
+        physical_devices.emplace(physical_device.vk_physical_device.handle, std::move(physical_device));
+        return *this;
+    }
 
-    BUILDER_VECTOR(TestICD, PhysicalDeviceGroup, physical_device_groups, physical_device_group);
+    PhysicalDevice& add_and_get_physical_device(PhysicalDevice&& physical_device) {
+        VkPhysicalDevice pd = physical_device.vk_physical_device.handle;
+        physical_device.iteration_order = physical_devices.size();
+        physical_devices.emplace(physical_device.vk_physical_device.handle, std::move(physical_device));
+        return physical_devices.at(pd);
+    }
+
+    PhysicalDevice& add_physical_device_at_index(size_t index, PhysicalDevice&& physical_device) {
+        VkPhysicalDevice pd = physical_device.vk_physical_device.handle;
+        physical_device.iteration_order = index;
+        for (auto& [handle, phys_dev] : physical_devices) {
+            if (phys_dev.iteration_order >= index) {
+                phys_dev.iteration_order++;
+            }
+        }
+        physical_devices.emplace(physical_device.vk_physical_device.handle, std::move(physical_device));
+        return physical_devices.at(pd);
+    }
+
+    BUILDER_VECTOR(PhysicalDeviceGroup, physical_device_groups, physical_device_group);
 
     DispatchableHandle<VkInstance> instance_handle;
     std::vector<DispatchableHandle<VkDevice>> device_handles;
@@ -198,35 +245,27 @@
     std::vector<uint64_t> callback_handles;
     std::vector<uint64_t> swapchain_handles;
 
-    BUILDER_VALUE(TestICD, bool, can_query_vkEnumerateInstanceVersion, true);
-    BUILDER_VALUE(TestICD, bool, can_query_GetPhysicalDeviceFuncs, true);
+    BUILDER_VALUE_WITH_DEFAULT(bool, can_query_vkEnumerateInstanceVersion, true);
+    BUILDER_VALUE_WITH_DEFAULT(bool, can_query_GetPhysicalDeviceFuncs, true);
 
     // Unknown instance functions Add a `VulkanFunction` to this list which will be searched in
     // vkGetInstanceProcAddr for custom_instance_functions and vk_icdGetPhysicalDeviceProcAddr for
     // custom_physical_device_functions. To add unknown device functions, add it to the PhysicalDevice directly (in the
     // known_device_functions member)
-    BUILDER_VECTOR(TestICD, VulkanFunction, custom_instance_functions, custom_instance_function)
+    BUILDER_VECTOR(VulkanFunction, custom_instance_functions, custom_instance_function)
 
     // Must explicitely state support for the tooling info extension, that way we can control if vkGetInstanceProcAddr returns a
     // function pointer for vkGetPhysicalDeviceToolPropertiesEXT or vkGetPhysicalDeviceToolProperties (core version)
-    BUILDER_VALUE(TestICD, bool, supports_tooling_info_ext, false);
-    BUILDER_VALUE(TestICD, bool, supports_tooling_info_core, false);
+    BUILDER_VALUE(bool, supports_tooling_info_ext);
+    BUILDER_VALUE(bool, supports_tooling_info_core);
     // List of tooling properties that this driver 'supports'
-    BUILDER_VECTOR(TestICD, VkPhysicalDeviceToolPropertiesEXT, tooling_properties, tooling_property)
+    BUILDER_VECTOR(VkPhysicalDeviceToolPropertiesEXT, tooling_properties, tooling_property)
     std::vector<DispatchableHandle<VkCommandBuffer>> allocated_command_buffers;
 
     VkInstanceCreateFlags passed_in_instance_create_flags{};
 
-    BUILDER_VALUE(TestICD, VkResult, enum_physical_devices_return_code, VK_SUCCESS);
-    BUILDER_VALUE(TestICD, VkResult, enum_adapter_physical_devices_return_code, VK_SUCCESS);
-
-    PhysicalDevice& GetPhysDevice(VkPhysicalDevice physicalDevice) {
-        for (auto& phys_dev : physical_devices) {
-            if (phys_dev.vk_physical_device.handle == physicalDevice) return phys_dev;
-        }
-        assert(false && "vkPhysicalDevice not found!");
-        return physical_devices[0];
-    }
+    BUILDER_VALUE_WITH_DEFAULT(VkResult, enum_physical_devices_return_code, VK_SUCCESS);
+    BUILDER_VALUE_WITH_DEFAULT(VkResult, enum_adapter_physical_devices_return_code, VK_SUCCESS);
 
     InstanceCreateInfo GetVkInstanceCreateInfo() {
         InstanceCreateInfo info;
@@ -235,30 +274,12 @@
         return info;
     }
 
-    struct FindDevice {
-        bool found = false;
-        uint32_t phys_dev_index = 0;
-        uint32_t dev_index = 0;
-    };
-
-    FindDevice lookup_device(VkDevice device) {
-        FindDevice fd{};
-        for (uint32_t p = 0; p < physical_devices.size(); p++) {
-            auto const& phys_dev = physical_devices.at(p);
-            for (uint32_t d = 0; d < phys_dev.device_handles.size(); d++) {
-                if (phys_dev.device_handles.at(d) == device) {
-                    fd.found = true;
-                    fd.phys_dev_index = p;
-                    fd.dev_index = d;
-                    return fd;
-                }
-            }
-        }
-        return fd;
-    }
+    // Speedup looking for physical devices by not having to iterate through the entire physical_device map to find a particular
+    // physical device
+    std::unordered_map<VkDevice, VkPhysicalDevice> device_to_physical_device_map;
 
 #if defined(WIN32)
-    BUILDER_VALUE(TestICD, LUID, adapterLUID, {})
+    BUILDER_VALUE(LUID, adapterLUID)
 #endif  // defined(WIN32)
 };
 
diff --git a/tests/framework/json_writer.h b/tests/framework/json_writer.h
deleted file mode 100644
index f22db28..0000000
--- a/tests/framework/json_writer.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2023 The Khronos Group Inc.
- * Copyright (c) 2023 Valve Corporation
- * Copyright (c) 2023 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and/or associated documentation files (the "Materials"), to
- * deal in the Materials without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Materials, and to permit persons to whom the Materials are
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice(s) and this permission notice shall be included in
- * all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- *
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
- * USE OR OTHER DEALINGS IN THE MATERIALS.
- *
- * Author: Charles Giessen <charles@lunarg.com>
- */
-
-#pragma once
-
-#include <cstdint>
-#include <stack>
-#include <string>
-
-// Utility class to simplify the writing of JSON manifest files
-
-struct JsonWriter {
-    std::string output;
-
-    // the bool represents whether an object has been written & a comma is needed
-    std::stack<bool> stack;
-
-    void StartObject() {
-        CommaAndNewLine();
-        Indent();
-        output += "{";
-        stack.push(false);
-    }
-    void StartKeyedObject(std::string const& key) {
-        CommaAndNewLine();
-        Indent();
-        output += "\"" + key + "\": {";
-        stack.push(false);
-    }
-    void EndObject() {
-        stack.pop();
-        output += "\n";
-        Indent();
-        output += "}";
-    }
-    void StartKeyedArray(std::string const& key) {
-        CommaAndNewLine();
-        Indent();
-        output += "\"" + key + "\": [";
-        stack.push(false);
-    }
-    void StartArray() {
-        CommaAndNewLine();
-        Indent();
-        output += "[";
-        stack.push(false);
-    }
-    void EndArray() {
-        stack.pop();
-        output += "\n";
-        Indent();
-        output += "]";
-    }
-
-    void AddKeyedString(std::string const& key, std::string const& value) {
-        CommaAndNewLine();
-        Indent();
-        output += "\"" + key + "\": \"" + escape(value) + "\"";
-    }
-    void AddString(std::string const& value) {
-        CommaAndNewLine();
-        Indent();
-        output += "\"" + escape(value) + "\"";
-    }
-#if defined(WIN32)
-    void AddKeyedString(std::string const& key, std::wstring const& value) {
-        CommaAndNewLine();
-        Indent();
-        output += "\"" + key + "\": \"" + escape(narrow(value)) + "\"";
-    }
-    void AddString(std::wstring const& value) {
-        CommaAndNewLine();
-        Indent();
-        output += "\"" + escape(narrow(value)) + "\"";
-    }
-#endif
-
-    void AddKeyedBool(std::string const& key, bool value) {
-        CommaAndNewLine();
-        Indent();
-        output += "\"" + key + "\": " + (value ? "true" : "false");
-    }
-    void AddBool(bool value) {
-        CommaAndNewLine();
-        Indent();
-        output += std::string(value ? "true" : "false");
-    }
-
-    // Json doesn't allow `\` in strings, it must be escaped. Thus we have to convert '\\' to '\\\\' in strings
-    static std::string escape(std::string const& in_path) {
-        std::string out;
-        for (auto& c : in_path) {
-            if (c == '\\')
-                out += "\\\\";
-            else
-                out += c;
-        }
-        return out;
-    }
-    static std::string escape(std::filesystem::path const& in_path) { return escape(narrow(in_path.native())); }
-
-   private:
-    void CommaAndNewLine() {
-        if (stack.size() > 0) {
-            if (stack.top() == false) {
-                stack.top() = true;
-            } else {
-                output += ",";
-            }
-            output += "\n";
-        }
-    }
-    void Indent() {
-        for (uint32_t i = 0; i < stack.size(); i++) {
-            output += '\t';
-        }
-    }
-};
diff --git a/tests/framework/layer/generated/vk_dispatch_table_helper.h b/tests/framework/layer/generated/vk_dispatch_table_helper.h
new file mode 100644
index 0000000..e48aca3
--- /dev/null
+++ b/tests/framework/layer/generated/vk_dispatch_table_helper.h
@@ -0,0 +1,1004 @@
+#pragma once
+// *** THIS FILE IS GENERATED - DO NOT EDIT ***
+// See dispatch_table_helper_generator.py for modifications
+
+/*
+ * Copyright (c) 2015-2025 The Khronos Group Inc.
+ * Copyright (c) 2015-2025 Valve Corporation
+ * Copyright (c) 2015-2025 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
+ * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Charles Giessen <charles@lunarg.com>
+ */
+
+#include <vulkan/vulkan.h>
+#include <vulkan/vk_layer.h>
+#include <string.h>
+#include "loader/generated/vk_layer_dispatch_table.h"
+
+// clang-format off
+static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDispatchTable *table, PFN_vkGetDeviceProcAddr gpa) {
+    memset(table, 0, sizeof(*table));
+    table->magic = DEVICE_DISP_TABLE_MAGIC_NUMBER;
+
+    // Device function pointers
+    table->GetDeviceProcAddr = gpa;
+    table->DestroyDevice = (PFN_vkDestroyDevice)gpa(device, "vkDestroyDevice");
+    table->GetDeviceQueue = (PFN_vkGetDeviceQueue)gpa(device, "vkGetDeviceQueue");
+    table->QueueSubmit = (PFN_vkQueueSubmit)gpa(device, "vkQueueSubmit");
+    table->QueueWaitIdle = (PFN_vkQueueWaitIdle)gpa(device, "vkQueueWaitIdle");
+    table->DeviceWaitIdle = (PFN_vkDeviceWaitIdle)gpa(device, "vkDeviceWaitIdle");
+    table->AllocateMemory = (PFN_vkAllocateMemory)gpa(device, "vkAllocateMemory");
+    table->FreeMemory = (PFN_vkFreeMemory)gpa(device, "vkFreeMemory");
+    table->MapMemory = (PFN_vkMapMemory)gpa(device, "vkMapMemory");
+    table->UnmapMemory = (PFN_vkUnmapMemory)gpa(device, "vkUnmapMemory");
+    table->FlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges)gpa(device, "vkFlushMappedMemoryRanges");
+    table->InvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges)gpa(device, "vkInvalidateMappedMemoryRanges");
+    table->GetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment)gpa(device, "vkGetDeviceMemoryCommitment");
+    table->BindBufferMemory = (PFN_vkBindBufferMemory)gpa(device, "vkBindBufferMemory");
+    table->BindImageMemory = (PFN_vkBindImageMemory)gpa(device, "vkBindImageMemory");
+    table->GetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements)gpa(device, "vkGetBufferMemoryRequirements");
+    table->GetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements)gpa(device, "vkGetImageMemoryRequirements");
+    table->GetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements)gpa(device, "vkGetImageSparseMemoryRequirements");
+    table->QueueBindSparse = (PFN_vkQueueBindSparse)gpa(device, "vkQueueBindSparse");
+    table->CreateFence = (PFN_vkCreateFence)gpa(device, "vkCreateFence");
+    table->DestroyFence = (PFN_vkDestroyFence)gpa(device, "vkDestroyFence");
+    table->ResetFences = (PFN_vkResetFences)gpa(device, "vkResetFences");
+    table->GetFenceStatus = (PFN_vkGetFenceStatus)gpa(device, "vkGetFenceStatus");
+    table->WaitForFences = (PFN_vkWaitForFences)gpa(device, "vkWaitForFences");
+    table->CreateSemaphore = (PFN_vkCreateSemaphore)gpa(device, "vkCreateSemaphore");
+    table->DestroySemaphore = (PFN_vkDestroySemaphore)gpa(device, "vkDestroySemaphore");
+    table->CreateQueryPool = (PFN_vkCreateQueryPool)gpa(device, "vkCreateQueryPool");
+    table->DestroyQueryPool = (PFN_vkDestroyQueryPool)gpa(device, "vkDestroyQueryPool");
+    table->GetQueryPoolResults = (PFN_vkGetQueryPoolResults)gpa(device, "vkGetQueryPoolResults");
+    table->CreateBuffer = (PFN_vkCreateBuffer)gpa(device, "vkCreateBuffer");
+    table->DestroyBuffer = (PFN_vkDestroyBuffer)gpa(device, "vkDestroyBuffer");
+    table->CreateImage = (PFN_vkCreateImage)gpa(device, "vkCreateImage");
+    table->DestroyImage = (PFN_vkDestroyImage)gpa(device, "vkDestroyImage");
+    table->GetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout)gpa(device, "vkGetImageSubresourceLayout");
+    table->CreateImageView = (PFN_vkCreateImageView)gpa(device, "vkCreateImageView");
+    table->DestroyImageView = (PFN_vkDestroyImageView)gpa(device, "vkDestroyImageView");
+    table->CreateCommandPool = (PFN_vkCreateCommandPool)gpa(device, "vkCreateCommandPool");
+    table->DestroyCommandPool = (PFN_vkDestroyCommandPool)gpa(device, "vkDestroyCommandPool");
+    table->ResetCommandPool = (PFN_vkResetCommandPool)gpa(device, "vkResetCommandPool");
+    table->AllocateCommandBuffers = (PFN_vkAllocateCommandBuffers)gpa(device, "vkAllocateCommandBuffers");
+    table->FreeCommandBuffers = (PFN_vkFreeCommandBuffers)gpa(device, "vkFreeCommandBuffers");
+    table->BeginCommandBuffer = (PFN_vkBeginCommandBuffer)gpa(device, "vkBeginCommandBuffer");
+    table->EndCommandBuffer = (PFN_vkEndCommandBuffer)gpa(device, "vkEndCommandBuffer");
+    table->ResetCommandBuffer = (PFN_vkResetCommandBuffer)gpa(device, "vkResetCommandBuffer");
+    table->CmdCopyBuffer = (PFN_vkCmdCopyBuffer)gpa(device, "vkCmdCopyBuffer");
+    table->CmdCopyImage = (PFN_vkCmdCopyImage)gpa(device, "vkCmdCopyImage");
+    table->CmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage)gpa(device, "vkCmdCopyBufferToImage");
+    table->CmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer)gpa(device, "vkCmdCopyImageToBuffer");
+    table->CmdUpdateBuffer = (PFN_vkCmdUpdateBuffer)gpa(device, "vkCmdUpdateBuffer");
+    table->CmdFillBuffer = (PFN_vkCmdFillBuffer)gpa(device, "vkCmdFillBuffer");
+    table->CmdPipelineBarrier = (PFN_vkCmdPipelineBarrier)gpa(device, "vkCmdPipelineBarrier");
+    table->CmdBeginQuery = (PFN_vkCmdBeginQuery)gpa(device, "vkCmdBeginQuery");
+    table->CmdEndQuery = (PFN_vkCmdEndQuery)gpa(device, "vkCmdEndQuery");
+    table->CmdResetQueryPool = (PFN_vkCmdResetQueryPool)gpa(device, "vkCmdResetQueryPool");
+    table->CmdWriteTimestamp = (PFN_vkCmdWriteTimestamp)gpa(device, "vkCmdWriteTimestamp");
+    table->CmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults)gpa(device, "vkCmdCopyQueryPoolResults");
+    table->CmdExecuteCommands = (PFN_vkCmdExecuteCommands)gpa(device, "vkCmdExecuteCommands");
+    table->CreateEvent = (PFN_vkCreateEvent)gpa(device, "vkCreateEvent");
+    table->DestroyEvent = (PFN_vkDestroyEvent)gpa(device, "vkDestroyEvent");
+    table->GetEventStatus = (PFN_vkGetEventStatus)gpa(device, "vkGetEventStatus");
+    table->SetEvent = (PFN_vkSetEvent)gpa(device, "vkSetEvent");
+    table->ResetEvent = (PFN_vkResetEvent)gpa(device, "vkResetEvent");
+    table->CreateBufferView = (PFN_vkCreateBufferView)gpa(device, "vkCreateBufferView");
+    table->DestroyBufferView = (PFN_vkDestroyBufferView)gpa(device, "vkDestroyBufferView");
+    table->CreateShaderModule = (PFN_vkCreateShaderModule)gpa(device, "vkCreateShaderModule");
+    table->DestroyShaderModule = (PFN_vkDestroyShaderModule)gpa(device, "vkDestroyShaderModule");
+    table->CreatePipelineCache = (PFN_vkCreatePipelineCache)gpa(device, "vkCreatePipelineCache");
+    table->DestroyPipelineCache = (PFN_vkDestroyPipelineCache)gpa(device, "vkDestroyPipelineCache");
+    table->GetPipelineCacheData = (PFN_vkGetPipelineCacheData)gpa(device, "vkGetPipelineCacheData");
+    table->MergePipelineCaches = (PFN_vkMergePipelineCaches)gpa(device, "vkMergePipelineCaches");
+    table->CreateComputePipelines = (PFN_vkCreateComputePipelines)gpa(device, "vkCreateComputePipelines");
+    table->DestroyPipeline = (PFN_vkDestroyPipeline)gpa(device, "vkDestroyPipeline");
+    table->CreatePipelineLayout = (PFN_vkCreatePipelineLayout)gpa(device, "vkCreatePipelineLayout");
+    table->DestroyPipelineLayout = (PFN_vkDestroyPipelineLayout)gpa(device, "vkDestroyPipelineLayout");
+    table->CreateSampler = (PFN_vkCreateSampler)gpa(device, "vkCreateSampler");
+    table->DestroySampler = (PFN_vkDestroySampler)gpa(device, "vkDestroySampler");
+    table->CreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout)gpa(device, "vkCreateDescriptorSetLayout");
+    table->DestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout)gpa(device, "vkDestroyDescriptorSetLayout");
+    table->CreateDescriptorPool = (PFN_vkCreateDescriptorPool)gpa(device, "vkCreateDescriptorPool");
+    table->DestroyDescriptorPool = (PFN_vkDestroyDescriptorPool)gpa(device, "vkDestroyDescriptorPool");
+    table->ResetDescriptorPool = (PFN_vkResetDescriptorPool)gpa(device, "vkResetDescriptorPool");
+    table->AllocateDescriptorSets = (PFN_vkAllocateDescriptorSets)gpa(device, "vkAllocateDescriptorSets");
+    table->FreeDescriptorSets = (PFN_vkFreeDescriptorSets)gpa(device, "vkFreeDescriptorSets");
+    table->UpdateDescriptorSets = (PFN_vkUpdateDescriptorSets)gpa(device, "vkUpdateDescriptorSets");
+    table->CmdBindPipeline = (PFN_vkCmdBindPipeline)gpa(device, "vkCmdBindPipeline");
+    table->CmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets)gpa(device, "vkCmdBindDescriptorSets");
+    table->CmdClearColorImage = (PFN_vkCmdClearColorImage)gpa(device, "vkCmdClearColorImage");
+    table->CmdDispatch = (PFN_vkCmdDispatch)gpa(device, "vkCmdDispatch");
+    table->CmdDispatchIndirect = (PFN_vkCmdDispatchIndirect)gpa(device, "vkCmdDispatchIndirect");
+    table->CmdSetEvent = (PFN_vkCmdSetEvent)gpa(device, "vkCmdSetEvent");
+    table->CmdResetEvent = (PFN_vkCmdResetEvent)gpa(device, "vkCmdResetEvent");
+    table->CmdWaitEvents = (PFN_vkCmdWaitEvents)gpa(device, "vkCmdWaitEvents");
+    table->CmdPushConstants = (PFN_vkCmdPushConstants)gpa(device, "vkCmdPushConstants");
+    table->CreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines)gpa(device, "vkCreateGraphicsPipelines");
+    table->CreateFramebuffer = (PFN_vkCreateFramebuffer)gpa(device, "vkCreateFramebuffer");
+    table->DestroyFramebuffer = (PFN_vkDestroyFramebuffer)gpa(device, "vkDestroyFramebuffer");
+    table->CreateRenderPass = (PFN_vkCreateRenderPass)gpa(device, "vkCreateRenderPass");
+    table->DestroyRenderPass = (PFN_vkDestroyRenderPass)gpa(device, "vkDestroyRenderPass");
+    table->GetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity)gpa(device, "vkGetRenderAreaGranularity");
+    table->CmdSetViewport = (PFN_vkCmdSetViewport)gpa(device, "vkCmdSetViewport");
+    table->CmdSetScissor = (PFN_vkCmdSetScissor)gpa(device, "vkCmdSetScissor");
+    table->CmdSetLineWidth = (PFN_vkCmdSetLineWidth)gpa(device, "vkCmdSetLineWidth");
+    table->CmdSetDepthBias = (PFN_vkCmdSetDepthBias)gpa(device, "vkCmdSetDepthBias");
+    table->CmdSetBlendConstants = (PFN_vkCmdSetBlendConstants)gpa(device, "vkCmdSetBlendConstants");
+    table->CmdSetDepthBounds = (PFN_vkCmdSetDepthBounds)gpa(device, "vkCmdSetDepthBounds");
+    table->CmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask)gpa(device, "vkCmdSetStencilCompareMask");
+    table->CmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask)gpa(device, "vkCmdSetStencilWriteMask");
+    table->CmdSetStencilReference = (PFN_vkCmdSetStencilReference)gpa(device, "vkCmdSetStencilReference");
+    table->CmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer)gpa(device, "vkCmdBindIndexBuffer");
+    table->CmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers)gpa(device, "vkCmdBindVertexBuffers");
+    table->CmdDraw = (PFN_vkCmdDraw)gpa(device, "vkCmdDraw");
+    table->CmdDrawIndexed = (PFN_vkCmdDrawIndexed)gpa(device, "vkCmdDrawIndexed");
+    table->CmdDrawIndirect = (PFN_vkCmdDrawIndirect)gpa(device, "vkCmdDrawIndirect");
+    table->CmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect)gpa(device, "vkCmdDrawIndexedIndirect");
+    table->CmdBlitImage = (PFN_vkCmdBlitImage)gpa(device, "vkCmdBlitImage");
+    table->CmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage)gpa(device, "vkCmdClearDepthStencilImage");
+    table->CmdClearAttachments = (PFN_vkCmdClearAttachments)gpa(device, "vkCmdClearAttachments");
+    table->CmdResolveImage = (PFN_vkCmdResolveImage)gpa(device, "vkCmdResolveImage");
+    table->CmdBeginRenderPass = (PFN_vkCmdBeginRenderPass)gpa(device, "vkCmdBeginRenderPass");
+    table->CmdNextSubpass = (PFN_vkCmdNextSubpass)gpa(device, "vkCmdNextSubpass");
+    table->CmdEndRenderPass = (PFN_vkCmdEndRenderPass)gpa(device, "vkCmdEndRenderPass");
+    table->BindBufferMemory2 = (PFN_vkBindBufferMemory2)gpa(device, "vkBindBufferMemory2");
+    table->BindImageMemory2 = (PFN_vkBindImageMemory2)gpa(device, "vkBindImageMemory2");
+    table->GetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures)gpa(device, "vkGetDeviceGroupPeerMemoryFeatures");
+    table->CmdSetDeviceMask = (PFN_vkCmdSetDeviceMask)gpa(device, "vkCmdSetDeviceMask");
+    table->GetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2)gpa(device, "vkGetImageMemoryRequirements2");
+    table->GetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2)gpa(device, "vkGetBufferMemoryRequirements2");
+    table->GetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2)gpa(device, "vkGetImageSparseMemoryRequirements2");
+    table->TrimCommandPool = (PFN_vkTrimCommandPool)gpa(device, "vkTrimCommandPool");
+    table->GetDeviceQueue2 = (PFN_vkGetDeviceQueue2)gpa(device, "vkGetDeviceQueue2");
+    table->CmdDispatchBase = (PFN_vkCmdDispatchBase)gpa(device, "vkCmdDispatchBase");
+    table->CreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate)gpa(device, "vkCreateDescriptorUpdateTemplate");
+    table->DestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate)gpa(device, "vkDestroyDescriptorUpdateTemplate");
+    table->UpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate)gpa(device, "vkUpdateDescriptorSetWithTemplate");
+    table->GetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport)gpa(device, "vkGetDescriptorSetLayoutSupport");
+    table->CreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)gpa(device, "vkCreateSamplerYcbcrConversion");
+    table->DestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion)gpa(device, "vkDestroySamplerYcbcrConversion");
+    table->ResetQueryPool = (PFN_vkResetQueryPool)gpa(device, "vkResetQueryPool");
+    table->GetSemaphoreCounterValue = (PFN_vkGetSemaphoreCounterValue)gpa(device, "vkGetSemaphoreCounterValue");
+    table->WaitSemaphores = (PFN_vkWaitSemaphores)gpa(device, "vkWaitSemaphores");
+    table->SignalSemaphore = (PFN_vkSignalSemaphore)gpa(device, "vkSignalSemaphore");
+    table->GetBufferDeviceAddress = (PFN_vkGetBufferDeviceAddress)gpa(device, "vkGetBufferDeviceAddress");
+    table->GetBufferOpaqueCaptureAddress = (PFN_vkGetBufferOpaqueCaptureAddress)gpa(device, "vkGetBufferOpaqueCaptureAddress");
+    table->GetDeviceMemoryOpaqueCaptureAddress = (PFN_vkGetDeviceMemoryOpaqueCaptureAddress)gpa(device, "vkGetDeviceMemoryOpaqueCaptureAddress");
+    table->CmdDrawIndirectCount = (PFN_vkCmdDrawIndirectCount)gpa(device, "vkCmdDrawIndirectCount");
+    table->CmdDrawIndexedIndirectCount = (PFN_vkCmdDrawIndexedIndirectCount)gpa(device, "vkCmdDrawIndexedIndirectCount");
+    table->CreateRenderPass2 = (PFN_vkCreateRenderPass2)gpa(device, "vkCreateRenderPass2");
+    table->CmdBeginRenderPass2 = (PFN_vkCmdBeginRenderPass2)gpa(device, "vkCmdBeginRenderPass2");
+    table->CmdNextSubpass2 = (PFN_vkCmdNextSubpass2)gpa(device, "vkCmdNextSubpass2");
+    table->CmdEndRenderPass2 = (PFN_vkCmdEndRenderPass2)gpa(device, "vkCmdEndRenderPass2");
+    table->CreatePrivateDataSlot = (PFN_vkCreatePrivateDataSlot)gpa(device, "vkCreatePrivateDataSlot");
+    table->DestroyPrivateDataSlot = (PFN_vkDestroyPrivateDataSlot)gpa(device, "vkDestroyPrivateDataSlot");
+    table->SetPrivateData = (PFN_vkSetPrivateData)gpa(device, "vkSetPrivateData");
+    table->GetPrivateData = (PFN_vkGetPrivateData)gpa(device, "vkGetPrivateData");
+    table->CmdPipelineBarrier2 = (PFN_vkCmdPipelineBarrier2)gpa(device, "vkCmdPipelineBarrier2");
+    table->CmdWriteTimestamp2 = (PFN_vkCmdWriteTimestamp2)gpa(device, "vkCmdWriteTimestamp2");
+    table->QueueSubmit2 = (PFN_vkQueueSubmit2)gpa(device, "vkQueueSubmit2");
+    table->CmdCopyBuffer2 = (PFN_vkCmdCopyBuffer2)gpa(device, "vkCmdCopyBuffer2");
+    table->CmdCopyImage2 = (PFN_vkCmdCopyImage2)gpa(device, "vkCmdCopyImage2");
+    table->CmdCopyBufferToImage2 = (PFN_vkCmdCopyBufferToImage2)gpa(device, "vkCmdCopyBufferToImage2");
+    table->CmdCopyImageToBuffer2 = (PFN_vkCmdCopyImageToBuffer2)gpa(device, "vkCmdCopyImageToBuffer2");
+    table->GetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements)gpa(device, "vkGetDeviceBufferMemoryRequirements");
+    table->GetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements)gpa(device, "vkGetDeviceImageMemoryRequirements");
+    table->GetDeviceImageSparseMemoryRequirements = (PFN_vkGetDeviceImageSparseMemoryRequirements)gpa(device, "vkGetDeviceImageSparseMemoryRequirements");
+    table->CmdSetEvent2 = (PFN_vkCmdSetEvent2)gpa(device, "vkCmdSetEvent2");
+    table->CmdResetEvent2 = (PFN_vkCmdResetEvent2)gpa(device, "vkCmdResetEvent2");
+    table->CmdWaitEvents2 = (PFN_vkCmdWaitEvents2)gpa(device, "vkCmdWaitEvents2");
+    table->CmdBlitImage2 = (PFN_vkCmdBlitImage2)gpa(device, "vkCmdBlitImage2");
+    table->CmdResolveImage2 = (PFN_vkCmdResolveImage2)gpa(device, "vkCmdResolveImage2");
+    table->CmdBeginRendering = (PFN_vkCmdBeginRendering)gpa(device, "vkCmdBeginRendering");
+    table->CmdEndRendering = (PFN_vkCmdEndRendering)gpa(device, "vkCmdEndRendering");
+    table->CmdSetCullMode = (PFN_vkCmdSetCullMode)gpa(device, "vkCmdSetCullMode");
+    table->CmdSetFrontFace = (PFN_vkCmdSetFrontFace)gpa(device, "vkCmdSetFrontFace");
+    table->CmdSetPrimitiveTopology = (PFN_vkCmdSetPrimitiveTopology)gpa(device, "vkCmdSetPrimitiveTopology");
+    table->CmdSetViewportWithCount = (PFN_vkCmdSetViewportWithCount)gpa(device, "vkCmdSetViewportWithCount");
+    table->CmdSetScissorWithCount = (PFN_vkCmdSetScissorWithCount)gpa(device, "vkCmdSetScissorWithCount");
+    table->CmdBindVertexBuffers2 = (PFN_vkCmdBindVertexBuffers2)gpa(device, "vkCmdBindVertexBuffers2");
+    table->CmdSetDepthTestEnable = (PFN_vkCmdSetDepthTestEnable)gpa(device, "vkCmdSetDepthTestEnable");
+    table->CmdSetDepthWriteEnable = (PFN_vkCmdSetDepthWriteEnable)gpa(device, "vkCmdSetDepthWriteEnable");
+    table->CmdSetDepthCompareOp = (PFN_vkCmdSetDepthCompareOp)gpa(device, "vkCmdSetDepthCompareOp");
+    table->CmdSetDepthBoundsTestEnable = (PFN_vkCmdSetDepthBoundsTestEnable)gpa(device, "vkCmdSetDepthBoundsTestEnable");
+    table->CmdSetStencilTestEnable = (PFN_vkCmdSetStencilTestEnable)gpa(device, "vkCmdSetStencilTestEnable");
+    table->CmdSetStencilOp = (PFN_vkCmdSetStencilOp)gpa(device, "vkCmdSetStencilOp");
+    table->CmdSetRasterizerDiscardEnable = (PFN_vkCmdSetRasterizerDiscardEnable)gpa(device, "vkCmdSetRasterizerDiscardEnable");
+    table->CmdSetDepthBiasEnable = (PFN_vkCmdSetDepthBiasEnable)gpa(device, "vkCmdSetDepthBiasEnable");
+    table->CmdSetPrimitiveRestartEnable = (PFN_vkCmdSetPrimitiveRestartEnable)gpa(device, "vkCmdSetPrimitiveRestartEnable");
+    table->MapMemory2 = (PFN_vkMapMemory2)gpa(device, "vkMapMemory2");
+    table->UnmapMemory2 = (PFN_vkUnmapMemory2)gpa(device, "vkUnmapMemory2");
+    table->GetDeviceImageSubresourceLayout = (PFN_vkGetDeviceImageSubresourceLayout)gpa(device, "vkGetDeviceImageSubresourceLayout");
+    table->GetImageSubresourceLayout2 = (PFN_vkGetImageSubresourceLayout2)gpa(device, "vkGetImageSubresourceLayout2");
+    table->CopyMemoryToImage = (PFN_vkCopyMemoryToImage)gpa(device, "vkCopyMemoryToImage");
+    table->CopyImageToMemory = (PFN_vkCopyImageToMemory)gpa(device, "vkCopyImageToMemory");
+    table->CopyImageToImage = (PFN_vkCopyImageToImage)gpa(device, "vkCopyImageToImage");
+    table->TransitionImageLayout = (PFN_vkTransitionImageLayout)gpa(device, "vkTransitionImageLayout");
+    table->CmdPushDescriptorSet = (PFN_vkCmdPushDescriptorSet)gpa(device, "vkCmdPushDescriptorSet");
+    table->CmdPushDescriptorSetWithTemplate = (PFN_vkCmdPushDescriptorSetWithTemplate)gpa(device, "vkCmdPushDescriptorSetWithTemplate");
+    table->CmdBindDescriptorSets2 = (PFN_vkCmdBindDescriptorSets2)gpa(device, "vkCmdBindDescriptorSets2");
+    table->CmdPushConstants2 = (PFN_vkCmdPushConstants2)gpa(device, "vkCmdPushConstants2");
+    table->CmdPushDescriptorSet2 = (PFN_vkCmdPushDescriptorSet2)gpa(device, "vkCmdPushDescriptorSet2");
+    table->CmdPushDescriptorSetWithTemplate2 = (PFN_vkCmdPushDescriptorSetWithTemplate2)gpa(device, "vkCmdPushDescriptorSetWithTemplate2");
+    table->CmdSetLineStipple = (PFN_vkCmdSetLineStipple)gpa(device, "vkCmdSetLineStipple");
+    table->CmdBindIndexBuffer2 = (PFN_vkCmdBindIndexBuffer2)gpa(device, "vkCmdBindIndexBuffer2");
+    table->GetRenderingAreaGranularity = (PFN_vkGetRenderingAreaGranularity)gpa(device, "vkGetRenderingAreaGranularity");
+    table->CmdSetRenderingAttachmentLocations = (PFN_vkCmdSetRenderingAttachmentLocations)gpa(device, "vkCmdSetRenderingAttachmentLocations");
+    table->CmdSetRenderingInputAttachmentIndices = (PFN_vkCmdSetRenderingInputAttachmentIndices)gpa(device, "vkCmdSetRenderingInputAttachmentIndices");
+    table->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
+    table->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR");
+    table->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
+    table->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
+    table->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
+    table->GetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR)gpa(device, "vkGetDeviceGroupPresentCapabilitiesKHR");
+    table->GetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR)gpa(device, "vkGetDeviceGroupSurfacePresentModesKHR");
+    table->AcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR)gpa(device, "vkAcquireNextImage2KHR");
+    table->CreateSharedSwapchainsKHR = (PFN_vkCreateSharedSwapchainsKHR)gpa(device, "vkCreateSharedSwapchainsKHR");
+    table->CreateVideoSessionKHR = (PFN_vkCreateVideoSessionKHR)gpa(device, "vkCreateVideoSessionKHR");
+    table->DestroyVideoSessionKHR = (PFN_vkDestroyVideoSessionKHR)gpa(device, "vkDestroyVideoSessionKHR");
+    table->GetVideoSessionMemoryRequirementsKHR = (PFN_vkGetVideoSessionMemoryRequirementsKHR)gpa(device, "vkGetVideoSessionMemoryRequirementsKHR");
+    table->BindVideoSessionMemoryKHR = (PFN_vkBindVideoSessionMemoryKHR)gpa(device, "vkBindVideoSessionMemoryKHR");
+    table->CreateVideoSessionParametersKHR = (PFN_vkCreateVideoSessionParametersKHR)gpa(device, "vkCreateVideoSessionParametersKHR");
+    table->UpdateVideoSessionParametersKHR = (PFN_vkUpdateVideoSessionParametersKHR)gpa(device, "vkUpdateVideoSessionParametersKHR");
+    table->DestroyVideoSessionParametersKHR = (PFN_vkDestroyVideoSessionParametersKHR)gpa(device, "vkDestroyVideoSessionParametersKHR");
+    table->CmdBeginVideoCodingKHR = (PFN_vkCmdBeginVideoCodingKHR)gpa(device, "vkCmdBeginVideoCodingKHR");
+    table->CmdEndVideoCodingKHR = (PFN_vkCmdEndVideoCodingKHR)gpa(device, "vkCmdEndVideoCodingKHR");
+    table->CmdControlVideoCodingKHR = (PFN_vkCmdControlVideoCodingKHR)gpa(device, "vkCmdControlVideoCodingKHR");
+    table->CmdDecodeVideoKHR = (PFN_vkCmdDecodeVideoKHR)gpa(device, "vkCmdDecodeVideoKHR");
+    table->CmdBeginRenderingKHR = (PFN_vkCmdBeginRenderingKHR)gpa(device, "vkCmdBeginRenderingKHR");
+    table->CmdEndRenderingKHR = (PFN_vkCmdEndRenderingKHR)gpa(device, "vkCmdEndRenderingKHR");
+    table->GetDeviceGroupPeerMemoryFeaturesKHR = (PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR)gpa(device, "vkGetDeviceGroupPeerMemoryFeaturesKHR");
+    table->CmdSetDeviceMaskKHR = (PFN_vkCmdSetDeviceMaskKHR)gpa(device, "vkCmdSetDeviceMaskKHR");
+    table->CmdDispatchBaseKHR = (PFN_vkCmdDispatchBaseKHR)gpa(device, "vkCmdDispatchBaseKHR");
+    table->TrimCommandPoolKHR = (PFN_vkTrimCommandPoolKHR)gpa(device, "vkTrimCommandPoolKHR");
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->GetMemoryWin32HandleKHR = (PFN_vkGetMemoryWin32HandleKHR)gpa(device, "vkGetMemoryWin32HandleKHR");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->GetMemoryWin32HandlePropertiesKHR = (PFN_vkGetMemoryWin32HandlePropertiesKHR)gpa(device, "vkGetMemoryWin32HandlePropertiesKHR");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+    table->GetMemoryFdKHR = (PFN_vkGetMemoryFdKHR)gpa(device, "vkGetMemoryFdKHR");
+    table->GetMemoryFdPropertiesKHR = (PFN_vkGetMemoryFdPropertiesKHR)gpa(device, "vkGetMemoryFdPropertiesKHR");
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->ImportSemaphoreWin32HandleKHR = (PFN_vkImportSemaphoreWin32HandleKHR)gpa(device, "vkImportSemaphoreWin32HandleKHR");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->GetSemaphoreWin32HandleKHR = (PFN_vkGetSemaphoreWin32HandleKHR)gpa(device, "vkGetSemaphoreWin32HandleKHR");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+    table->ImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)gpa(device, "vkImportSemaphoreFdKHR");
+    table->GetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)gpa(device, "vkGetSemaphoreFdKHR");
+    table->CmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)gpa(device, "vkCmdPushDescriptorSetKHR");
+    table->CmdPushDescriptorSetWithTemplateKHR = (PFN_vkCmdPushDescriptorSetWithTemplateKHR)gpa(device, "vkCmdPushDescriptorSetWithTemplateKHR");
+    table->CreateDescriptorUpdateTemplateKHR = (PFN_vkCreateDescriptorUpdateTemplateKHR)gpa(device, "vkCreateDescriptorUpdateTemplateKHR");
+    table->DestroyDescriptorUpdateTemplateKHR = (PFN_vkDestroyDescriptorUpdateTemplateKHR)gpa(device, "vkDestroyDescriptorUpdateTemplateKHR");
+    table->UpdateDescriptorSetWithTemplateKHR = (PFN_vkUpdateDescriptorSetWithTemplateKHR)gpa(device, "vkUpdateDescriptorSetWithTemplateKHR");
+    table->CreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)gpa(device, "vkCreateRenderPass2KHR");
+    table->CmdBeginRenderPass2KHR = (PFN_vkCmdBeginRenderPass2KHR)gpa(device, "vkCmdBeginRenderPass2KHR");
+    table->CmdNextSubpass2KHR = (PFN_vkCmdNextSubpass2KHR)gpa(device, "vkCmdNextSubpass2KHR");
+    table->CmdEndRenderPass2KHR = (PFN_vkCmdEndRenderPass2KHR)gpa(device, "vkCmdEndRenderPass2KHR");
+    table->GetSwapchainStatusKHR = (PFN_vkGetSwapchainStatusKHR)gpa(device, "vkGetSwapchainStatusKHR");
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->ImportFenceWin32HandleKHR = (PFN_vkImportFenceWin32HandleKHR)gpa(device, "vkImportFenceWin32HandleKHR");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->GetFenceWin32HandleKHR = (PFN_vkGetFenceWin32HandleKHR)gpa(device, "vkGetFenceWin32HandleKHR");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+    table->ImportFenceFdKHR = (PFN_vkImportFenceFdKHR)gpa(device, "vkImportFenceFdKHR");
+    table->GetFenceFdKHR = (PFN_vkGetFenceFdKHR)gpa(device, "vkGetFenceFdKHR");
+    table->AcquireProfilingLockKHR = (PFN_vkAcquireProfilingLockKHR)gpa(device, "vkAcquireProfilingLockKHR");
+    table->ReleaseProfilingLockKHR = (PFN_vkReleaseProfilingLockKHR)gpa(device, "vkReleaseProfilingLockKHR");
+    table->GetImageMemoryRequirements2KHR = (PFN_vkGetImageMemoryRequirements2KHR)gpa(device, "vkGetImageMemoryRequirements2KHR");
+    table->GetBufferMemoryRequirements2KHR = (PFN_vkGetBufferMemoryRequirements2KHR)gpa(device, "vkGetBufferMemoryRequirements2KHR");
+    table->GetImageSparseMemoryRequirements2KHR = (PFN_vkGetImageSparseMemoryRequirements2KHR)gpa(device, "vkGetImageSparseMemoryRequirements2KHR");
+    table->CreateSamplerYcbcrConversionKHR = (PFN_vkCreateSamplerYcbcrConversionKHR)gpa(device, "vkCreateSamplerYcbcrConversionKHR");
+    table->DestroySamplerYcbcrConversionKHR = (PFN_vkDestroySamplerYcbcrConversionKHR)gpa(device, "vkDestroySamplerYcbcrConversionKHR");
+    table->BindBufferMemory2KHR = (PFN_vkBindBufferMemory2KHR)gpa(device, "vkBindBufferMemory2KHR");
+    table->BindImageMemory2KHR = (PFN_vkBindImageMemory2KHR)gpa(device, "vkBindImageMemory2KHR");
+    table->GetDescriptorSetLayoutSupportKHR = (PFN_vkGetDescriptorSetLayoutSupportKHR)gpa(device, "vkGetDescriptorSetLayoutSupportKHR");
+    table->CmdDrawIndirectCountKHR = (PFN_vkCmdDrawIndirectCountKHR)gpa(device, "vkCmdDrawIndirectCountKHR");
+    table->CmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR)gpa(device, "vkCmdDrawIndexedIndirectCountKHR");
+    table->GetSemaphoreCounterValueKHR = (PFN_vkGetSemaphoreCounterValueKHR)gpa(device, "vkGetSemaphoreCounterValueKHR");
+    table->WaitSemaphoresKHR = (PFN_vkWaitSemaphoresKHR)gpa(device, "vkWaitSemaphoresKHR");
+    table->SignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR)gpa(device, "vkSignalSemaphoreKHR");
+    table->CmdSetFragmentShadingRateKHR = (PFN_vkCmdSetFragmentShadingRateKHR)gpa(device, "vkCmdSetFragmentShadingRateKHR");
+    table->CmdSetRenderingAttachmentLocationsKHR = (PFN_vkCmdSetRenderingAttachmentLocationsKHR)gpa(device, "vkCmdSetRenderingAttachmentLocationsKHR");
+    table->CmdSetRenderingInputAttachmentIndicesKHR = (PFN_vkCmdSetRenderingInputAttachmentIndicesKHR)gpa(device, "vkCmdSetRenderingInputAttachmentIndicesKHR");
+    table->WaitForPresentKHR = (PFN_vkWaitForPresentKHR)gpa(device, "vkWaitForPresentKHR");
+    table->GetBufferDeviceAddressKHR = (PFN_vkGetBufferDeviceAddressKHR)gpa(device, "vkGetBufferDeviceAddressKHR");
+    table->GetBufferOpaqueCaptureAddressKHR = (PFN_vkGetBufferOpaqueCaptureAddressKHR)gpa(device, "vkGetBufferOpaqueCaptureAddressKHR");
+    table->GetDeviceMemoryOpaqueCaptureAddressKHR = (PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)gpa(device, "vkGetDeviceMemoryOpaqueCaptureAddressKHR");
+    table->CreateDeferredOperationKHR = (PFN_vkCreateDeferredOperationKHR)gpa(device, "vkCreateDeferredOperationKHR");
+    table->DestroyDeferredOperationKHR = (PFN_vkDestroyDeferredOperationKHR)gpa(device, "vkDestroyDeferredOperationKHR");
+    table->GetDeferredOperationMaxConcurrencyKHR = (PFN_vkGetDeferredOperationMaxConcurrencyKHR)gpa(device, "vkGetDeferredOperationMaxConcurrencyKHR");
+    table->GetDeferredOperationResultKHR = (PFN_vkGetDeferredOperationResultKHR)gpa(device, "vkGetDeferredOperationResultKHR");
+    table->DeferredOperationJoinKHR = (PFN_vkDeferredOperationJoinKHR)gpa(device, "vkDeferredOperationJoinKHR");
+    table->GetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)gpa(device, "vkGetPipelineExecutablePropertiesKHR");
+    table->GetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)gpa(device, "vkGetPipelineExecutableStatisticsKHR");
+    table->GetPipelineExecutableInternalRepresentationsKHR = (PFN_vkGetPipelineExecutableInternalRepresentationsKHR)gpa(device, "vkGetPipelineExecutableInternalRepresentationsKHR");
+    table->MapMemory2KHR = (PFN_vkMapMemory2KHR)gpa(device, "vkMapMemory2KHR");
+    table->UnmapMemory2KHR = (PFN_vkUnmapMemory2KHR)gpa(device, "vkUnmapMemory2KHR");
+    table->GetEncodedVideoSessionParametersKHR = (PFN_vkGetEncodedVideoSessionParametersKHR)gpa(device, "vkGetEncodedVideoSessionParametersKHR");
+    table->CmdEncodeVideoKHR = (PFN_vkCmdEncodeVideoKHR)gpa(device, "vkCmdEncodeVideoKHR");
+    table->CmdSetEvent2KHR = (PFN_vkCmdSetEvent2KHR)gpa(device, "vkCmdSetEvent2KHR");
+    table->CmdResetEvent2KHR = (PFN_vkCmdResetEvent2KHR)gpa(device, "vkCmdResetEvent2KHR");
+    table->CmdWaitEvents2KHR = (PFN_vkCmdWaitEvents2KHR)gpa(device, "vkCmdWaitEvents2KHR");
+    table->CmdPipelineBarrier2KHR = (PFN_vkCmdPipelineBarrier2KHR)gpa(device, "vkCmdPipelineBarrier2KHR");
+    table->CmdWriteTimestamp2KHR = (PFN_vkCmdWriteTimestamp2KHR)gpa(device, "vkCmdWriteTimestamp2KHR");
+    table->QueueSubmit2KHR = (PFN_vkQueueSubmit2KHR)gpa(device, "vkQueueSubmit2KHR");
+    table->CmdBindIndexBuffer3KHR = (PFN_vkCmdBindIndexBuffer3KHR)gpa(device, "vkCmdBindIndexBuffer3KHR");
+    table->CmdBindVertexBuffers3KHR = (PFN_vkCmdBindVertexBuffers3KHR)gpa(device, "vkCmdBindVertexBuffers3KHR");
+    table->CmdDrawIndirect2KHR = (PFN_vkCmdDrawIndirect2KHR)gpa(device, "vkCmdDrawIndirect2KHR");
+    table->CmdDrawIndexedIndirect2KHR = (PFN_vkCmdDrawIndexedIndirect2KHR)gpa(device, "vkCmdDrawIndexedIndirect2KHR");
+    table->CmdDispatchIndirect2KHR = (PFN_vkCmdDispatchIndirect2KHR)gpa(device, "vkCmdDispatchIndirect2KHR");
+    table->CmdCopyMemoryKHR = (PFN_vkCmdCopyMemoryKHR)gpa(device, "vkCmdCopyMemoryKHR");
+    table->CmdCopyMemoryToImageKHR = (PFN_vkCmdCopyMemoryToImageKHR)gpa(device, "vkCmdCopyMemoryToImageKHR");
+    table->CmdCopyImageToMemoryKHR = (PFN_vkCmdCopyImageToMemoryKHR)gpa(device, "vkCmdCopyImageToMemoryKHR");
+    table->CmdUpdateMemoryKHR = (PFN_vkCmdUpdateMemoryKHR)gpa(device, "vkCmdUpdateMemoryKHR");
+    table->CmdFillMemoryKHR = (PFN_vkCmdFillMemoryKHR)gpa(device, "vkCmdFillMemoryKHR");
+    table->CmdCopyQueryPoolResultsToMemoryKHR = (PFN_vkCmdCopyQueryPoolResultsToMemoryKHR)gpa(device, "vkCmdCopyQueryPoolResultsToMemoryKHR");
+    table->CmdDrawIndirectCount2KHR = (PFN_vkCmdDrawIndirectCount2KHR)gpa(device, "vkCmdDrawIndirectCount2KHR");
+    table->CmdDrawIndexedIndirectCount2KHR = (PFN_vkCmdDrawIndexedIndirectCount2KHR)gpa(device, "vkCmdDrawIndexedIndirectCount2KHR");
+    table->CmdBeginConditionalRendering2EXT = (PFN_vkCmdBeginConditionalRendering2EXT)gpa(device, "vkCmdBeginConditionalRendering2EXT");
+    table->CmdBindTransformFeedbackBuffers2EXT = (PFN_vkCmdBindTransformFeedbackBuffers2EXT)gpa(device, "vkCmdBindTransformFeedbackBuffers2EXT");
+    table->CmdBeginTransformFeedback2EXT = (PFN_vkCmdBeginTransformFeedback2EXT)gpa(device, "vkCmdBeginTransformFeedback2EXT");
+    table->CmdEndTransformFeedback2EXT = (PFN_vkCmdEndTransformFeedback2EXT)gpa(device, "vkCmdEndTransformFeedback2EXT");
+    table->CmdDrawIndirectByteCount2EXT = (PFN_vkCmdDrawIndirectByteCount2EXT)gpa(device, "vkCmdDrawIndirectByteCount2EXT");
+    table->CmdDrawMeshTasksIndirect2EXT = (PFN_vkCmdDrawMeshTasksIndirect2EXT)gpa(device, "vkCmdDrawMeshTasksIndirect2EXT");
+    table->CmdDrawMeshTasksIndirectCount2EXT = (PFN_vkCmdDrawMeshTasksIndirectCount2EXT)gpa(device, "vkCmdDrawMeshTasksIndirectCount2EXT");
+    table->CmdWriteMarkerToMemoryAMD = (PFN_vkCmdWriteMarkerToMemoryAMD)gpa(device, "vkCmdWriteMarkerToMemoryAMD");
+    table->CreateAccelerationStructure2KHR = (PFN_vkCreateAccelerationStructure2KHR)gpa(device, "vkCreateAccelerationStructure2KHR");
+    table->CmdCopyBuffer2KHR = (PFN_vkCmdCopyBuffer2KHR)gpa(device, "vkCmdCopyBuffer2KHR");
+    table->CmdCopyImage2KHR = (PFN_vkCmdCopyImage2KHR)gpa(device, "vkCmdCopyImage2KHR");
+    table->CmdCopyBufferToImage2KHR = (PFN_vkCmdCopyBufferToImage2KHR)gpa(device, "vkCmdCopyBufferToImage2KHR");
+    table->CmdCopyImageToBuffer2KHR = (PFN_vkCmdCopyImageToBuffer2KHR)gpa(device, "vkCmdCopyImageToBuffer2KHR");
+    table->CmdBlitImage2KHR = (PFN_vkCmdBlitImage2KHR)gpa(device, "vkCmdBlitImage2KHR");
+    table->CmdResolveImage2KHR = (PFN_vkCmdResolveImage2KHR)gpa(device, "vkCmdResolveImage2KHR");
+    table->CmdTraceRaysIndirect2KHR = (PFN_vkCmdTraceRaysIndirect2KHR)gpa(device, "vkCmdTraceRaysIndirect2KHR");
+    table->GetDeviceBufferMemoryRequirementsKHR = (PFN_vkGetDeviceBufferMemoryRequirementsKHR)gpa(device, "vkGetDeviceBufferMemoryRequirementsKHR");
+    table->GetDeviceImageMemoryRequirementsKHR = (PFN_vkGetDeviceImageMemoryRequirementsKHR)gpa(device, "vkGetDeviceImageMemoryRequirementsKHR");
+    table->GetDeviceImageSparseMemoryRequirementsKHR = (PFN_vkGetDeviceImageSparseMemoryRequirementsKHR)gpa(device, "vkGetDeviceImageSparseMemoryRequirementsKHR");
+    table->CmdBindIndexBuffer2KHR = (PFN_vkCmdBindIndexBuffer2KHR)gpa(device, "vkCmdBindIndexBuffer2KHR");
+    table->GetRenderingAreaGranularityKHR = (PFN_vkGetRenderingAreaGranularityKHR)gpa(device, "vkGetRenderingAreaGranularityKHR");
+    table->GetDeviceImageSubresourceLayoutKHR = (PFN_vkGetDeviceImageSubresourceLayoutKHR)gpa(device, "vkGetDeviceImageSubresourceLayoutKHR");
+    table->GetImageSubresourceLayout2KHR = (PFN_vkGetImageSubresourceLayout2KHR)gpa(device, "vkGetImageSubresourceLayout2KHR");
+    table->WaitForPresent2KHR = (PFN_vkWaitForPresent2KHR)gpa(device, "vkWaitForPresent2KHR");
+    table->CreatePipelineBinariesKHR = (PFN_vkCreatePipelineBinariesKHR)gpa(device, "vkCreatePipelineBinariesKHR");
+    table->DestroyPipelineBinaryKHR = (PFN_vkDestroyPipelineBinaryKHR)gpa(device, "vkDestroyPipelineBinaryKHR");
+    table->GetPipelineKeyKHR = (PFN_vkGetPipelineKeyKHR)gpa(device, "vkGetPipelineKeyKHR");
+    table->GetPipelineBinaryDataKHR = (PFN_vkGetPipelineBinaryDataKHR)gpa(device, "vkGetPipelineBinaryDataKHR");
+    table->ReleaseCapturedPipelineDataKHR = (PFN_vkReleaseCapturedPipelineDataKHR)gpa(device, "vkReleaseCapturedPipelineDataKHR");
+    table->ReleaseSwapchainImagesKHR = (PFN_vkReleaseSwapchainImagesKHR)gpa(device, "vkReleaseSwapchainImagesKHR");
+    table->CmdSetLineStippleKHR = (PFN_vkCmdSetLineStippleKHR)gpa(device, "vkCmdSetLineStippleKHR");
+    table->GetCalibratedTimestampsKHR = (PFN_vkGetCalibratedTimestampsKHR)gpa(device, "vkGetCalibratedTimestampsKHR");
+    table->CmdBindDescriptorSets2KHR = (PFN_vkCmdBindDescriptorSets2KHR)gpa(device, "vkCmdBindDescriptorSets2KHR");
+    table->CmdPushConstants2KHR = (PFN_vkCmdPushConstants2KHR)gpa(device, "vkCmdPushConstants2KHR");
+    table->CmdPushDescriptorSet2KHR = (PFN_vkCmdPushDescriptorSet2KHR)gpa(device, "vkCmdPushDescriptorSet2KHR");
+    table->CmdPushDescriptorSetWithTemplate2KHR = (PFN_vkCmdPushDescriptorSetWithTemplate2KHR)gpa(device, "vkCmdPushDescriptorSetWithTemplate2KHR");
+    table->CmdSetDescriptorBufferOffsets2EXT = (PFN_vkCmdSetDescriptorBufferOffsets2EXT)gpa(device, "vkCmdSetDescriptorBufferOffsets2EXT");
+    table->CmdBindDescriptorBufferEmbeddedSamplers2EXT = (PFN_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT)gpa(device, "vkCmdBindDescriptorBufferEmbeddedSamplers2EXT");
+    table->CmdCopyMemoryIndirectKHR = (PFN_vkCmdCopyMemoryIndirectKHR)gpa(device, "vkCmdCopyMemoryIndirectKHR");
+    table->CmdCopyMemoryToImageIndirectKHR = (PFN_vkCmdCopyMemoryToImageIndirectKHR)gpa(device, "vkCmdCopyMemoryToImageIndirectKHR");
+    table->GetDeviceFaultReportsKHR = (PFN_vkGetDeviceFaultReportsKHR)gpa(device, "vkGetDeviceFaultReportsKHR");
+    table->GetDeviceFaultDebugInfoKHR = (PFN_vkGetDeviceFaultDebugInfoKHR)gpa(device, "vkGetDeviceFaultDebugInfoKHR");
+    table->CmdEndRendering2KHR = (PFN_vkCmdEndRendering2KHR)gpa(device, "vkCmdEndRendering2KHR");
+    table->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)gpa(device, "vkDebugMarkerSetObjectTagEXT");
+    table->DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)gpa(device, "vkDebugMarkerSetObjectNameEXT");
+    table->CmdDebugMarkerBeginEXT = (PFN_vkCmdDebugMarkerBeginEXT)gpa(device, "vkCmdDebugMarkerBeginEXT");
+    table->CmdDebugMarkerEndEXT = (PFN_vkCmdDebugMarkerEndEXT)gpa(device, "vkCmdDebugMarkerEndEXT");
+    table->CmdDebugMarkerInsertEXT = (PFN_vkCmdDebugMarkerInsertEXT)gpa(device, "vkCmdDebugMarkerInsertEXT");
+    table->CmdBindTransformFeedbackBuffersEXT = (PFN_vkCmdBindTransformFeedbackBuffersEXT)gpa(device, "vkCmdBindTransformFeedbackBuffersEXT");
+    table->CmdBeginTransformFeedbackEXT = (PFN_vkCmdBeginTransformFeedbackEXT)gpa(device, "vkCmdBeginTransformFeedbackEXT");
+    table->CmdEndTransformFeedbackEXT = (PFN_vkCmdEndTransformFeedbackEXT)gpa(device, "vkCmdEndTransformFeedbackEXT");
+    table->CmdBeginQueryIndexedEXT = (PFN_vkCmdBeginQueryIndexedEXT)gpa(device, "vkCmdBeginQueryIndexedEXT");
+    table->CmdEndQueryIndexedEXT = (PFN_vkCmdEndQueryIndexedEXT)gpa(device, "vkCmdEndQueryIndexedEXT");
+    table->CmdDrawIndirectByteCountEXT = (PFN_vkCmdDrawIndirectByteCountEXT)gpa(device, "vkCmdDrawIndirectByteCountEXT");
+    table->CreateCuModuleNVX = (PFN_vkCreateCuModuleNVX)gpa(device, "vkCreateCuModuleNVX");
+    table->CreateCuFunctionNVX = (PFN_vkCreateCuFunctionNVX)gpa(device, "vkCreateCuFunctionNVX");
+    table->DestroyCuModuleNVX = (PFN_vkDestroyCuModuleNVX)gpa(device, "vkDestroyCuModuleNVX");
+    table->DestroyCuFunctionNVX = (PFN_vkDestroyCuFunctionNVX)gpa(device, "vkDestroyCuFunctionNVX");
+    table->CmdCuLaunchKernelNVX = (PFN_vkCmdCuLaunchKernelNVX)gpa(device, "vkCmdCuLaunchKernelNVX");
+    table->GetImageViewHandleNVX = (PFN_vkGetImageViewHandleNVX)gpa(device, "vkGetImageViewHandleNVX");
+    table->GetImageViewHandle64NVX = (PFN_vkGetImageViewHandle64NVX)gpa(device, "vkGetImageViewHandle64NVX");
+    table->GetImageViewAddressNVX = (PFN_vkGetImageViewAddressNVX)gpa(device, "vkGetImageViewAddressNVX");
+    table->GetDeviceCombinedImageSamplerIndexNVX = (PFN_vkGetDeviceCombinedImageSamplerIndexNVX)gpa(device, "vkGetDeviceCombinedImageSamplerIndexNVX");
+    table->CmdDrawIndirectCountAMD = (PFN_vkCmdDrawIndirectCountAMD)gpa(device, "vkCmdDrawIndirectCountAMD");
+    table->CmdDrawIndexedIndirectCountAMD = (PFN_vkCmdDrawIndexedIndirectCountAMD)gpa(device, "vkCmdDrawIndexedIndirectCountAMD");
+    table->GetShaderInfoAMD = (PFN_vkGetShaderInfoAMD)gpa(device, "vkGetShaderInfoAMD");
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->GetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV)gpa(device, "vkGetMemoryWin32HandleNV");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+    table->CmdBeginConditionalRenderingEXT = (PFN_vkCmdBeginConditionalRenderingEXT)gpa(device, "vkCmdBeginConditionalRenderingEXT");
+    table->CmdEndConditionalRenderingEXT = (PFN_vkCmdEndConditionalRenderingEXT)gpa(device, "vkCmdEndConditionalRenderingEXT");
+    table->CmdSetViewportWScalingNV = (PFN_vkCmdSetViewportWScalingNV)gpa(device, "vkCmdSetViewportWScalingNV");
+    table->DisplayPowerControlEXT = (PFN_vkDisplayPowerControlEXT)gpa(device, "vkDisplayPowerControlEXT");
+    table->RegisterDeviceEventEXT = (PFN_vkRegisterDeviceEventEXT)gpa(device, "vkRegisterDeviceEventEXT");
+    table->RegisterDisplayEventEXT = (PFN_vkRegisterDisplayEventEXT)gpa(device, "vkRegisterDisplayEventEXT");
+    table->GetSwapchainCounterEXT = (PFN_vkGetSwapchainCounterEXT)gpa(device, "vkGetSwapchainCounterEXT");
+    table->GetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE)gpa(device, "vkGetRefreshCycleDurationGOOGLE");
+    table->GetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE)gpa(device, "vkGetPastPresentationTimingGOOGLE");
+    table->CmdSetDiscardRectangleEXT = (PFN_vkCmdSetDiscardRectangleEXT)gpa(device, "vkCmdSetDiscardRectangleEXT");
+    table->CmdSetDiscardRectangleEnableEXT = (PFN_vkCmdSetDiscardRectangleEnableEXT)gpa(device, "vkCmdSetDiscardRectangleEnableEXT");
+    table->CmdSetDiscardRectangleModeEXT = (PFN_vkCmdSetDiscardRectangleModeEXT)gpa(device, "vkCmdSetDiscardRectangleModeEXT");
+    table->SetHdrMetadataEXT = (PFN_vkSetHdrMetadataEXT)gpa(device, "vkSetHdrMetadataEXT");
+    table->SetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)gpa(device, "vkSetDebugUtilsObjectNameEXT");
+    table->SetDebugUtilsObjectTagEXT = (PFN_vkSetDebugUtilsObjectTagEXT)gpa(device, "vkSetDebugUtilsObjectTagEXT");
+    table->QueueBeginDebugUtilsLabelEXT = (PFN_vkQueueBeginDebugUtilsLabelEXT)gpa(device, "vkQueueBeginDebugUtilsLabelEXT");
+    table->QueueEndDebugUtilsLabelEXT = (PFN_vkQueueEndDebugUtilsLabelEXT)gpa(device, "vkQueueEndDebugUtilsLabelEXT");
+    table->QueueInsertDebugUtilsLabelEXT = (PFN_vkQueueInsertDebugUtilsLabelEXT)gpa(device, "vkQueueInsertDebugUtilsLabelEXT");
+    table->CmdBeginDebugUtilsLabelEXT = (PFN_vkCmdBeginDebugUtilsLabelEXT)gpa(device, "vkCmdBeginDebugUtilsLabelEXT");
+    table->CmdEndDebugUtilsLabelEXT = (PFN_vkCmdEndDebugUtilsLabelEXT)gpa(device, "vkCmdEndDebugUtilsLabelEXT");
+    table->CmdInsertDebugUtilsLabelEXT = (PFN_vkCmdInsertDebugUtilsLabelEXT)gpa(device, "vkCmdInsertDebugUtilsLabelEXT");
+#if defined(VK_USE_PLATFORM_ANDROID_KHR)
+    table->GetAndroidHardwareBufferPropertiesANDROID = (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)gpa(device, "vkGetAndroidHardwareBufferPropertiesANDROID");
+#endif  // VK_USE_PLATFORM_ANDROID_KHR
+#if defined(VK_USE_PLATFORM_ANDROID_KHR)
+    table->GetMemoryAndroidHardwareBufferANDROID = (PFN_vkGetMemoryAndroidHardwareBufferANDROID)gpa(device, "vkGetMemoryAndroidHardwareBufferANDROID");
+#endif  // VK_USE_PLATFORM_ANDROID_KHR
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->CreateExecutionGraphPipelinesAMDX = (PFN_vkCreateExecutionGraphPipelinesAMDX)gpa(device, "vkCreateExecutionGraphPipelinesAMDX");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->GetExecutionGraphPipelineScratchSizeAMDX = (PFN_vkGetExecutionGraphPipelineScratchSizeAMDX)gpa(device, "vkGetExecutionGraphPipelineScratchSizeAMDX");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->GetExecutionGraphPipelineNodeIndexAMDX = (PFN_vkGetExecutionGraphPipelineNodeIndexAMDX)gpa(device, "vkGetExecutionGraphPipelineNodeIndexAMDX");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->CmdInitializeGraphScratchMemoryAMDX = (PFN_vkCmdInitializeGraphScratchMemoryAMDX)gpa(device, "vkCmdInitializeGraphScratchMemoryAMDX");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->CmdDispatchGraphAMDX = (PFN_vkCmdDispatchGraphAMDX)gpa(device, "vkCmdDispatchGraphAMDX");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->CmdDispatchGraphIndirectAMDX = (PFN_vkCmdDispatchGraphIndirectAMDX)gpa(device, "vkCmdDispatchGraphIndirectAMDX");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->CmdDispatchGraphIndirectCountAMDX = (PFN_vkCmdDispatchGraphIndirectCountAMDX)gpa(device, "vkCmdDispatchGraphIndirectCountAMDX");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+    table->WriteSamplerDescriptorsEXT = (PFN_vkWriteSamplerDescriptorsEXT)gpa(device, "vkWriteSamplerDescriptorsEXT");
+    table->WriteResourceDescriptorsEXT = (PFN_vkWriteResourceDescriptorsEXT)gpa(device, "vkWriteResourceDescriptorsEXT");
+    table->CmdBindSamplerHeapEXT = (PFN_vkCmdBindSamplerHeapEXT)gpa(device, "vkCmdBindSamplerHeapEXT");
+    table->CmdBindResourceHeapEXT = (PFN_vkCmdBindResourceHeapEXT)gpa(device, "vkCmdBindResourceHeapEXT");
+    table->CmdPushDataEXT = (PFN_vkCmdPushDataEXT)gpa(device, "vkCmdPushDataEXT");
+    table->GetImageOpaqueCaptureDataEXT = (PFN_vkGetImageOpaqueCaptureDataEXT)gpa(device, "vkGetImageOpaqueCaptureDataEXT");
+    table->RegisterCustomBorderColorEXT = (PFN_vkRegisterCustomBorderColorEXT)gpa(device, "vkRegisterCustomBorderColorEXT");
+    table->UnregisterCustomBorderColorEXT = (PFN_vkUnregisterCustomBorderColorEXT)gpa(device, "vkUnregisterCustomBorderColorEXT");
+    table->GetTensorOpaqueCaptureDataARM = (PFN_vkGetTensorOpaqueCaptureDataARM)gpa(device, "vkGetTensorOpaqueCaptureDataARM");
+    table->CmdSetSampleLocationsEXT = (PFN_vkCmdSetSampleLocationsEXT)gpa(device, "vkCmdSetSampleLocationsEXT");
+    table->GetImageDrmFormatModifierPropertiesEXT = (PFN_vkGetImageDrmFormatModifierPropertiesEXT)gpa(device, "vkGetImageDrmFormatModifierPropertiesEXT");
+    table->CreateValidationCacheEXT = (PFN_vkCreateValidationCacheEXT)gpa(device, "vkCreateValidationCacheEXT");
+    table->DestroyValidationCacheEXT = (PFN_vkDestroyValidationCacheEXT)gpa(device, "vkDestroyValidationCacheEXT");
+    table->MergeValidationCachesEXT = (PFN_vkMergeValidationCachesEXT)gpa(device, "vkMergeValidationCachesEXT");
+    table->GetValidationCacheDataEXT = (PFN_vkGetValidationCacheDataEXT)gpa(device, "vkGetValidationCacheDataEXT");
+    table->CmdBindShadingRateImageNV = (PFN_vkCmdBindShadingRateImageNV)gpa(device, "vkCmdBindShadingRateImageNV");
+    table->CmdSetViewportShadingRatePaletteNV = (PFN_vkCmdSetViewportShadingRatePaletteNV)gpa(device, "vkCmdSetViewportShadingRatePaletteNV");
+    table->CmdSetCoarseSampleOrderNV = (PFN_vkCmdSetCoarseSampleOrderNV)gpa(device, "vkCmdSetCoarseSampleOrderNV");
+    table->CreateAccelerationStructureNV = (PFN_vkCreateAccelerationStructureNV)gpa(device, "vkCreateAccelerationStructureNV");
+    table->DestroyAccelerationStructureNV = (PFN_vkDestroyAccelerationStructureNV)gpa(device, "vkDestroyAccelerationStructureNV");
+    table->GetAccelerationStructureMemoryRequirementsNV = (PFN_vkGetAccelerationStructureMemoryRequirementsNV)gpa(device, "vkGetAccelerationStructureMemoryRequirementsNV");
+    table->BindAccelerationStructureMemoryNV = (PFN_vkBindAccelerationStructureMemoryNV)gpa(device, "vkBindAccelerationStructureMemoryNV");
+    table->CmdBuildAccelerationStructureNV = (PFN_vkCmdBuildAccelerationStructureNV)gpa(device, "vkCmdBuildAccelerationStructureNV");
+    table->CmdCopyAccelerationStructureNV = (PFN_vkCmdCopyAccelerationStructureNV)gpa(device, "vkCmdCopyAccelerationStructureNV");
+    table->CmdTraceRaysNV = (PFN_vkCmdTraceRaysNV)gpa(device, "vkCmdTraceRaysNV");
+    table->CreateRayTracingPipelinesNV = (PFN_vkCreateRayTracingPipelinesNV)gpa(device, "vkCreateRayTracingPipelinesNV");
+    table->GetRayTracingShaderGroupHandlesKHR = (PFN_vkGetRayTracingShaderGroupHandlesKHR)gpa(device, "vkGetRayTracingShaderGroupHandlesKHR");
+    table->GetRayTracingShaderGroupHandlesNV = (PFN_vkGetRayTracingShaderGroupHandlesNV)gpa(device, "vkGetRayTracingShaderGroupHandlesNV");
+    table->GetAccelerationStructureHandleNV = (PFN_vkGetAccelerationStructureHandleNV)gpa(device, "vkGetAccelerationStructureHandleNV");
+    table->CmdWriteAccelerationStructuresPropertiesNV = (PFN_vkCmdWriteAccelerationStructuresPropertiesNV)gpa(device, "vkCmdWriteAccelerationStructuresPropertiesNV");
+    table->CompileDeferredNV = (PFN_vkCompileDeferredNV)gpa(device, "vkCompileDeferredNV");
+    table->GetMemoryHostPointerPropertiesEXT = (PFN_vkGetMemoryHostPointerPropertiesEXT)gpa(device, "vkGetMemoryHostPointerPropertiesEXT");
+    table->CmdWriteBufferMarkerAMD = (PFN_vkCmdWriteBufferMarkerAMD)gpa(device, "vkCmdWriteBufferMarkerAMD");
+    table->CmdWriteBufferMarker2AMD = (PFN_vkCmdWriteBufferMarker2AMD)gpa(device, "vkCmdWriteBufferMarker2AMD");
+    table->GetCalibratedTimestampsEXT = (PFN_vkGetCalibratedTimestampsEXT)gpa(device, "vkGetCalibratedTimestampsEXT");
+    table->CmdDrawMeshTasksNV = (PFN_vkCmdDrawMeshTasksNV)gpa(device, "vkCmdDrawMeshTasksNV");
+    table->CmdDrawMeshTasksIndirectNV = (PFN_vkCmdDrawMeshTasksIndirectNV)gpa(device, "vkCmdDrawMeshTasksIndirectNV");
+    table->CmdDrawMeshTasksIndirectCountNV = (PFN_vkCmdDrawMeshTasksIndirectCountNV)gpa(device, "vkCmdDrawMeshTasksIndirectCountNV");
+    table->CmdSetExclusiveScissorEnableNV = (PFN_vkCmdSetExclusiveScissorEnableNV)gpa(device, "vkCmdSetExclusiveScissorEnableNV");
+    table->CmdSetExclusiveScissorNV = (PFN_vkCmdSetExclusiveScissorNV)gpa(device, "vkCmdSetExclusiveScissorNV");
+    table->CmdSetCheckpointNV = (PFN_vkCmdSetCheckpointNV)gpa(device, "vkCmdSetCheckpointNV");
+    table->GetQueueCheckpointDataNV = (PFN_vkGetQueueCheckpointDataNV)gpa(device, "vkGetQueueCheckpointDataNV");
+    table->GetQueueCheckpointData2NV = (PFN_vkGetQueueCheckpointData2NV)gpa(device, "vkGetQueueCheckpointData2NV");
+    table->SetSwapchainPresentTimingQueueSizeEXT = (PFN_vkSetSwapchainPresentTimingQueueSizeEXT)gpa(device, "vkSetSwapchainPresentTimingQueueSizeEXT");
+    table->GetSwapchainTimingPropertiesEXT = (PFN_vkGetSwapchainTimingPropertiesEXT)gpa(device, "vkGetSwapchainTimingPropertiesEXT");
+    table->GetSwapchainTimeDomainPropertiesEXT = (PFN_vkGetSwapchainTimeDomainPropertiesEXT)gpa(device, "vkGetSwapchainTimeDomainPropertiesEXT");
+    table->GetPastPresentationTimingEXT = (PFN_vkGetPastPresentationTimingEXT)gpa(device, "vkGetPastPresentationTimingEXT");
+    table->InitializePerformanceApiINTEL = (PFN_vkInitializePerformanceApiINTEL)gpa(device, "vkInitializePerformanceApiINTEL");
+    table->UninitializePerformanceApiINTEL = (PFN_vkUninitializePerformanceApiINTEL)gpa(device, "vkUninitializePerformanceApiINTEL");
+    table->CmdSetPerformanceMarkerINTEL = (PFN_vkCmdSetPerformanceMarkerINTEL)gpa(device, "vkCmdSetPerformanceMarkerINTEL");
+    table->CmdSetPerformanceStreamMarkerINTEL = (PFN_vkCmdSetPerformanceStreamMarkerINTEL)gpa(device, "vkCmdSetPerformanceStreamMarkerINTEL");
+    table->CmdSetPerformanceOverrideINTEL = (PFN_vkCmdSetPerformanceOverrideINTEL)gpa(device, "vkCmdSetPerformanceOverrideINTEL");
+    table->AcquirePerformanceConfigurationINTEL = (PFN_vkAcquirePerformanceConfigurationINTEL)gpa(device, "vkAcquirePerformanceConfigurationINTEL");
+    table->ReleasePerformanceConfigurationINTEL = (PFN_vkReleasePerformanceConfigurationINTEL)gpa(device, "vkReleasePerformanceConfigurationINTEL");
+    table->QueueSetPerformanceConfigurationINTEL = (PFN_vkQueueSetPerformanceConfigurationINTEL)gpa(device, "vkQueueSetPerformanceConfigurationINTEL");
+    table->GetPerformanceParameterINTEL = (PFN_vkGetPerformanceParameterINTEL)gpa(device, "vkGetPerformanceParameterINTEL");
+    table->SetLocalDimmingAMD = (PFN_vkSetLocalDimmingAMD)gpa(device, "vkSetLocalDimmingAMD");
+    table->GetBufferDeviceAddressEXT = (PFN_vkGetBufferDeviceAddressEXT)gpa(device, "vkGetBufferDeviceAddressEXT");
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->AcquireFullScreenExclusiveModeEXT = (PFN_vkAcquireFullScreenExclusiveModeEXT)gpa(device, "vkAcquireFullScreenExclusiveModeEXT");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->ReleaseFullScreenExclusiveModeEXT = (PFN_vkReleaseFullScreenExclusiveModeEXT)gpa(device, "vkReleaseFullScreenExclusiveModeEXT");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)gpa(device, "vkGetDeviceGroupSurfacePresentModes2EXT");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+    table->CmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT)gpa(device, "vkCmdSetLineStippleEXT");
+    table->ResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)gpa(device, "vkResetQueryPoolEXT");
+    table->CmdSetCullModeEXT = (PFN_vkCmdSetCullModeEXT)gpa(device, "vkCmdSetCullModeEXT");
+    table->CmdSetFrontFaceEXT = (PFN_vkCmdSetFrontFaceEXT)gpa(device, "vkCmdSetFrontFaceEXT");
+    table->CmdSetPrimitiveTopologyEXT = (PFN_vkCmdSetPrimitiveTopologyEXT)gpa(device, "vkCmdSetPrimitiveTopologyEXT");
+    table->CmdSetViewportWithCountEXT = (PFN_vkCmdSetViewportWithCountEXT)gpa(device, "vkCmdSetViewportWithCountEXT");
+    table->CmdSetScissorWithCountEXT = (PFN_vkCmdSetScissorWithCountEXT)gpa(device, "vkCmdSetScissorWithCountEXT");
+    table->CmdBindVertexBuffers2EXT = (PFN_vkCmdBindVertexBuffers2EXT)gpa(device, "vkCmdBindVertexBuffers2EXT");
+    table->CmdSetDepthTestEnableEXT = (PFN_vkCmdSetDepthTestEnableEXT)gpa(device, "vkCmdSetDepthTestEnableEXT");
+    table->CmdSetDepthWriteEnableEXT = (PFN_vkCmdSetDepthWriteEnableEXT)gpa(device, "vkCmdSetDepthWriteEnableEXT");
+    table->CmdSetDepthCompareOpEXT = (PFN_vkCmdSetDepthCompareOpEXT)gpa(device, "vkCmdSetDepthCompareOpEXT");
+    table->CmdSetDepthBoundsTestEnableEXT = (PFN_vkCmdSetDepthBoundsTestEnableEXT)gpa(device, "vkCmdSetDepthBoundsTestEnableEXT");
+    table->CmdSetStencilTestEnableEXT = (PFN_vkCmdSetStencilTestEnableEXT)gpa(device, "vkCmdSetStencilTestEnableEXT");
+    table->CmdSetStencilOpEXT = (PFN_vkCmdSetStencilOpEXT)gpa(device, "vkCmdSetStencilOpEXT");
+    table->CopyMemoryToImageEXT = (PFN_vkCopyMemoryToImageEXT)gpa(device, "vkCopyMemoryToImageEXT");
+    table->CopyImageToMemoryEXT = (PFN_vkCopyImageToMemoryEXT)gpa(device, "vkCopyImageToMemoryEXT");
+    table->CopyImageToImageEXT = (PFN_vkCopyImageToImageEXT)gpa(device, "vkCopyImageToImageEXT");
+    table->TransitionImageLayoutEXT = (PFN_vkTransitionImageLayoutEXT)gpa(device, "vkTransitionImageLayoutEXT");
+    table->GetImageSubresourceLayout2EXT = (PFN_vkGetImageSubresourceLayout2EXT)gpa(device, "vkGetImageSubresourceLayout2EXT");
+    table->ReleaseSwapchainImagesEXT = (PFN_vkReleaseSwapchainImagesEXT)gpa(device, "vkReleaseSwapchainImagesEXT");
+    table->GetGeneratedCommandsMemoryRequirementsNV = (PFN_vkGetGeneratedCommandsMemoryRequirementsNV)gpa(device, "vkGetGeneratedCommandsMemoryRequirementsNV");
+    table->CmdPreprocessGeneratedCommandsNV = (PFN_vkCmdPreprocessGeneratedCommandsNV)gpa(device, "vkCmdPreprocessGeneratedCommandsNV");
+    table->CmdExecuteGeneratedCommandsNV = (PFN_vkCmdExecuteGeneratedCommandsNV)gpa(device, "vkCmdExecuteGeneratedCommandsNV");
+    table->CmdBindPipelineShaderGroupNV = (PFN_vkCmdBindPipelineShaderGroupNV)gpa(device, "vkCmdBindPipelineShaderGroupNV");
+    table->CreateIndirectCommandsLayoutNV = (PFN_vkCreateIndirectCommandsLayoutNV)gpa(device, "vkCreateIndirectCommandsLayoutNV");
+    table->DestroyIndirectCommandsLayoutNV = (PFN_vkDestroyIndirectCommandsLayoutNV)gpa(device, "vkDestroyIndirectCommandsLayoutNV");
+    table->CmdSetDepthBias2EXT = (PFN_vkCmdSetDepthBias2EXT)gpa(device, "vkCmdSetDepthBias2EXT");
+    table->CreatePrivateDataSlotEXT = (PFN_vkCreatePrivateDataSlotEXT)gpa(device, "vkCreatePrivateDataSlotEXT");
+    table->DestroyPrivateDataSlotEXT = (PFN_vkDestroyPrivateDataSlotEXT)gpa(device, "vkDestroyPrivateDataSlotEXT");
+    table->SetPrivateDataEXT = (PFN_vkSetPrivateDataEXT)gpa(device, "vkSetPrivateDataEXT");
+    table->GetPrivateDataEXT = (PFN_vkGetPrivateDataEXT)gpa(device, "vkGetPrivateDataEXT");
+    table->QueueSetPerfHintQCOM = (PFN_vkQueueSetPerfHintQCOM)gpa(device, "vkQueueSetPerfHintQCOM");
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->CreateCudaModuleNV = (PFN_vkCreateCudaModuleNV)gpa(device, "vkCreateCudaModuleNV");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->GetCudaModuleCacheNV = (PFN_vkGetCudaModuleCacheNV)gpa(device, "vkGetCudaModuleCacheNV");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->CreateCudaFunctionNV = (PFN_vkCreateCudaFunctionNV)gpa(device, "vkCreateCudaFunctionNV");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->DestroyCudaModuleNV = (PFN_vkDestroyCudaModuleNV)gpa(device, "vkDestroyCudaModuleNV");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->DestroyCudaFunctionNV = (PFN_vkDestroyCudaFunctionNV)gpa(device, "vkDestroyCudaFunctionNV");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+#if defined(VK_ENABLE_BETA_EXTENSIONS)
+    table->CmdCudaLaunchKernelNV = (PFN_vkCmdCudaLaunchKernelNV)gpa(device, "vkCmdCudaLaunchKernelNV");
+#endif  // VK_ENABLE_BETA_EXTENSIONS
+    table->CmdDispatchTileQCOM = (PFN_vkCmdDispatchTileQCOM)gpa(device, "vkCmdDispatchTileQCOM");
+    table->CmdBeginPerTileExecutionQCOM = (PFN_vkCmdBeginPerTileExecutionQCOM)gpa(device, "vkCmdBeginPerTileExecutionQCOM");
+    table->CmdEndPerTileExecutionQCOM = (PFN_vkCmdEndPerTileExecutionQCOM)gpa(device, "vkCmdEndPerTileExecutionQCOM");
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    table->ExportMetalObjectsEXT = (PFN_vkExportMetalObjectsEXT)gpa(device, "vkExportMetalObjectsEXT");
+#endif  // VK_USE_PLATFORM_METAL_EXT
+    table->GetDescriptorSetLayoutSizeEXT = (PFN_vkGetDescriptorSetLayoutSizeEXT)gpa(device, "vkGetDescriptorSetLayoutSizeEXT");
+    table->GetDescriptorSetLayoutBindingOffsetEXT = (PFN_vkGetDescriptorSetLayoutBindingOffsetEXT)gpa(device, "vkGetDescriptorSetLayoutBindingOffsetEXT");
+    table->GetDescriptorEXT = (PFN_vkGetDescriptorEXT)gpa(device, "vkGetDescriptorEXT");
+    table->CmdBindDescriptorBuffersEXT = (PFN_vkCmdBindDescriptorBuffersEXT)gpa(device, "vkCmdBindDescriptorBuffersEXT");
+    table->CmdSetDescriptorBufferOffsetsEXT = (PFN_vkCmdSetDescriptorBufferOffsetsEXT)gpa(device, "vkCmdSetDescriptorBufferOffsetsEXT");
+    table->CmdBindDescriptorBufferEmbeddedSamplersEXT = (PFN_vkCmdBindDescriptorBufferEmbeddedSamplersEXT)gpa(device, "vkCmdBindDescriptorBufferEmbeddedSamplersEXT");
+    table->GetBufferOpaqueCaptureDescriptorDataEXT = (PFN_vkGetBufferOpaqueCaptureDescriptorDataEXT)gpa(device, "vkGetBufferOpaqueCaptureDescriptorDataEXT");
+    table->GetImageOpaqueCaptureDescriptorDataEXT = (PFN_vkGetImageOpaqueCaptureDescriptorDataEXT)gpa(device, "vkGetImageOpaqueCaptureDescriptorDataEXT");
+    table->GetImageViewOpaqueCaptureDescriptorDataEXT = (PFN_vkGetImageViewOpaqueCaptureDescriptorDataEXT)gpa(device, "vkGetImageViewOpaqueCaptureDescriptorDataEXT");
+    table->GetSamplerOpaqueCaptureDescriptorDataEXT = (PFN_vkGetSamplerOpaqueCaptureDescriptorDataEXT)gpa(device, "vkGetSamplerOpaqueCaptureDescriptorDataEXT");
+    table->GetAccelerationStructureOpaqueCaptureDescriptorDataEXT = (PFN_vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT)gpa(device, "vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT");
+    table->CmdSetFragmentShadingRateEnumNV = (PFN_vkCmdSetFragmentShadingRateEnumNV)gpa(device, "vkCmdSetFragmentShadingRateEnumNV");
+    table->GetDeviceFaultInfoEXT = (PFN_vkGetDeviceFaultInfoEXT)gpa(device, "vkGetDeviceFaultInfoEXT");
+    table->CmdSetVertexInputEXT = (PFN_vkCmdSetVertexInputEXT)gpa(device, "vkCmdSetVertexInputEXT");
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    table->GetMemoryZirconHandleFUCHSIA = (PFN_vkGetMemoryZirconHandleFUCHSIA)gpa(device, "vkGetMemoryZirconHandleFUCHSIA");
+#endif  // VK_USE_PLATFORM_FUCHSIA
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    table->GetMemoryZirconHandlePropertiesFUCHSIA = (PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA)gpa(device, "vkGetMemoryZirconHandlePropertiesFUCHSIA");
+#endif  // VK_USE_PLATFORM_FUCHSIA
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    table->ImportSemaphoreZirconHandleFUCHSIA = (PFN_vkImportSemaphoreZirconHandleFUCHSIA)gpa(device, "vkImportSemaphoreZirconHandleFUCHSIA");
+#endif  // VK_USE_PLATFORM_FUCHSIA
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    table->GetSemaphoreZirconHandleFUCHSIA = (PFN_vkGetSemaphoreZirconHandleFUCHSIA)gpa(device, "vkGetSemaphoreZirconHandleFUCHSIA");
+#endif  // VK_USE_PLATFORM_FUCHSIA
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    table->CreateBufferCollectionFUCHSIA = (PFN_vkCreateBufferCollectionFUCHSIA)gpa(device, "vkCreateBufferCollectionFUCHSIA");
+#endif  // VK_USE_PLATFORM_FUCHSIA
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    table->SetBufferCollectionImageConstraintsFUCHSIA = (PFN_vkSetBufferCollectionImageConstraintsFUCHSIA)gpa(device, "vkSetBufferCollectionImageConstraintsFUCHSIA");
+#endif  // VK_USE_PLATFORM_FUCHSIA
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    table->SetBufferCollectionBufferConstraintsFUCHSIA = (PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA)gpa(device, "vkSetBufferCollectionBufferConstraintsFUCHSIA");
+#endif  // VK_USE_PLATFORM_FUCHSIA
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    table->DestroyBufferCollectionFUCHSIA = (PFN_vkDestroyBufferCollectionFUCHSIA)gpa(device, "vkDestroyBufferCollectionFUCHSIA");
+#endif  // VK_USE_PLATFORM_FUCHSIA
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    table->GetBufferCollectionPropertiesFUCHSIA = (PFN_vkGetBufferCollectionPropertiesFUCHSIA)gpa(device, "vkGetBufferCollectionPropertiesFUCHSIA");
+#endif  // VK_USE_PLATFORM_FUCHSIA
+    table->GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI = (PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)gpa(device, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
+    table->CmdSubpassShadingHUAWEI = (PFN_vkCmdSubpassShadingHUAWEI)gpa(device, "vkCmdSubpassShadingHUAWEI");
+    table->CmdBindInvocationMaskHUAWEI = (PFN_vkCmdBindInvocationMaskHUAWEI)gpa(device, "vkCmdBindInvocationMaskHUAWEI");
+    table->GetMemoryRemoteAddressNV = (PFN_vkGetMemoryRemoteAddressNV)gpa(device, "vkGetMemoryRemoteAddressNV");
+    table->GetPipelinePropertiesEXT = (PFN_vkGetPipelinePropertiesEXT)gpa(device, "vkGetPipelinePropertiesEXT");
+    table->CmdSetPatchControlPointsEXT = (PFN_vkCmdSetPatchControlPointsEXT)gpa(device, "vkCmdSetPatchControlPointsEXT");
+    table->CmdSetRasterizerDiscardEnableEXT = (PFN_vkCmdSetRasterizerDiscardEnableEXT)gpa(device, "vkCmdSetRasterizerDiscardEnableEXT");
+    table->CmdSetDepthBiasEnableEXT = (PFN_vkCmdSetDepthBiasEnableEXT)gpa(device, "vkCmdSetDepthBiasEnableEXT");
+    table->CmdSetLogicOpEXT = (PFN_vkCmdSetLogicOpEXT)gpa(device, "vkCmdSetLogicOpEXT");
+    table->CmdSetPrimitiveRestartEnableEXT = (PFN_vkCmdSetPrimitiveRestartEnableEXT)gpa(device, "vkCmdSetPrimitiveRestartEnableEXT");
+    table->CmdSetColorWriteEnableEXT = (PFN_vkCmdSetColorWriteEnableEXT)gpa(device, "vkCmdSetColorWriteEnableEXT");
+    table->CmdDrawMultiEXT = (PFN_vkCmdDrawMultiEXT)gpa(device, "vkCmdDrawMultiEXT");
+    table->CmdDrawMultiIndexedEXT = (PFN_vkCmdDrawMultiIndexedEXT)gpa(device, "vkCmdDrawMultiIndexedEXT");
+    table->CreateMicromapEXT = (PFN_vkCreateMicromapEXT)gpa(device, "vkCreateMicromapEXT");
+    table->DestroyMicromapEXT = (PFN_vkDestroyMicromapEXT)gpa(device, "vkDestroyMicromapEXT");
+    table->CmdBuildMicromapsEXT = (PFN_vkCmdBuildMicromapsEXT)gpa(device, "vkCmdBuildMicromapsEXT");
+    table->BuildMicromapsEXT = (PFN_vkBuildMicromapsEXT)gpa(device, "vkBuildMicromapsEXT");
+    table->CopyMicromapEXT = (PFN_vkCopyMicromapEXT)gpa(device, "vkCopyMicromapEXT");
+    table->CopyMicromapToMemoryEXT = (PFN_vkCopyMicromapToMemoryEXT)gpa(device, "vkCopyMicromapToMemoryEXT");
+    table->CopyMemoryToMicromapEXT = (PFN_vkCopyMemoryToMicromapEXT)gpa(device, "vkCopyMemoryToMicromapEXT");
+    table->WriteMicromapsPropertiesEXT = (PFN_vkWriteMicromapsPropertiesEXT)gpa(device, "vkWriteMicromapsPropertiesEXT");
+    table->CmdCopyMicromapEXT = (PFN_vkCmdCopyMicromapEXT)gpa(device, "vkCmdCopyMicromapEXT");
+    table->CmdCopyMicromapToMemoryEXT = (PFN_vkCmdCopyMicromapToMemoryEXT)gpa(device, "vkCmdCopyMicromapToMemoryEXT");
+    table->CmdCopyMemoryToMicromapEXT = (PFN_vkCmdCopyMemoryToMicromapEXT)gpa(device, "vkCmdCopyMemoryToMicromapEXT");
+    table->CmdWriteMicromapsPropertiesEXT = (PFN_vkCmdWriteMicromapsPropertiesEXT)gpa(device, "vkCmdWriteMicromapsPropertiesEXT");
+    table->GetDeviceMicromapCompatibilityEXT = (PFN_vkGetDeviceMicromapCompatibilityEXT)gpa(device, "vkGetDeviceMicromapCompatibilityEXT");
+    table->GetMicromapBuildSizesEXT = (PFN_vkGetMicromapBuildSizesEXT)gpa(device, "vkGetMicromapBuildSizesEXT");
+    table->CmdDrawClusterHUAWEI = (PFN_vkCmdDrawClusterHUAWEI)gpa(device, "vkCmdDrawClusterHUAWEI");
+    table->CmdDrawClusterIndirectHUAWEI = (PFN_vkCmdDrawClusterIndirectHUAWEI)gpa(device, "vkCmdDrawClusterIndirectHUAWEI");
+    table->SetDeviceMemoryPriorityEXT = (PFN_vkSetDeviceMemoryPriorityEXT)gpa(device, "vkSetDeviceMemoryPriorityEXT");
+    table->CmdSetDispatchParametersARM = (PFN_vkCmdSetDispatchParametersARM)gpa(device, "vkCmdSetDispatchParametersARM");
+    table->GetDescriptorSetLayoutHostMappingInfoVALVE = (PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE)gpa(device, "vkGetDescriptorSetLayoutHostMappingInfoVALVE");
+    table->GetDescriptorSetHostMappingVALVE = (PFN_vkGetDescriptorSetHostMappingVALVE)gpa(device, "vkGetDescriptorSetHostMappingVALVE");
+    table->CmdCopyMemoryIndirectNV = (PFN_vkCmdCopyMemoryIndirectNV)gpa(device, "vkCmdCopyMemoryIndirectNV");
+    table->CmdCopyMemoryToImageIndirectNV = (PFN_vkCmdCopyMemoryToImageIndirectNV)gpa(device, "vkCmdCopyMemoryToImageIndirectNV");
+    table->CmdDecompressMemoryNV = (PFN_vkCmdDecompressMemoryNV)gpa(device, "vkCmdDecompressMemoryNV");
+    table->CmdDecompressMemoryIndirectCountNV = (PFN_vkCmdDecompressMemoryIndirectCountNV)gpa(device, "vkCmdDecompressMemoryIndirectCountNV");
+    table->GetPipelineIndirectMemoryRequirementsNV = (PFN_vkGetPipelineIndirectMemoryRequirementsNV)gpa(device, "vkGetPipelineIndirectMemoryRequirementsNV");
+    table->CmdUpdatePipelineIndirectBufferNV = (PFN_vkCmdUpdatePipelineIndirectBufferNV)gpa(device, "vkCmdUpdatePipelineIndirectBufferNV");
+    table->GetPipelineIndirectDeviceAddressNV = (PFN_vkGetPipelineIndirectDeviceAddressNV)gpa(device, "vkGetPipelineIndirectDeviceAddressNV");
+#if defined(VK_USE_PLATFORM_OHOS)
+    table->GetNativeBufferPropertiesOHOS = (PFN_vkGetNativeBufferPropertiesOHOS)gpa(device, "vkGetNativeBufferPropertiesOHOS");
+#endif  // VK_USE_PLATFORM_OHOS
+#if defined(VK_USE_PLATFORM_OHOS)
+    table->GetMemoryNativeBufferOHOS = (PFN_vkGetMemoryNativeBufferOHOS)gpa(device, "vkGetMemoryNativeBufferOHOS");
+#endif  // VK_USE_PLATFORM_OHOS
+    table->CmdSetDepthClampEnableEXT = (PFN_vkCmdSetDepthClampEnableEXT)gpa(device, "vkCmdSetDepthClampEnableEXT");
+    table->CmdSetPolygonModeEXT = (PFN_vkCmdSetPolygonModeEXT)gpa(device, "vkCmdSetPolygonModeEXT");
+    table->CmdSetRasterizationSamplesEXT = (PFN_vkCmdSetRasterizationSamplesEXT)gpa(device, "vkCmdSetRasterizationSamplesEXT");
+    table->CmdSetSampleMaskEXT = (PFN_vkCmdSetSampleMaskEXT)gpa(device, "vkCmdSetSampleMaskEXT");
+    table->CmdSetAlphaToCoverageEnableEXT = (PFN_vkCmdSetAlphaToCoverageEnableEXT)gpa(device, "vkCmdSetAlphaToCoverageEnableEXT");
+    table->CmdSetAlphaToOneEnableEXT = (PFN_vkCmdSetAlphaToOneEnableEXT)gpa(device, "vkCmdSetAlphaToOneEnableEXT");
+    table->CmdSetLogicOpEnableEXT = (PFN_vkCmdSetLogicOpEnableEXT)gpa(device, "vkCmdSetLogicOpEnableEXT");
+    table->CmdSetColorBlendEnableEXT = (PFN_vkCmdSetColorBlendEnableEXT)gpa(device, "vkCmdSetColorBlendEnableEXT");
+    table->CmdSetColorBlendEquationEXT = (PFN_vkCmdSetColorBlendEquationEXT)gpa(device, "vkCmdSetColorBlendEquationEXT");
+    table->CmdSetColorWriteMaskEXT = (PFN_vkCmdSetColorWriteMaskEXT)gpa(device, "vkCmdSetColorWriteMaskEXT");
+    table->CmdSetTessellationDomainOriginEXT = (PFN_vkCmdSetTessellationDomainOriginEXT)gpa(device, "vkCmdSetTessellationDomainOriginEXT");
+    table->CmdSetRasterizationStreamEXT = (PFN_vkCmdSetRasterizationStreamEXT)gpa(device, "vkCmdSetRasterizationStreamEXT");
+    table->CmdSetConservativeRasterizationModeEXT = (PFN_vkCmdSetConservativeRasterizationModeEXT)gpa(device, "vkCmdSetConservativeRasterizationModeEXT");
+    table->CmdSetExtraPrimitiveOverestimationSizeEXT = (PFN_vkCmdSetExtraPrimitiveOverestimationSizeEXT)gpa(device, "vkCmdSetExtraPrimitiveOverestimationSizeEXT");
+    table->CmdSetDepthClipEnableEXT = (PFN_vkCmdSetDepthClipEnableEXT)gpa(device, "vkCmdSetDepthClipEnableEXT");
+    table->CmdSetSampleLocationsEnableEXT = (PFN_vkCmdSetSampleLocationsEnableEXT)gpa(device, "vkCmdSetSampleLocationsEnableEXT");
+    table->CmdSetColorBlendAdvancedEXT = (PFN_vkCmdSetColorBlendAdvancedEXT)gpa(device, "vkCmdSetColorBlendAdvancedEXT");
+    table->CmdSetProvokingVertexModeEXT = (PFN_vkCmdSetProvokingVertexModeEXT)gpa(device, "vkCmdSetProvokingVertexModeEXT");
+    table->CmdSetLineRasterizationModeEXT = (PFN_vkCmdSetLineRasterizationModeEXT)gpa(device, "vkCmdSetLineRasterizationModeEXT");
+    table->CmdSetLineStippleEnableEXT = (PFN_vkCmdSetLineStippleEnableEXT)gpa(device, "vkCmdSetLineStippleEnableEXT");
+    table->CmdSetDepthClipNegativeOneToOneEXT = (PFN_vkCmdSetDepthClipNegativeOneToOneEXT)gpa(device, "vkCmdSetDepthClipNegativeOneToOneEXT");
+    table->CmdSetViewportWScalingEnableNV = (PFN_vkCmdSetViewportWScalingEnableNV)gpa(device, "vkCmdSetViewportWScalingEnableNV");
+    table->CmdSetViewportSwizzleNV = (PFN_vkCmdSetViewportSwizzleNV)gpa(device, "vkCmdSetViewportSwizzleNV");
+    table->CmdSetCoverageToColorEnableNV = (PFN_vkCmdSetCoverageToColorEnableNV)gpa(device, "vkCmdSetCoverageToColorEnableNV");
+    table->CmdSetCoverageToColorLocationNV = (PFN_vkCmdSetCoverageToColorLocationNV)gpa(device, "vkCmdSetCoverageToColorLocationNV");
+    table->CmdSetCoverageModulationModeNV = (PFN_vkCmdSetCoverageModulationModeNV)gpa(device, "vkCmdSetCoverageModulationModeNV");
+    table->CmdSetCoverageModulationTableEnableNV = (PFN_vkCmdSetCoverageModulationTableEnableNV)gpa(device, "vkCmdSetCoverageModulationTableEnableNV");
+    table->CmdSetCoverageModulationTableNV = (PFN_vkCmdSetCoverageModulationTableNV)gpa(device, "vkCmdSetCoverageModulationTableNV");
+    table->CmdSetShadingRateImageEnableNV = (PFN_vkCmdSetShadingRateImageEnableNV)gpa(device, "vkCmdSetShadingRateImageEnableNV");
+    table->CmdSetRepresentativeFragmentTestEnableNV = (PFN_vkCmdSetRepresentativeFragmentTestEnableNV)gpa(device, "vkCmdSetRepresentativeFragmentTestEnableNV");
+    table->CmdSetCoverageReductionModeNV = (PFN_vkCmdSetCoverageReductionModeNV)gpa(device, "vkCmdSetCoverageReductionModeNV");
+    table->CreateTensorARM = (PFN_vkCreateTensorARM)gpa(device, "vkCreateTensorARM");
+    table->DestroyTensorARM = (PFN_vkDestroyTensorARM)gpa(device, "vkDestroyTensorARM");
+    table->CreateTensorViewARM = (PFN_vkCreateTensorViewARM)gpa(device, "vkCreateTensorViewARM");
+    table->DestroyTensorViewARM = (PFN_vkDestroyTensorViewARM)gpa(device, "vkDestroyTensorViewARM");
+    table->GetTensorMemoryRequirementsARM = (PFN_vkGetTensorMemoryRequirementsARM)gpa(device, "vkGetTensorMemoryRequirementsARM");
+    table->BindTensorMemoryARM = (PFN_vkBindTensorMemoryARM)gpa(device, "vkBindTensorMemoryARM");
+    table->GetDeviceTensorMemoryRequirementsARM = (PFN_vkGetDeviceTensorMemoryRequirementsARM)gpa(device, "vkGetDeviceTensorMemoryRequirementsARM");
+    table->CmdCopyTensorARM = (PFN_vkCmdCopyTensorARM)gpa(device, "vkCmdCopyTensorARM");
+    table->GetTensorOpaqueCaptureDescriptorDataARM = (PFN_vkGetTensorOpaqueCaptureDescriptorDataARM)gpa(device, "vkGetTensorOpaqueCaptureDescriptorDataARM");
+    table->GetTensorViewOpaqueCaptureDescriptorDataARM = (PFN_vkGetTensorViewOpaqueCaptureDescriptorDataARM)gpa(device, "vkGetTensorViewOpaqueCaptureDescriptorDataARM");
+    table->GetShaderModuleIdentifierEXT = (PFN_vkGetShaderModuleIdentifierEXT)gpa(device, "vkGetShaderModuleIdentifierEXT");
+    table->GetShaderModuleCreateInfoIdentifierEXT = (PFN_vkGetShaderModuleCreateInfoIdentifierEXT)gpa(device, "vkGetShaderModuleCreateInfoIdentifierEXT");
+    table->CreateOpticalFlowSessionNV = (PFN_vkCreateOpticalFlowSessionNV)gpa(device, "vkCreateOpticalFlowSessionNV");
+    table->DestroyOpticalFlowSessionNV = (PFN_vkDestroyOpticalFlowSessionNV)gpa(device, "vkDestroyOpticalFlowSessionNV");
+    table->BindOpticalFlowSessionImageNV = (PFN_vkBindOpticalFlowSessionImageNV)gpa(device, "vkBindOpticalFlowSessionImageNV");
+    table->CmdOpticalFlowExecuteNV = (PFN_vkCmdOpticalFlowExecuteNV)gpa(device, "vkCmdOpticalFlowExecuteNV");
+    table->AntiLagUpdateAMD = (PFN_vkAntiLagUpdateAMD)gpa(device, "vkAntiLagUpdateAMD");
+    table->CreateShadersEXT = (PFN_vkCreateShadersEXT)gpa(device, "vkCreateShadersEXT");
+    table->DestroyShaderEXT = (PFN_vkDestroyShaderEXT)gpa(device, "vkDestroyShaderEXT");
+    table->GetShaderBinaryDataEXT = (PFN_vkGetShaderBinaryDataEXT)gpa(device, "vkGetShaderBinaryDataEXT");
+    table->CmdBindShadersEXT = (PFN_vkCmdBindShadersEXT)gpa(device, "vkCmdBindShadersEXT");
+    table->CmdSetDepthClampRangeEXT = (PFN_vkCmdSetDepthClampRangeEXT)gpa(device, "vkCmdSetDepthClampRangeEXT");
+    table->GetFramebufferTilePropertiesQCOM = (PFN_vkGetFramebufferTilePropertiesQCOM)gpa(device, "vkGetFramebufferTilePropertiesQCOM");
+    table->GetDynamicRenderingTilePropertiesQCOM = (PFN_vkGetDynamicRenderingTilePropertiesQCOM)gpa(device, "vkGetDynamicRenderingTilePropertiesQCOM");
+    table->ConvertCooperativeVectorMatrixNV = (PFN_vkConvertCooperativeVectorMatrixNV)gpa(device, "vkConvertCooperativeVectorMatrixNV");
+    table->CmdConvertCooperativeVectorMatrixNV = (PFN_vkCmdConvertCooperativeVectorMatrixNV)gpa(device, "vkCmdConvertCooperativeVectorMatrixNV");
+    table->SetLatencySleepModeNV = (PFN_vkSetLatencySleepModeNV)gpa(device, "vkSetLatencySleepModeNV");
+    table->LatencySleepNV = (PFN_vkLatencySleepNV)gpa(device, "vkLatencySleepNV");
+    table->SetLatencyMarkerNV = (PFN_vkSetLatencyMarkerNV)gpa(device, "vkSetLatencyMarkerNV");
+    table->GetLatencyTimingsNV = (PFN_vkGetLatencyTimingsNV)gpa(device, "vkGetLatencyTimingsNV");
+    table->QueueNotifyOutOfBandNV = (PFN_vkQueueNotifyOutOfBandNV)gpa(device, "vkQueueNotifyOutOfBandNV");
+    table->CreateDataGraphPipelinesARM = (PFN_vkCreateDataGraphPipelinesARM)gpa(device, "vkCreateDataGraphPipelinesARM");
+    table->CreateDataGraphPipelineSessionARM = (PFN_vkCreateDataGraphPipelineSessionARM)gpa(device, "vkCreateDataGraphPipelineSessionARM");
+    table->GetDataGraphPipelineSessionBindPointRequirementsARM = (PFN_vkGetDataGraphPipelineSessionBindPointRequirementsARM)gpa(device, "vkGetDataGraphPipelineSessionBindPointRequirementsARM");
+    table->GetDataGraphPipelineSessionMemoryRequirementsARM = (PFN_vkGetDataGraphPipelineSessionMemoryRequirementsARM)gpa(device, "vkGetDataGraphPipelineSessionMemoryRequirementsARM");
+    table->BindDataGraphPipelineSessionMemoryARM = (PFN_vkBindDataGraphPipelineSessionMemoryARM)gpa(device, "vkBindDataGraphPipelineSessionMemoryARM");
+    table->DestroyDataGraphPipelineSessionARM = (PFN_vkDestroyDataGraphPipelineSessionARM)gpa(device, "vkDestroyDataGraphPipelineSessionARM");
+    table->CmdDispatchDataGraphARM = (PFN_vkCmdDispatchDataGraphARM)gpa(device, "vkCmdDispatchDataGraphARM");
+    table->GetDataGraphPipelineAvailablePropertiesARM = (PFN_vkGetDataGraphPipelineAvailablePropertiesARM)gpa(device, "vkGetDataGraphPipelineAvailablePropertiesARM");
+    table->GetDataGraphPipelinePropertiesARM = (PFN_vkGetDataGraphPipelinePropertiesARM)gpa(device, "vkGetDataGraphPipelinePropertiesARM");
+    table->CmdSetAttachmentFeedbackLoopEnableEXT = (PFN_vkCmdSetAttachmentFeedbackLoopEnableEXT)gpa(device, "vkCmdSetAttachmentFeedbackLoopEnableEXT");
+#if defined(VK_USE_PLATFORM_SCREEN_QNX)
+    table->GetScreenBufferPropertiesQNX = (PFN_vkGetScreenBufferPropertiesQNX)gpa(device, "vkGetScreenBufferPropertiesQNX");
+#endif  // VK_USE_PLATFORM_SCREEN_QNX
+    table->CmdBindTileMemoryQCOM = (PFN_vkCmdBindTileMemoryQCOM)gpa(device, "vkCmdBindTileMemoryQCOM");
+    table->CmdDecompressMemoryEXT = (PFN_vkCmdDecompressMemoryEXT)gpa(device, "vkCmdDecompressMemoryEXT");
+    table->CmdDecompressMemoryIndirectCountEXT = (PFN_vkCmdDecompressMemoryIndirectCountEXT)gpa(device, "vkCmdDecompressMemoryIndirectCountEXT");
+    table->CreateExternalComputeQueueNV = (PFN_vkCreateExternalComputeQueueNV)gpa(device, "vkCreateExternalComputeQueueNV");
+    table->DestroyExternalComputeQueueNV = (PFN_vkDestroyExternalComputeQueueNV)gpa(device, "vkDestroyExternalComputeQueueNV");
+    table->GetExternalComputeQueueDataNV = (PFN_vkGetExternalComputeQueueDataNV)gpa(device, "vkGetExternalComputeQueueDataNV");
+    table->GetClusterAccelerationStructureBuildSizesNV = (PFN_vkGetClusterAccelerationStructureBuildSizesNV)gpa(device, "vkGetClusterAccelerationStructureBuildSizesNV");
+    table->CmdBuildClusterAccelerationStructureIndirectNV = (PFN_vkCmdBuildClusterAccelerationStructureIndirectNV)gpa(device, "vkCmdBuildClusterAccelerationStructureIndirectNV");
+    table->GetPartitionedAccelerationStructuresBuildSizesNV = (PFN_vkGetPartitionedAccelerationStructuresBuildSizesNV)gpa(device, "vkGetPartitionedAccelerationStructuresBuildSizesNV");
+    table->CmdBuildPartitionedAccelerationStructuresNV = (PFN_vkCmdBuildPartitionedAccelerationStructuresNV)gpa(device, "vkCmdBuildPartitionedAccelerationStructuresNV");
+    table->GetGeneratedCommandsMemoryRequirementsEXT = (PFN_vkGetGeneratedCommandsMemoryRequirementsEXT)gpa(device, "vkGetGeneratedCommandsMemoryRequirementsEXT");
+    table->CmdPreprocessGeneratedCommandsEXT = (PFN_vkCmdPreprocessGeneratedCommandsEXT)gpa(device, "vkCmdPreprocessGeneratedCommandsEXT");
+    table->CmdExecuteGeneratedCommandsEXT = (PFN_vkCmdExecuteGeneratedCommandsEXT)gpa(device, "vkCmdExecuteGeneratedCommandsEXT");
+    table->CreateIndirectCommandsLayoutEXT = (PFN_vkCreateIndirectCommandsLayoutEXT)gpa(device, "vkCreateIndirectCommandsLayoutEXT");
+    table->DestroyIndirectCommandsLayoutEXT = (PFN_vkDestroyIndirectCommandsLayoutEXT)gpa(device, "vkDestroyIndirectCommandsLayoutEXT");
+    table->CreateIndirectExecutionSetEXT = (PFN_vkCreateIndirectExecutionSetEXT)gpa(device, "vkCreateIndirectExecutionSetEXT");
+    table->DestroyIndirectExecutionSetEXT = (PFN_vkDestroyIndirectExecutionSetEXT)gpa(device, "vkDestroyIndirectExecutionSetEXT");
+    table->UpdateIndirectExecutionSetPipelineEXT = (PFN_vkUpdateIndirectExecutionSetPipelineEXT)gpa(device, "vkUpdateIndirectExecutionSetPipelineEXT");
+    table->UpdateIndirectExecutionSetShaderEXT = (PFN_vkUpdateIndirectExecutionSetShaderEXT)gpa(device, "vkUpdateIndirectExecutionSetShaderEXT");
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    table->GetMemoryMetalHandleEXT = (PFN_vkGetMemoryMetalHandleEXT)gpa(device, "vkGetMemoryMetalHandleEXT");
+#endif  // VK_USE_PLATFORM_METAL_EXT
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    table->GetMemoryMetalHandlePropertiesEXT = (PFN_vkGetMemoryMetalHandlePropertiesEXT)gpa(device, "vkGetMemoryMetalHandlePropertiesEXT");
+#endif  // VK_USE_PLATFORM_METAL_EXT
+    table->CreateShaderInstrumentationARM = (PFN_vkCreateShaderInstrumentationARM)gpa(device, "vkCreateShaderInstrumentationARM");
+    table->DestroyShaderInstrumentationARM = (PFN_vkDestroyShaderInstrumentationARM)gpa(device, "vkDestroyShaderInstrumentationARM");
+    table->CmdBeginShaderInstrumentationARM = (PFN_vkCmdBeginShaderInstrumentationARM)gpa(device, "vkCmdBeginShaderInstrumentationARM");
+    table->CmdEndShaderInstrumentationARM = (PFN_vkCmdEndShaderInstrumentationARM)gpa(device, "vkCmdEndShaderInstrumentationARM");
+    table->GetShaderInstrumentationValuesARM = (PFN_vkGetShaderInstrumentationValuesARM)gpa(device, "vkGetShaderInstrumentationValuesARM");
+    table->ClearShaderInstrumentationMetricsARM = (PFN_vkClearShaderInstrumentationMetricsARM)gpa(device, "vkClearShaderInstrumentationMetricsARM");
+    table->CmdEndRendering2EXT = (PFN_vkCmdEndRendering2EXT)gpa(device, "vkCmdEndRendering2EXT");
+    table->CmdBeginCustomResolveEXT = (PFN_vkCmdBeginCustomResolveEXT)gpa(device, "vkCmdBeginCustomResolveEXT");
+    table->CmdSetComputeOccupancyPriorityNV = (PFN_vkCmdSetComputeOccupancyPriorityNV)gpa(device, "vkCmdSetComputeOccupancyPriorityNV");
+    table->CmdSetPrimitiveRestartIndexEXT = (PFN_vkCmdSetPrimitiveRestartIndexEXT)gpa(device, "vkCmdSetPrimitiveRestartIndexEXT");
+    table->CreateAccelerationStructureKHR = (PFN_vkCreateAccelerationStructureKHR)gpa(device, "vkCreateAccelerationStructureKHR");
+    table->DestroyAccelerationStructureKHR = (PFN_vkDestroyAccelerationStructureKHR)gpa(device, "vkDestroyAccelerationStructureKHR");
+    table->CmdBuildAccelerationStructuresKHR = (PFN_vkCmdBuildAccelerationStructuresKHR)gpa(device, "vkCmdBuildAccelerationStructuresKHR");
+    table->CmdBuildAccelerationStructuresIndirectKHR = (PFN_vkCmdBuildAccelerationStructuresIndirectKHR)gpa(device, "vkCmdBuildAccelerationStructuresIndirectKHR");
+    table->BuildAccelerationStructuresKHR = (PFN_vkBuildAccelerationStructuresKHR)gpa(device, "vkBuildAccelerationStructuresKHR");
+    table->CopyAccelerationStructureKHR = (PFN_vkCopyAccelerationStructureKHR)gpa(device, "vkCopyAccelerationStructureKHR");
+    table->CopyAccelerationStructureToMemoryKHR = (PFN_vkCopyAccelerationStructureToMemoryKHR)gpa(device, "vkCopyAccelerationStructureToMemoryKHR");
+    table->CopyMemoryToAccelerationStructureKHR = (PFN_vkCopyMemoryToAccelerationStructureKHR)gpa(device, "vkCopyMemoryToAccelerationStructureKHR");
+    table->WriteAccelerationStructuresPropertiesKHR = (PFN_vkWriteAccelerationStructuresPropertiesKHR)gpa(device, "vkWriteAccelerationStructuresPropertiesKHR");
+    table->CmdCopyAccelerationStructureKHR = (PFN_vkCmdCopyAccelerationStructureKHR)gpa(device, "vkCmdCopyAccelerationStructureKHR");
+    table->CmdCopyAccelerationStructureToMemoryKHR = (PFN_vkCmdCopyAccelerationStructureToMemoryKHR)gpa(device, "vkCmdCopyAccelerationStructureToMemoryKHR");
+    table->CmdCopyMemoryToAccelerationStructureKHR = (PFN_vkCmdCopyMemoryToAccelerationStructureKHR)gpa(device, "vkCmdCopyMemoryToAccelerationStructureKHR");
+    table->GetAccelerationStructureDeviceAddressKHR = (PFN_vkGetAccelerationStructureDeviceAddressKHR)gpa(device, "vkGetAccelerationStructureDeviceAddressKHR");
+    table->CmdWriteAccelerationStructuresPropertiesKHR = (PFN_vkCmdWriteAccelerationStructuresPropertiesKHR)gpa(device, "vkCmdWriteAccelerationStructuresPropertiesKHR");
+    table->GetDeviceAccelerationStructureCompatibilityKHR = (PFN_vkGetDeviceAccelerationStructureCompatibilityKHR)gpa(device, "vkGetDeviceAccelerationStructureCompatibilityKHR");
+    table->GetAccelerationStructureBuildSizesKHR = (PFN_vkGetAccelerationStructureBuildSizesKHR)gpa(device, "vkGetAccelerationStructureBuildSizesKHR");
+    table->CmdTraceRaysKHR = (PFN_vkCmdTraceRaysKHR)gpa(device, "vkCmdTraceRaysKHR");
+    table->CreateRayTracingPipelinesKHR = (PFN_vkCreateRayTracingPipelinesKHR)gpa(device, "vkCreateRayTracingPipelinesKHR");
+    table->GetRayTracingCaptureReplayShaderGroupHandlesKHR = (PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR)gpa(device, "vkGetRayTracingCaptureReplayShaderGroupHandlesKHR");
+    table->CmdTraceRaysIndirectKHR = (PFN_vkCmdTraceRaysIndirectKHR)gpa(device, "vkCmdTraceRaysIndirectKHR");
+    table->GetRayTracingShaderGroupStackSizeKHR = (PFN_vkGetRayTracingShaderGroupStackSizeKHR)gpa(device, "vkGetRayTracingShaderGroupStackSizeKHR");
+    table->CmdSetRayTracingPipelineStackSizeKHR = (PFN_vkCmdSetRayTracingPipelineStackSizeKHR)gpa(device, "vkCmdSetRayTracingPipelineStackSizeKHR");
+    table->CmdDrawMeshTasksEXT = (PFN_vkCmdDrawMeshTasksEXT)gpa(device, "vkCmdDrawMeshTasksEXT");
+    table->CmdDrawMeshTasksIndirectEXT = (PFN_vkCmdDrawMeshTasksIndirectEXT)gpa(device, "vkCmdDrawMeshTasksIndirectEXT");
+    table->CmdDrawMeshTasksIndirectCountEXT = (PFN_vkCmdDrawMeshTasksIndirectCountEXT)gpa(device, "vkCmdDrawMeshTasksIndirectCountEXT");
+    // clang-format on
+}
+
+// clang-format off
+static inline void layer_init_instance_dispatch_table(VkInstance instance, VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa) {
+    memset(table, 0, sizeof(*table));
+
+    // Instance function pointers
+    table->CreateInstance = (PFN_vkCreateInstance)gpa(instance, "vkCreateInstance");
+    table->DestroyInstance = (PFN_vkDestroyInstance)gpa(instance, "vkDestroyInstance");
+    table->EnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices)gpa(instance, "vkEnumeratePhysicalDevices");
+    table->GetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures)gpa(instance, "vkGetPhysicalDeviceFeatures");
+    table->GetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties)gpa(instance, "vkGetPhysicalDeviceFormatProperties");
+    table->GetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties)gpa(instance, "vkGetPhysicalDeviceImageFormatProperties");
+    table->GetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)gpa(instance, "vkGetPhysicalDeviceProperties");
+    table->GetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties)gpa(instance, "vkGetPhysicalDeviceQueueFamilyProperties");
+    table->GetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties)gpa(instance, "vkGetPhysicalDeviceMemoryProperties");
+    table->GetInstanceProcAddr = gpa;
+    table->CreateDevice = (PFN_vkCreateDevice)gpa(instance, "vkCreateDevice");
+    table->EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)gpa(instance, "vkEnumerateInstanceExtensionProperties");
+    table->EnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties)gpa(instance, "vkEnumerateDeviceExtensionProperties");
+    table->EnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties)gpa(instance, "vkEnumerateInstanceLayerProperties");
+    table->EnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties)gpa(instance, "vkEnumerateDeviceLayerProperties");
+    table->GetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties)gpa(instance, "vkGetPhysicalDeviceSparseImageFormatProperties");
+    table->EnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion)gpa(instance, "vkEnumerateInstanceVersion");
+    table->EnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups)gpa(instance, "vkEnumeratePhysicalDeviceGroups");
+    table->GetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2)gpa(instance, "vkGetPhysicalDeviceFeatures2");
+    table->GetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2)gpa(instance, "vkGetPhysicalDeviceProperties2");
+    table->GetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2)gpa(instance, "vkGetPhysicalDeviceFormatProperties2");
+    table->GetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2)gpa(instance, "vkGetPhysicalDeviceImageFormatProperties2");
+    table->GetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2)gpa(instance, "vkGetPhysicalDeviceQueueFamilyProperties2");
+    table->GetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2)gpa(instance, "vkGetPhysicalDeviceMemoryProperties2");
+    table->GetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)gpa(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2");
+    table->GetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties)gpa(instance, "vkGetPhysicalDeviceExternalBufferProperties");
+    table->GetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties)gpa(instance, "vkGetPhysicalDeviceExternalFenceProperties");
+    table->GetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)gpa(instance, "vkGetPhysicalDeviceExternalSemaphoreProperties");
+    table->GetPhysicalDeviceToolProperties = (PFN_vkGetPhysicalDeviceToolProperties)gpa(instance, "vkGetPhysicalDeviceToolProperties");
+    table->DestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)gpa(instance, "vkDestroySurfaceKHR");
+    table->GetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
+    table->GetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
+    table->GetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
+    table->GetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
+    table->GetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR)gpa(instance, "vkGetPhysicalDevicePresentRectanglesKHR");
+    table->GetPhysicalDeviceDisplayPropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)gpa(instance, "vkGetPhysicalDeviceDisplayPropertiesKHR");
+    table->GetPhysicalDeviceDisplayPlanePropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)gpa(instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
+    table->GetDisplayPlaneSupportedDisplaysKHR = (PFN_vkGetDisplayPlaneSupportedDisplaysKHR)gpa(instance, "vkGetDisplayPlaneSupportedDisplaysKHR");
+    table->GetDisplayModePropertiesKHR = (PFN_vkGetDisplayModePropertiesKHR)gpa(instance, "vkGetDisplayModePropertiesKHR");
+    table->CreateDisplayModeKHR = (PFN_vkCreateDisplayModeKHR)gpa(instance, "vkCreateDisplayModeKHR");
+    table->GetDisplayPlaneCapabilitiesKHR = (PFN_vkGetDisplayPlaneCapabilitiesKHR)gpa(instance, "vkGetDisplayPlaneCapabilitiesKHR");
+    table->CreateDisplayPlaneSurfaceKHR = (PFN_vkCreateDisplayPlaneSurfaceKHR)gpa(instance, "vkCreateDisplayPlaneSurfaceKHR");
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+    table->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)gpa(instance, "vkCreateXlibSurfaceKHR");
+#endif  // VK_USE_PLATFORM_XLIB_KHR
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+    table->GetPhysicalDeviceXlibPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
+#endif  // VK_USE_PLATFORM_XLIB_KHR
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+    table->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)gpa(instance, "vkCreateXcbSurfaceKHR");
+#endif  // VK_USE_PLATFORM_XCB_KHR
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+    table->GetPhysicalDeviceXcbPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
+#endif  // VK_USE_PLATFORM_XCB_KHR
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    table->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)gpa(instance, "vkCreateWaylandSurfaceKHR");
+#endif  // VK_USE_PLATFORM_WAYLAND_KHR
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    table->GetPhysicalDeviceWaylandPresentationSupportKHR = (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
+#endif  // VK_USE_PLATFORM_WAYLAND_KHR
+#if defined(VK_USE_PLATFORM_ANDROID_KHR)
+    table->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)gpa(instance, "vkCreateAndroidSurfaceKHR");
+#endif  // VK_USE_PLATFORM_ANDROID_KHR
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)gpa(instance, "vkCreateWin32SurfaceKHR");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->GetPhysicalDeviceWin32PresentationSupportKHR = (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+    table->GetPhysicalDeviceVideoCapabilitiesKHR = (PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR)gpa(instance, "vkGetPhysicalDeviceVideoCapabilitiesKHR");
+    table->GetPhysicalDeviceVideoFormatPropertiesKHR = (PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR)gpa(instance, "vkGetPhysicalDeviceVideoFormatPropertiesKHR");
+    table->GetPhysicalDeviceFeatures2KHR = (PFN_vkGetPhysicalDeviceFeatures2KHR)gpa(instance, "vkGetPhysicalDeviceFeatures2KHR");
+    table->GetPhysicalDeviceProperties2KHR = (PFN_vkGetPhysicalDeviceProperties2KHR)gpa(instance, "vkGetPhysicalDeviceProperties2KHR");
+    table->GetPhysicalDeviceFormatProperties2KHR = (PFN_vkGetPhysicalDeviceFormatProperties2KHR)gpa(instance, "vkGetPhysicalDeviceFormatProperties2KHR");
+    table->GetPhysicalDeviceImageFormatProperties2KHR = (PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)gpa(instance, "vkGetPhysicalDeviceImageFormatProperties2KHR");
+    table->GetPhysicalDeviceQueueFamilyProperties2KHR = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)gpa(instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR");
+    table->GetPhysicalDeviceMemoryProperties2KHR = (PFN_vkGetPhysicalDeviceMemoryProperties2KHR)gpa(instance, "vkGetPhysicalDeviceMemoryProperties2KHR");
+    table->GetPhysicalDeviceSparseImageFormatProperties2KHR = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)gpa(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR");
+    table->EnumeratePhysicalDeviceGroupsKHR = (PFN_vkEnumeratePhysicalDeviceGroupsKHR)gpa(instance, "vkEnumeratePhysicalDeviceGroupsKHR");
+    table->GetPhysicalDeviceExternalBufferPropertiesKHR = (PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)gpa(instance, "vkGetPhysicalDeviceExternalBufferPropertiesKHR");
+    table->GetPhysicalDeviceExternalSemaphorePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)gpa(instance, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
+    table->GetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)gpa(instance, "vkGetPhysicalDeviceExternalFencePropertiesKHR");
+    table->EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR = (PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)gpa(instance, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
+    table->GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR = (PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR)gpa(instance, "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR");
+    table->GetPhysicalDeviceSurfaceCapabilities2KHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilities2KHR");
+    table->GetPhysicalDeviceSurfaceFormats2KHR = (PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)gpa(instance, "vkGetPhysicalDeviceSurfaceFormats2KHR");
+    table->GetPhysicalDeviceDisplayProperties2KHR = (PFN_vkGetPhysicalDeviceDisplayProperties2KHR)gpa(instance, "vkGetPhysicalDeviceDisplayProperties2KHR");
+    table->GetPhysicalDeviceDisplayPlaneProperties2KHR = (PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR)gpa(instance, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR");
+    table->GetDisplayModeProperties2KHR = (PFN_vkGetDisplayModeProperties2KHR)gpa(instance, "vkGetDisplayModeProperties2KHR");
+    table->GetDisplayPlaneCapabilities2KHR = (PFN_vkGetDisplayPlaneCapabilities2KHR)gpa(instance, "vkGetDisplayPlaneCapabilities2KHR");
+    table->GetPhysicalDeviceFragmentShadingRatesKHR = (PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR)gpa(instance, "vkGetPhysicalDeviceFragmentShadingRatesKHR");
+    table->GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR = (PFN_vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR)gpa(instance, "vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR");
+    table->GetPhysicalDeviceCooperativeMatrixPropertiesKHR = (PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR)gpa(instance, "vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR");
+    table->GetPhysicalDeviceCalibrateableTimeDomainsKHR = (PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsKHR)gpa(instance, "vkGetPhysicalDeviceCalibrateableTimeDomainsKHR");
+    table->CreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)gpa(instance, "vkCreateDebugReportCallbackEXT");
+    table->DestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)gpa(instance, "vkDestroyDebugReportCallbackEXT");
+    table->DebugReportMessageEXT = (PFN_vkDebugReportMessageEXT)gpa(instance, "vkDebugReportMessageEXT");
+#if defined(VK_USE_PLATFORM_GGP)
+    table->CreateStreamDescriptorSurfaceGGP = (PFN_vkCreateStreamDescriptorSurfaceGGP)gpa(instance, "vkCreateStreamDescriptorSurfaceGGP");
+#endif  // VK_USE_PLATFORM_GGP
+    table->GetPhysicalDeviceExternalImageFormatPropertiesNV = (PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV)gpa(instance, "vkGetPhysicalDeviceExternalImageFormatPropertiesNV");
+#if defined(VK_USE_PLATFORM_VI_NN)
+    table->CreateViSurfaceNN = (PFN_vkCreateViSurfaceNN)gpa(instance, "vkCreateViSurfaceNN");
+#endif  // VK_USE_PLATFORM_VI_NN
+    table->ReleaseDisplayEXT = (PFN_vkReleaseDisplayEXT)gpa(instance, "vkReleaseDisplayEXT");
+#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
+    table->AcquireXlibDisplayEXT = (PFN_vkAcquireXlibDisplayEXT)gpa(instance, "vkAcquireXlibDisplayEXT");
+#endif  // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
+    table->GetRandROutputDisplayEXT = (PFN_vkGetRandROutputDisplayEXT)gpa(instance, "vkGetRandROutputDisplayEXT");
+#endif  // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+    table->GetPhysicalDeviceSurfaceCapabilities2EXT = (PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilities2EXT");
+#if defined(VK_USE_PLATFORM_IOS_MVK)
+    table->CreateIOSSurfaceMVK = (PFN_vkCreateIOSSurfaceMVK)gpa(instance, "vkCreateIOSSurfaceMVK");
+#endif  // VK_USE_PLATFORM_IOS_MVK
+#if defined(VK_USE_PLATFORM_MACOS_MVK)
+    table->CreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)gpa(instance, "vkCreateMacOSSurfaceMVK");
+#endif  // VK_USE_PLATFORM_MACOS_MVK
+    table->CreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT)gpa(instance, "vkCreateDebugUtilsMessengerEXT");
+    table->DestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT)gpa(instance, "vkDestroyDebugUtilsMessengerEXT");
+    table->SubmitDebugUtilsMessageEXT = (PFN_vkSubmitDebugUtilsMessageEXT)gpa(instance, "vkSubmitDebugUtilsMessageEXT");
+    table->GetPhysicalDeviceDescriptorSizeEXT = (PFN_vkGetPhysicalDeviceDescriptorSizeEXT)gpa(instance, "vkGetPhysicalDeviceDescriptorSizeEXT");
+    table->GetPhysicalDeviceMultisamplePropertiesEXT = (PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT)gpa(instance, "vkGetPhysicalDeviceMultisamplePropertiesEXT");
+    table->GetPhysicalDeviceCalibrateableTimeDomainsEXT = (PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)gpa(instance, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT");
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    table->CreateImagePipeSurfaceFUCHSIA = (PFN_vkCreateImagePipeSurfaceFUCHSIA)gpa(instance, "vkCreateImagePipeSurfaceFUCHSIA");
+#endif  // VK_USE_PLATFORM_FUCHSIA
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    table->CreateMetalSurfaceEXT = (PFN_vkCreateMetalSurfaceEXT)gpa(instance, "vkCreateMetalSurfaceEXT");
+#endif  // VK_USE_PLATFORM_METAL_EXT
+    table->GetPhysicalDeviceToolPropertiesEXT = (PFN_vkGetPhysicalDeviceToolPropertiesEXT)gpa(instance, "vkGetPhysicalDeviceToolPropertiesEXT");
+    table->GetPhysicalDeviceCooperativeMatrixPropertiesNV = (PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV)gpa(instance, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV");
+    table->GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV = (PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV)gpa(instance, "vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV");
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->GetPhysicalDeviceSurfacePresentModes2EXT = (PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT)gpa(instance, "vkGetPhysicalDeviceSurfacePresentModes2EXT");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+    table->CreateHeadlessSurfaceEXT = (PFN_vkCreateHeadlessSurfaceEXT)gpa(instance, "vkCreateHeadlessSurfaceEXT");
+    table->AcquireDrmDisplayEXT = (PFN_vkAcquireDrmDisplayEXT)gpa(instance, "vkAcquireDrmDisplayEXT");
+    table->GetDrmDisplayEXT = (PFN_vkGetDrmDisplayEXT)gpa(instance, "vkGetDrmDisplayEXT");
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->AcquireWinrtDisplayNV = (PFN_vkAcquireWinrtDisplayNV)gpa(instance, "vkAcquireWinrtDisplayNV");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    table->GetWinrtDisplayNV = (PFN_vkGetWinrtDisplayNV)gpa(instance, "vkGetWinrtDisplayNV");
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    table->CreateDirectFBSurfaceEXT = (PFN_vkCreateDirectFBSurfaceEXT)gpa(instance, "vkCreateDirectFBSurfaceEXT");
+#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    table->GetPhysicalDeviceDirectFBPresentationSupportEXT = (PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT)gpa(instance, "vkGetPhysicalDeviceDirectFBPresentationSupportEXT");
+#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
+#if defined(VK_USE_PLATFORM_SCREEN_QNX)
+    table->CreateScreenSurfaceQNX = (PFN_vkCreateScreenSurfaceQNX)gpa(instance, "vkCreateScreenSurfaceQNX");
+#endif  // VK_USE_PLATFORM_SCREEN_QNX
+#if defined(VK_USE_PLATFORM_SCREEN_QNX)
+    table->GetPhysicalDeviceScreenPresentationSupportQNX = (PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX)gpa(instance, "vkGetPhysicalDeviceScreenPresentationSupportQNX");
+#endif  // VK_USE_PLATFORM_SCREEN_QNX
+    table->GetPhysicalDeviceExternalTensorPropertiesARM = (PFN_vkGetPhysicalDeviceExternalTensorPropertiesARM)gpa(instance, "vkGetPhysicalDeviceExternalTensorPropertiesARM");
+    table->GetPhysicalDeviceOpticalFlowImageFormatsNV = (PFN_vkGetPhysicalDeviceOpticalFlowImageFormatsNV)gpa(instance, "vkGetPhysicalDeviceOpticalFlowImageFormatsNV");
+    table->GetPhysicalDeviceCooperativeVectorPropertiesNV = (PFN_vkGetPhysicalDeviceCooperativeVectorPropertiesNV)gpa(instance, "vkGetPhysicalDeviceCooperativeVectorPropertiesNV");
+    table->GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM = (PFN_vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM)gpa(instance, "vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM");
+    table->GetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM = (PFN_vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM)gpa(instance, "vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM");
+    table->GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM = (PFN_vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM)gpa(instance, "vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM");
+#if defined(VK_USE_PLATFORM_OHOS)
+    table->CreateSurfaceOHOS = (PFN_vkCreateSurfaceOHOS)gpa(instance, "vkCreateSurfaceOHOS");
+#endif  // VK_USE_PLATFORM_OHOS
+    table->GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV = (PFN_vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV)gpa(instance, "vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV");
+    table->EnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM = (PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM)gpa(instance, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceCountersByRegionARM");
+    table->EnumeratePhysicalDeviceShaderInstrumentationMetricsARM = (PFN_vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM)gpa(instance, "vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM");
+    table->GetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM = (PFN_vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM)gpa(instance, "vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM");
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    table->CreateUbmSurfaceSEC = (PFN_vkCreateUbmSurfaceSEC)gpa(instance, "vkCreateUbmSurfaceSEC");
+#endif  // VK_USE_PLATFORM_UBM_SEC
+#if defined(VK_USE_PLATFORM_UBM_SEC)
+    table->GetPhysicalDeviceUbmPresentationSupportSEC = (PFN_vkGetPhysicalDeviceUbmPresentationSupportSEC)gpa(instance, "vkGetPhysicalDeviceUbmPresentationSupportSEC");
+#endif  // VK_USE_PLATFORM_UBM_SEC
+    // clang-format on
+}
diff --git a/tests/framework/layer/layer_util.h b/tests/framework/layer/layer_util.h
index 549bfa7..7107b46 100644
--- a/tests/framework/layer/layer_util.h
+++ b/tests/framework/layer/layer_util.h
@@ -27,21 +27,23 @@
 
 #pragma once
 
-#include "test_util.h"
+#include "builder_defines.h"
+
+#include "vulkan_object_wrappers.h"
 
 struct LayerDefinition {
-    BUILDER_VALUE(LayerDefinition, std::string, layerName, {})
-    BUILDER_VALUE(LayerDefinition, uint32_t, specVersion, VK_API_VERSION_1_0)
-    BUILDER_VALUE(LayerDefinition, uint32_t, implementationVersion, VK_API_VERSION_1_0)
-    BUILDER_VALUE(LayerDefinition, std::string, description, {})
-    BUILDER_VECTOR(LayerDefinition, Extension, extensions, extension)
+    BUILDER_VALUE(std::string, layerName)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, specVersion, VK_API_VERSION_1_0)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, implementationVersion, VK_API_VERSION_1_0)
+    BUILDER_VALUE(std::string, description)
+    BUILDER_VECTOR(Extension, extensions, extension)
 
     VkLayerProperties get() const noexcept {
         VkLayerProperties props{};
-        copy_string_to_char_array(layerName, &props.layerName[0], VK_MAX_EXTENSION_NAME_SIZE);
+        layerName.copy(props.layerName, VK_MAX_EXTENSION_NAME_SIZE);
         props.specVersion = specVersion;
         props.implementationVersion = implementationVersion;
-        copy_string_to_char_array(description, &props.description[0], VK_MAX_DESCRIPTION_SIZE);
+        description.copy(props.description, VK_MAX_DESCRIPTION_SIZE);
         return props;
     }
 };
diff --git a/tests/framework/layer/test_layer.cpp b/tests/framework/layer/test_layer.cpp
index 93c27c7..b98f543 100644
--- a/tests/framework/layer/test_layer.cpp
+++ b/tests/framework/layer/test_layer.cpp
@@ -27,7 +27,14 @@
 
 #include "test_layer.h"
 
-#include "vk_dispatch_table_helper.h"
+#include <assert.h>
+
+#include <vulkan/vk_layer.h>
+
+#include "util/test_defines.h"
+#include "util/equality_helpers.h"
+
+#include "generated/vk_dispatch_table_helper.h"
 
 // export the enumeration functions instance|device+layer|extension
 #if !defined(TEST_LAYER_EXPORT_ENUMERATE_FUNCTIONS)
@@ -243,7 +250,7 @@
     VkLayerInstanceCreateInfo* chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
 
     PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
-    PFN_vk_icdGetPhysicalDeviceProcAddr fpGetPhysicalDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetPhysicalDeviceProcAddr;
+    PFN_GetPhysicalDeviceProcAddr fpGetPhysicalDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetPhysicalDeviceProcAddr;
     PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
     if (fpCreateInstance == NULL) {
         return VK_ERROR_INITIALIZATION_FAILED;
diff --git a/tests/framework/layer/test_layer.h b/tests/framework/layer/test_layer.h
index b4ae37a..085be61 100644
--- a/tests/framework/layer/test_layer.h
+++ b/tests/framework/layer/test_layer.h
@@ -27,14 +27,18 @@
 
 #pragma once
 
-#include "test_util.h"
-
 #include <functional>
+#include <filesystem>
 
-#include "layer/layer_util.h"
+#include <vulkan/vulkan_core.h>
+#include <vulkan/vk_layer.h>
 
 #include "loader/generated/vk_layer_dispatch_table.h"
 
+#include "util/functions.h"
+
+#include "layer_util.h"
+
 /*
 Interface Version 0
 */
@@ -94,58 +98,57 @@
     std::filesystem::path manifest_file_path;
     uint32_t manifest_version = VK_MAKE_API_VERSION(0, 1, 1, 2);
 
-    BUILDER_VALUE(TestLayer, bool, is_meta_layer, false)
+    BUILDER_VALUE(bool, is_meta_layer)
 
-    BUILDER_VALUE(TestLayer, uint32_t, api_version, VK_API_VERSION_1_0)
-    BUILDER_VALUE(TestLayer, uint32_t, reported_layer_props, 1)
-    BUILDER_VALUE(TestLayer, uint32_t, reported_extension_props, 0)
-    BUILDER_VALUE(TestLayer, uint32_t, reported_instance_version, VK_API_VERSION_1_0)
-    BUILDER_VALUE(TestLayer, uint32_t, implementation_version, 2)
-    BUILDER_VALUE(TestLayer, uint32_t, min_implementation_version, 0)
-    BUILDER_VALUE(TestLayer, std::string, description, {})
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, api_version, VK_API_VERSION_1_0)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, reported_layer_props, 1)
+    BUILDER_VALUE(uint32_t, reported_extension_props)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, reported_instance_version, VK_API_VERSION_1_0)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, implementation_version, 2)
+    BUILDER_VALUE(uint32_t, min_implementation_version)
+    BUILDER_VALUE(std::string, description)
 
     // Some layers may try to change the API version during instance creation - we should allow testing of such behavior
-    BUILDER_VALUE(TestLayer, uint32_t, alter_api_version, VK_API_VERSION_1_0)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, alter_api_version, VK_API_VERSION_1_0)
 
-    BUILDER_VECTOR(TestLayer, std::string, alternative_function_names, alternative_function_name)
+    BUILDER_VECTOR(std::string, alternative_function_names, alternative_function_name)
 
-    BUILDER_VECTOR(TestLayer, Extension, instance_extensions, instance_extension)
+    BUILDER_VECTOR(Extension, instance_extensions, instance_extension)
     std::vector<Extension> enabled_instance_extensions;
 
-    BUILDER_VECTOR(TestLayer, Extension, device_extensions, device_extension)
+    BUILDER_VECTOR(Extension, device_extensions, device_extension)
 
-    BUILDER_VALUE(TestLayer, std::string, enable_environment, {});
-    BUILDER_VALUE(TestLayer, std::string, disable_environment, {});
+    BUILDER_VALUE(std::string, enable_environment);
+    BUILDER_VALUE(std::string, disable_environment);
 
     // Modifies the extension list returned by vkEnumerateInstanceExtensionProperties to include what is in this vector
-    BUILDER_VECTOR(TestLayer, Extension, injected_instance_extensions, injected_instance_extension)
+    BUILDER_VECTOR(Extension, injected_instance_extensions, injected_instance_extension)
     // Modifies the extension list returned by  vkEnumerateDeviceExtensionProperties to include what is in this vector
-    BUILDER_VECTOR(TestLayer, Extension, injected_device_extensions, injected_device_extension)
+    BUILDER_VECTOR(Extension, injected_device_extensions, injected_device_extension)
 
-    BUILDER_VECTOR(TestLayer, LayerDefinition, meta_component_layers, meta_component_layer);
+    BUILDER_VECTOR(LayerDefinition, meta_component_layers, meta_component_layer);
 
-    BUILDER_VALUE(TestLayer, bool, intercept_vkEnumerateInstanceExtensionProperties, false)
-    BUILDER_VALUE(TestLayer, bool, intercept_vkEnumerateInstanceLayerProperties, false)
+    BUILDER_VALUE(bool, intercept_vkEnumerateInstanceExtensionProperties)
+    BUILDER_VALUE(bool, intercept_vkEnumerateInstanceLayerProperties)
     // Called in vkCreateInstance after calling down the chain & returning
-    BUILDER_VALUE(TestLayer, std::function<VkResult(TestLayer& layer)>, create_instance_callback, {})
+    BUILDER_VALUE(std::function<VkResult(TestLayer& layer)>, create_instance_callback)
     // Called in vkCreateDevice after calling down the chain & returning
-    BUILDER_VALUE(TestLayer, std::function<VkResult(TestLayer& layer)>, create_device_callback, {})
+    BUILDER_VALUE(std::function<VkResult(TestLayer& layer)>, create_device_callback)
 
     // Physical device modifier test flags and members.  This data is primarily used to test adding, removing and
     // re-ordering physical device data in a layer.
-    BUILDER_VALUE(TestLayer, bool, add_phys_devs, false)
-    BUILDER_VALUE(TestLayer, bool, remove_phys_devs, false)
-    BUILDER_VALUE(TestLayer, bool, reorder_phys_devs, false)
-    BUILDER_VECTOR(TestLayer, VkPhysicalDevice, complete_physical_devices, complete_physical_device)
-    BUILDER_VECTOR(TestLayer, VkPhysicalDevice, removed_physical_devices, removed_physical_device)
-    BUILDER_VECTOR(TestLayer, VkPhysicalDevice, added_physical_devices, added_physical_device)
-    BUILDER_VECTOR(TestLayer, VkPhysicalDeviceGroupProperties, complete_physical_device_groups, complete_physical_device_group)
-    BUILDER_VECTOR(TestLayer, VkPhysicalDeviceGroupProperties, removed_physical_device_groups, removed_physical_device_group)
-    BUILDER_VECTOR(TestLayer, VkPhysicalDeviceGroupProperties, added_physical_device_groups, added_physical_device_group)
+    BUILDER_VALUE(bool, add_phys_devs)
+    BUILDER_VALUE(bool, remove_phys_devs)
+    BUILDER_VALUE(bool, reorder_phys_devs)
+    BUILDER_VECTOR(VkPhysicalDevice, complete_physical_devices, complete_physical_device)
+    BUILDER_VECTOR(VkPhysicalDevice, removed_physical_devices, removed_physical_device)
+    BUILDER_VECTOR(VkPhysicalDevice, added_physical_devices, added_physical_device)
+    BUILDER_VECTOR(VkPhysicalDeviceGroupProperties, complete_physical_device_groups, complete_physical_device_group)
+    BUILDER_VECTOR(VkPhysicalDeviceGroupProperties, removed_physical_device_groups, removed_physical_device_group)
+    BUILDER_VECTOR(VkPhysicalDeviceGroupProperties, added_physical_device_groups, added_physical_device_group)
 
-    BUILDER_VECTOR(TestLayer, VulkanFunction, custom_physical_device_implementation_functions,
-                   custom_physical_device_implementation_function)
-    BUILDER_VECTOR(TestLayer, VulkanFunction, custom_device_implementation_functions, custom_device_implementation_function)
+    BUILDER_VECTOR(VulkanFunction, custom_physical_device_implementation_functions, custom_physical_device_implementation_function)
+    BUILDER_VECTOR(VulkanFunction, custom_device_implementation_functions, custom_device_implementation_function)
 
     // Only need a single map for all 'custom' function - assumes that all function names are distinct, IE there cannot be a
     // physical device and device level function with the same name
@@ -170,10 +173,10 @@
     }
 
     // Allows distinguishing different layers (that use the same binary)
-    BUILDER_VALUE(TestLayer, std::string, make_spurious_log_in_create_instance, "")
-    BUILDER_VALUE(TestLayer, bool, do_spurious_allocations_in_create_instance, false)
+    BUILDER_VALUE(std::string, make_spurious_log_in_create_instance)
+    BUILDER_VALUE(bool, do_spurious_allocations_in_create_instance)
     void* spurious_instance_memory_allocation = nullptr;
-    BUILDER_VALUE(TestLayer, bool, do_spurious_allocations_in_create_device, false)
+    BUILDER_VALUE(bool, do_spurious_allocations_in_create_device)
     struct DeviceMemAlloc {
         void* allocation;
         VkDevice device;
@@ -181,25 +184,25 @@
     std::vector<DeviceMemAlloc> spurious_device_memory_allocations;
 
     // By default query GPDPA from GIPA, don't use value given from pNext
-    BUILDER_VALUE(TestLayer, bool, use_gipa_GetPhysicalDeviceProcAddr, true)
+    BUILDER_VALUE_WITH_DEFAULT(bool, use_gipa_GetPhysicalDeviceProcAddr, true)
 
     // Have a layer query for vkCreateDevice with a NULL instance handle
-    BUILDER_VALUE(TestLayer, bool, buggy_query_of_vkCreateDevice, false)
+    BUILDER_VALUE(bool, buggy_query_of_vkCreateDevice)
 
     // Makes the layer try to create a device using the loader provided function in the layer chain
-    BUILDER_VALUE(TestLayer, bool, call_create_device_while_create_device_is_called, false)
-    BUILDER_VALUE(TestLayer, uint32_t, physical_device_index_to_use_during_create_device, 0)
+    BUILDER_VALUE(bool, call_create_device_while_create_device_is_called)
+    BUILDER_VALUE(uint32_t, physical_device_index_to_use_during_create_device)
 
-    BUILDER_VALUE(TestLayer, bool, check_if_EnumDevExtProps_is_same_as_queried_function, false)
+    BUILDER_VALUE(bool, check_if_EnumDevExtProps_is_same_as_queried_function)
 
     // Clober the data pointed to by pInstance to overwrite the magic value
-    BUILDER_VALUE(TestLayer, bool, clobber_pInstance, false)
+    BUILDER_VALUE(bool, clobber_pInstance)
     // Clober the data pointed to by pDevice to overwrite the magic value
-    BUILDER_VALUE(TestLayer, bool, clobber_pDevice, false)
+    BUILDER_VALUE(bool, clobber_pDevice)
 
-    BUILDER_VALUE(TestLayer, bool, query_vkEnumerateInstanceLayerProperties, false)
-    BUILDER_VALUE(TestLayer, bool, query_vkEnumerateInstanceExtensionProperties, false)
-    BUILDER_VALUE(TestLayer, bool, query_vkEnumerateInstanceVersion, false)
+    BUILDER_VALUE(bool, query_vkEnumerateInstanceLayerProperties)
+    BUILDER_VALUE(bool, query_vkEnumerateInstanceExtensionProperties)
+    BUILDER_VALUE(bool, query_vkEnumerateInstanceVersion)
 
     PFN_vkGetInstanceProcAddr next_vkGetInstanceProcAddr = VK_NULL_HANDLE;
     PFN_GetPhysicalDeviceProcAddr next_GetPhysicalDeviceProcAddr = VK_NULL_HANDLE;
diff --git a/tests/framework/layer/vk_dispatch_table_helper.h b/tests/framework/layer/vk_dispatch_table_helper.h
deleted file mode 100644
index 48b6288..0000000
--- a/tests/framework/layer/vk_dispatch_table_helper.h
+++ /dev/null
@@ -1,952 +0,0 @@
-#pragma once
-// *** THIS FILE IS GENERATED - DO NOT EDIT ***
-// See dispatch_helper_generator.py for modifications
-
-/*
- * Copyright (c) 2015-2021 The Khronos Group Inc.
- * Copyright (c) 2015-2021 Valve Corporation
- * Copyright (c) 2015-2021 LunarG, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
- * Author: Jon Ashburn <jon@lunarg.com>
- * Author: Mark Lobodzinski <mark@lunarg.com>
- */
-
-#include <vulkan/vulkan.h>
-#include <vulkan/vk_layer.h>
-#include <string.h>
-#include "loader/generated/vk_layer_dispatch_table.h"
-
-static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDispatchTable *table, PFN_vkGetDeviceProcAddr gpa) {
-    memset(table, 0, sizeof(*table));
-    table->magic = DEVICE_DISP_TABLE_MAGIC_NUMBER;
-
-    // Device function pointers
-    table->GetDeviceProcAddr = gpa;
-    table->DestroyDevice = (PFN_vkDestroyDevice)gpa(device, "vkDestroyDevice");
-    table->GetDeviceQueue = (PFN_vkGetDeviceQueue)gpa(device, "vkGetDeviceQueue");
-    table->QueueSubmit = (PFN_vkQueueSubmit)gpa(device, "vkQueueSubmit");
-    table->QueueWaitIdle = (PFN_vkQueueWaitIdle)gpa(device, "vkQueueWaitIdle");
-    table->DeviceWaitIdle = (PFN_vkDeviceWaitIdle)gpa(device, "vkDeviceWaitIdle");
-    table->AllocateMemory = (PFN_vkAllocateMemory)gpa(device, "vkAllocateMemory");
-    table->FreeMemory = (PFN_vkFreeMemory)gpa(device, "vkFreeMemory");
-    table->MapMemory = (PFN_vkMapMemory)gpa(device, "vkMapMemory");
-    table->UnmapMemory = (PFN_vkUnmapMemory)gpa(device, "vkUnmapMemory");
-    table->FlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges)gpa(device, "vkFlushMappedMemoryRanges");
-    table->InvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges)gpa(device, "vkInvalidateMappedMemoryRanges");
-    table->GetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment)gpa(device, "vkGetDeviceMemoryCommitment");
-    table->BindBufferMemory = (PFN_vkBindBufferMemory)gpa(device, "vkBindBufferMemory");
-    table->BindImageMemory = (PFN_vkBindImageMemory)gpa(device, "vkBindImageMemory");
-    table->GetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements)gpa(device, "vkGetBufferMemoryRequirements");
-    table->GetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements)gpa(device, "vkGetImageMemoryRequirements");
-    table->GetImageSparseMemoryRequirements =
-        (PFN_vkGetImageSparseMemoryRequirements)gpa(device, "vkGetImageSparseMemoryRequirements");
-    table->QueueBindSparse = (PFN_vkQueueBindSparse)gpa(device, "vkQueueBindSparse");
-    table->CreateFence = (PFN_vkCreateFence)gpa(device, "vkCreateFence");
-    table->DestroyFence = (PFN_vkDestroyFence)gpa(device, "vkDestroyFence");
-    table->ResetFences = (PFN_vkResetFences)gpa(device, "vkResetFences");
-    table->GetFenceStatus = (PFN_vkGetFenceStatus)gpa(device, "vkGetFenceStatus");
-    table->WaitForFences = (PFN_vkWaitForFences)gpa(device, "vkWaitForFences");
-    table->CreateSemaphore = (PFN_vkCreateSemaphore)gpa(device, "vkCreateSemaphore");
-    table->DestroySemaphore = (PFN_vkDestroySemaphore)gpa(device, "vkDestroySemaphore");
-    table->CreateEvent = (PFN_vkCreateEvent)gpa(device, "vkCreateEvent");
-    table->DestroyEvent = (PFN_vkDestroyEvent)gpa(device, "vkDestroyEvent");
-    table->GetEventStatus = (PFN_vkGetEventStatus)gpa(device, "vkGetEventStatus");
-    table->SetEvent = (PFN_vkSetEvent)gpa(device, "vkSetEvent");
-    table->ResetEvent = (PFN_vkResetEvent)gpa(device, "vkResetEvent");
-    table->CreateQueryPool = (PFN_vkCreateQueryPool)gpa(device, "vkCreateQueryPool");
-    table->DestroyQueryPool = (PFN_vkDestroyQueryPool)gpa(device, "vkDestroyQueryPool");
-    table->GetQueryPoolResults = (PFN_vkGetQueryPoolResults)gpa(device, "vkGetQueryPoolResults");
-    table->CreateBuffer = (PFN_vkCreateBuffer)gpa(device, "vkCreateBuffer");
-    table->DestroyBuffer = (PFN_vkDestroyBuffer)gpa(device, "vkDestroyBuffer");
-    table->CreateBufferView = (PFN_vkCreateBufferView)gpa(device, "vkCreateBufferView");
-    table->DestroyBufferView = (PFN_vkDestroyBufferView)gpa(device, "vkDestroyBufferView");
-    table->CreateImage = (PFN_vkCreateImage)gpa(device, "vkCreateImage");
-    table->DestroyImage = (PFN_vkDestroyImage)gpa(device, "vkDestroyImage");
-    table->GetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout)gpa(device, "vkGetImageSubresourceLayout");
-    table->CreateImageView = (PFN_vkCreateImageView)gpa(device, "vkCreateImageView");
-    table->DestroyImageView = (PFN_vkDestroyImageView)gpa(device, "vkDestroyImageView");
-    table->CreateShaderModule = (PFN_vkCreateShaderModule)gpa(device, "vkCreateShaderModule");
-    table->DestroyShaderModule = (PFN_vkDestroyShaderModule)gpa(device, "vkDestroyShaderModule");
-    table->CreatePipelineCache = (PFN_vkCreatePipelineCache)gpa(device, "vkCreatePipelineCache");
-    table->DestroyPipelineCache = (PFN_vkDestroyPipelineCache)gpa(device, "vkDestroyPipelineCache");
-    table->GetPipelineCacheData = (PFN_vkGetPipelineCacheData)gpa(device, "vkGetPipelineCacheData");
-    table->MergePipelineCaches = (PFN_vkMergePipelineCaches)gpa(device, "vkMergePipelineCaches");
-    table->CreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines)gpa(device, "vkCreateGraphicsPipelines");
-    table->CreateComputePipelines = (PFN_vkCreateComputePipelines)gpa(device, "vkCreateComputePipelines");
-    table->DestroyPipeline = (PFN_vkDestroyPipeline)gpa(device, "vkDestroyPipeline");
-    table->CreatePipelineLayout = (PFN_vkCreatePipelineLayout)gpa(device, "vkCreatePipelineLayout");
-    table->DestroyPipelineLayout = (PFN_vkDestroyPipelineLayout)gpa(device, "vkDestroyPipelineLayout");
-    table->CreateSampler = (PFN_vkCreateSampler)gpa(device, "vkCreateSampler");
-    table->DestroySampler = (PFN_vkDestroySampler)gpa(device, "vkDestroySampler");
-    table->CreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout)gpa(device, "vkCreateDescriptorSetLayout");
-    table->DestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout)gpa(device, "vkDestroyDescriptorSetLayout");
-    table->CreateDescriptorPool = (PFN_vkCreateDescriptorPool)gpa(device, "vkCreateDescriptorPool");
-    table->DestroyDescriptorPool = (PFN_vkDestroyDescriptorPool)gpa(device, "vkDestroyDescriptorPool");
-    table->ResetDescriptorPool = (PFN_vkResetDescriptorPool)gpa(device, "vkResetDescriptorPool");
-    table->AllocateDescriptorSets = (PFN_vkAllocateDescriptorSets)gpa(device, "vkAllocateDescriptorSets");
-    table->FreeDescriptorSets = (PFN_vkFreeDescriptorSets)gpa(device, "vkFreeDescriptorSets");
-    table->UpdateDescriptorSets = (PFN_vkUpdateDescriptorSets)gpa(device, "vkUpdateDescriptorSets");
-    table->CreateFramebuffer = (PFN_vkCreateFramebuffer)gpa(device, "vkCreateFramebuffer");
-    table->DestroyFramebuffer = (PFN_vkDestroyFramebuffer)gpa(device, "vkDestroyFramebuffer");
-    table->CreateRenderPass = (PFN_vkCreateRenderPass)gpa(device, "vkCreateRenderPass");
-    table->DestroyRenderPass = (PFN_vkDestroyRenderPass)gpa(device, "vkDestroyRenderPass");
-    table->GetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity)gpa(device, "vkGetRenderAreaGranularity");
-    table->CreateCommandPool = (PFN_vkCreateCommandPool)gpa(device, "vkCreateCommandPool");
-    table->DestroyCommandPool = (PFN_vkDestroyCommandPool)gpa(device, "vkDestroyCommandPool");
-    table->ResetCommandPool = (PFN_vkResetCommandPool)gpa(device, "vkResetCommandPool");
-    table->AllocateCommandBuffers = (PFN_vkAllocateCommandBuffers)gpa(device, "vkAllocateCommandBuffers");
-    table->FreeCommandBuffers = (PFN_vkFreeCommandBuffers)gpa(device, "vkFreeCommandBuffers");
-    table->BeginCommandBuffer = (PFN_vkBeginCommandBuffer)gpa(device, "vkBeginCommandBuffer");
-    table->EndCommandBuffer = (PFN_vkEndCommandBuffer)gpa(device, "vkEndCommandBuffer");
-    table->ResetCommandBuffer = (PFN_vkResetCommandBuffer)gpa(device, "vkResetCommandBuffer");
-    table->CmdBindPipeline = (PFN_vkCmdBindPipeline)gpa(device, "vkCmdBindPipeline");
-    table->CmdSetViewport = (PFN_vkCmdSetViewport)gpa(device, "vkCmdSetViewport");
-    table->CmdSetScissor = (PFN_vkCmdSetScissor)gpa(device, "vkCmdSetScissor");
-    table->CmdSetLineWidth = (PFN_vkCmdSetLineWidth)gpa(device, "vkCmdSetLineWidth");
-    table->CmdSetDepthBias = (PFN_vkCmdSetDepthBias)gpa(device, "vkCmdSetDepthBias");
-    table->CmdSetBlendConstants = (PFN_vkCmdSetBlendConstants)gpa(device, "vkCmdSetBlendConstants");
-    table->CmdSetDepthBounds = (PFN_vkCmdSetDepthBounds)gpa(device, "vkCmdSetDepthBounds");
-    table->CmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask)gpa(device, "vkCmdSetStencilCompareMask");
-    table->CmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask)gpa(device, "vkCmdSetStencilWriteMask");
-    table->CmdSetStencilReference = (PFN_vkCmdSetStencilReference)gpa(device, "vkCmdSetStencilReference");
-    table->CmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets)gpa(device, "vkCmdBindDescriptorSets");
-    table->CmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer)gpa(device, "vkCmdBindIndexBuffer");
-    table->CmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers)gpa(device, "vkCmdBindVertexBuffers");
-    table->CmdDraw = (PFN_vkCmdDraw)gpa(device, "vkCmdDraw");
-    table->CmdDrawIndexed = (PFN_vkCmdDrawIndexed)gpa(device, "vkCmdDrawIndexed");
-    table->CmdDrawIndirect = (PFN_vkCmdDrawIndirect)gpa(device, "vkCmdDrawIndirect");
-    table->CmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect)gpa(device, "vkCmdDrawIndexedIndirect");
-    table->CmdDispatch = (PFN_vkCmdDispatch)gpa(device, "vkCmdDispatch");
-    table->CmdDispatchIndirect = (PFN_vkCmdDispatchIndirect)gpa(device, "vkCmdDispatchIndirect");
-    table->CmdCopyBuffer = (PFN_vkCmdCopyBuffer)gpa(device, "vkCmdCopyBuffer");
-    table->CmdCopyImage = (PFN_vkCmdCopyImage)gpa(device, "vkCmdCopyImage");
-    table->CmdBlitImage = (PFN_vkCmdBlitImage)gpa(device, "vkCmdBlitImage");
-    table->CmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage)gpa(device, "vkCmdCopyBufferToImage");
-    table->CmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer)gpa(device, "vkCmdCopyImageToBuffer");
-    table->CmdUpdateBuffer = (PFN_vkCmdUpdateBuffer)gpa(device, "vkCmdUpdateBuffer");
-    table->CmdFillBuffer = (PFN_vkCmdFillBuffer)gpa(device, "vkCmdFillBuffer");
-    table->CmdClearColorImage = (PFN_vkCmdClearColorImage)gpa(device, "vkCmdClearColorImage");
-    table->CmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage)gpa(device, "vkCmdClearDepthStencilImage");
-    table->CmdClearAttachments = (PFN_vkCmdClearAttachments)gpa(device, "vkCmdClearAttachments");
-    table->CmdResolveImage = (PFN_vkCmdResolveImage)gpa(device, "vkCmdResolveImage");
-    table->CmdSetEvent = (PFN_vkCmdSetEvent)gpa(device, "vkCmdSetEvent");
-    table->CmdResetEvent = (PFN_vkCmdResetEvent)gpa(device, "vkCmdResetEvent");
-    table->CmdWaitEvents = (PFN_vkCmdWaitEvents)gpa(device, "vkCmdWaitEvents");
-    table->CmdPipelineBarrier = (PFN_vkCmdPipelineBarrier)gpa(device, "vkCmdPipelineBarrier");
-    table->CmdBeginQuery = (PFN_vkCmdBeginQuery)gpa(device, "vkCmdBeginQuery");
-    table->CmdEndQuery = (PFN_vkCmdEndQuery)gpa(device, "vkCmdEndQuery");
-    table->CmdResetQueryPool = (PFN_vkCmdResetQueryPool)gpa(device, "vkCmdResetQueryPool");
-    table->CmdWriteTimestamp = (PFN_vkCmdWriteTimestamp)gpa(device, "vkCmdWriteTimestamp");
-    table->CmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults)gpa(device, "vkCmdCopyQueryPoolResults");
-    table->CmdPushConstants = (PFN_vkCmdPushConstants)gpa(device, "vkCmdPushConstants");
-    table->CmdBeginRenderPass = (PFN_vkCmdBeginRenderPass)gpa(device, "vkCmdBeginRenderPass");
-    table->CmdNextSubpass = (PFN_vkCmdNextSubpass)gpa(device, "vkCmdNextSubpass");
-    table->CmdEndRenderPass = (PFN_vkCmdEndRenderPass)gpa(device, "vkCmdEndRenderPass");
-    table->CmdExecuteCommands = (PFN_vkCmdExecuteCommands)gpa(device, "vkCmdExecuteCommands");
-    table->BindBufferMemory2 = (PFN_vkBindBufferMemory2)gpa(device, "vkBindBufferMemory2");
-    table->BindImageMemory2 = (PFN_vkBindImageMemory2)gpa(device, "vkBindImageMemory2");
-    table->GetDeviceGroupPeerMemoryFeatures =
-        (PFN_vkGetDeviceGroupPeerMemoryFeatures)gpa(device, "vkGetDeviceGroupPeerMemoryFeatures");
-    table->CmdSetDeviceMask = (PFN_vkCmdSetDeviceMask)gpa(device, "vkCmdSetDeviceMask");
-    table->CmdDispatchBase = (PFN_vkCmdDispatchBase)gpa(device, "vkCmdDispatchBase");
-    table->GetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2)gpa(device, "vkGetImageMemoryRequirements2");
-    table->GetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2)gpa(device, "vkGetBufferMemoryRequirements2");
-    table->GetImageSparseMemoryRequirements2 =
-        (PFN_vkGetImageSparseMemoryRequirements2)gpa(device, "vkGetImageSparseMemoryRequirements2");
-    table->TrimCommandPool = (PFN_vkTrimCommandPool)gpa(device, "vkTrimCommandPool");
-    table->GetDeviceQueue2 = (PFN_vkGetDeviceQueue2)gpa(device, "vkGetDeviceQueue2");
-    table->CreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)gpa(device, "vkCreateSamplerYcbcrConversion");
-    table->DestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion)gpa(device, "vkDestroySamplerYcbcrConversion");
-    table->CreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate)gpa(device, "vkCreateDescriptorUpdateTemplate");
-    table->DestroyDescriptorUpdateTemplate =
-        (PFN_vkDestroyDescriptorUpdateTemplate)gpa(device, "vkDestroyDescriptorUpdateTemplate");
-    table->UpdateDescriptorSetWithTemplate =
-        (PFN_vkUpdateDescriptorSetWithTemplate)gpa(device, "vkUpdateDescriptorSetWithTemplate");
-    table->GetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport)gpa(device, "vkGetDescriptorSetLayoutSupport");
-    table->CmdDrawIndirectCount = (PFN_vkCmdDrawIndirectCount)gpa(device, "vkCmdDrawIndirectCount");
-    table->CmdDrawIndexedIndirectCount = (PFN_vkCmdDrawIndexedIndirectCount)gpa(device, "vkCmdDrawIndexedIndirectCount");
-    table->CreateRenderPass2 = (PFN_vkCreateRenderPass2)gpa(device, "vkCreateRenderPass2");
-    table->CmdBeginRenderPass2 = (PFN_vkCmdBeginRenderPass2)gpa(device, "vkCmdBeginRenderPass2");
-    table->CmdNextSubpass2 = (PFN_vkCmdNextSubpass2)gpa(device, "vkCmdNextSubpass2");
-    table->CmdEndRenderPass2 = (PFN_vkCmdEndRenderPass2)gpa(device, "vkCmdEndRenderPass2");
-    table->ResetQueryPool = (PFN_vkResetQueryPool)gpa(device, "vkResetQueryPool");
-    table->GetSemaphoreCounterValue = (PFN_vkGetSemaphoreCounterValue)gpa(device, "vkGetSemaphoreCounterValue");
-    table->WaitSemaphores = (PFN_vkWaitSemaphores)gpa(device, "vkWaitSemaphores");
-    table->SignalSemaphore = (PFN_vkSignalSemaphore)gpa(device, "vkSignalSemaphore");
-    table->GetBufferDeviceAddress = (PFN_vkGetBufferDeviceAddress)gpa(device, "vkGetBufferDeviceAddress");
-    table->GetBufferOpaqueCaptureAddress = (PFN_vkGetBufferOpaqueCaptureAddress)gpa(device, "vkGetBufferOpaqueCaptureAddress");
-    table->GetDeviceMemoryOpaqueCaptureAddress =
-        (PFN_vkGetDeviceMemoryOpaqueCaptureAddress)gpa(device, "vkGetDeviceMemoryOpaqueCaptureAddress");
-    table->CreatePrivateDataSlot = (PFN_vkCreatePrivateDataSlot)gpa(device, "vkCreatePrivateDataSlot");
-    table->DestroyPrivateDataSlot = (PFN_vkDestroyPrivateDataSlot)gpa(device, "vkDestroyPrivateDataSlot");
-    table->SetPrivateData = (PFN_vkSetPrivateData)gpa(device, "vkSetPrivateData");
-    table->GetPrivateData = (PFN_vkGetPrivateData)gpa(device, "vkGetPrivateData");
-    table->CmdSetEvent2 = (PFN_vkCmdSetEvent2)gpa(device, "vkCmdSetEvent2");
-    table->CmdResetEvent2 = (PFN_vkCmdResetEvent2)gpa(device, "vkCmdResetEvent2");
-    table->CmdWaitEvents2 = (PFN_vkCmdWaitEvents2)gpa(device, "vkCmdWaitEvents2");
-    table->CmdPipelineBarrier2 = (PFN_vkCmdPipelineBarrier2)gpa(device, "vkCmdPipelineBarrier2");
-    table->CmdWriteTimestamp2 = (PFN_vkCmdWriteTimestamp2)gpa(device, "vkCmdWriteTimestamp2");
-    table->QueueSubmit2 = (PFN_vkQueueSubmit2)gpa(device, "vkQueueSubmit2");
-    table->CmdCopyBuffer2 = (PFN_vkCmdCopyBuffer2)gpa(device, "vkCmdCopyBuffer2");
-    table->CmdCopyImage2 = (PFN_vkCmdCopyImage2)gpa(device, "vkCmdCopyImage2");
-    table->CmdCopyBufferToImage2 = (PFN_vkCmdCopyBufferToImage2)gpa(device, "vkCmdCopyBufferToImage2");
-    table->CmdCopyImageToBuffer2 = (PFN_vkCmdCopyImageToBuffer2)gpa(device, "vkCmdCopyImageToBuffer2");
-    table->CmdBlitImage2 = (PFN_vkCmdBlitImage2)gpa(device, "vkCmdBlitImage2");
-    table->CmdResolveImage2 = (PFN_vkCmdResolveImage2)gpa(device, "vkCmdResolveImage2");
-    table->CmdBeginRendering = (PFN_vkCmdBeginRendering)gpa(device, "vkCmdBeginRendering");
-    table->CmdEndRendering = (PFN_vkCmdEndRendering)gpa(device, "vkCmdEndRendering");
-    table->CmdSetCullMode = (PFN_vkCmdSetCullMode)gpa(device, "vkCmdSetCullMode");
-    table->CmdSetFrontFace = (PFN_vkCmdSetFrontFace)gpa(device, "vkCmdSetFrontFace");
-    table->CmdSetPrimitiveTopology = (PFN_vkCmdSetPrimitiveTopology)gpa(device, "vkCmdSetPrimitiveTopology");
-    table->CmdSetViewportWithCount = (PFN_vkCmdSetViewportWithCount)gpa(device, "vkCmdSetViewportWithCount");
-    table->CmdSetScissorWithCount = (PFN_vkCmdSetScissorWithCount)gpa(device, "vkCmdSetScissorWithCount");
-    table->CmdBindVertexBuffers2 = (PFN_vkCmdBindVertexBuffers2)gpa(device, "vkCmdBindVertexBuffers2");
-    table->CmdSetDepthTestEnable = (PFN_vkCmdSetDepthTestEnable)gpa(device, "vkCmdSetDepthTestEnable");
-    table->CmdSetDepthWriteEnable = (PFN_vkCmdSetDepthWriteEnable)gpa(device, "vkCmdSetDepthWriteEnable");
-    table->CmdSetDepthCompareOp = (PFN_vkCmdSetDepthCompareOp)gpa(device, "vkCmdSetDepthCompareOp");
-    table->CmdSetDepthBoundsTestEnable = (PFN_vkCmdSetDepthBoundsTestEnable)gpa(device, "vkCmdSetDepthBoundsTestEnable");
-    table->CmdSetStencilTestEnable = (PFN_vkCmdSetStencilTestEnable)gpa(device, "vkCmdSetStencilTestEnable");
-    table->CmdSetStencilOp = (PFN_vkCmdSetStencilOp)gpa(device, "vkCmdSetStencilOp");
-    table->CmdSetRasterizerDiscardEnable = (PFN_vkCmdSetRasterizerDiscardEnable)gpa(device, "vkCmdSetRasterizerDiscardEnable");
-    table->CmdSetDepthBiasEnable = (PFN_vkCmdSetDepthBiasEnable)gpa(device, "vkCmdSetDepthBiasEnable");
-    table->CmdSetPrimitiveRestartEnable = (PFN_vkCmdSetPrimitiveRestartEnable)gpa(device, "vkCmdSetPrimitiveRestartEnable");
-    table->GetDeviceBufferMemoryRequirements =
-        (PFN_vkGetDeviceBufferMemoryRequirements)gpa(device, "vkGetDeviceBufferMemoryRequirements");
-    table->GetDeviceImageMemoryRequirements =
-        (PFN_vkGetDeviceImageMemoryRequirements)gpa(device, "vkGetDeviceImageMemoryRequirements");
-    table->GetDeviceImageSparseMemoryRequirements =
-        (PFN_vkGetDeviceImageSparseMemoryRequirements)gpa(device, "vkGetDeviceImageSparseMemoryRequirements");
-    table->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
-    table->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR");
-    table->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
-    table->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
-    table->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
-    table->GetDeviceGroupPresentCapabilitiesKHR =
-        (PFN_vkGetDeviceGroupPresentCapabilitiesKHR)gpa(device, "vkGetDeviceGroupPresentCapabilitiesKHR");
-    table->GetDeviceGroupSurfacePresentModesKHR =
-        (PFN_vkGetDeviceGroupSurfacePresentModesKHR)gpa(device, "vkGetDeviceGroupSurfacePresentModesKHR");
-    table->AcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR)gpa(device, "vkAcquireNextImage2KHR");
-    table->CreateSharedSwapchainsKHR = (PFN_vkCreateSharedSwapchainsKHR)gpa(device, "vkCreateSharedSwapchainsKHR");
-    table->CreateVideoSessionKHR = (PFN_vkCreateVideoSessionKHR)gpa(device, "vkCreateVideoSessionKHR");
-    table->DestroyVideoSessionKHR = (PFN_vkDestroyVideoSessionKHR)gpa(device, "vkDestroyVideoSessionKHR");
-    table->GetVideoSessionMemoryRequirementsKHR =
-        (PFN_vkGetVideoSessionMemoryRequirementsKHR)gpa(device, "vkGetVideoSessionMemoryRequirementsKHR");
-    table->BindVideoSessionMemoryKHR = (PFN_vkBindVideoSessionMemoryKHR)gpa(device, "vkBindVideoSessionMemoryKHR");
-    table->CreateVideoSessionParametersKHR =
-        (PFN_vkCreateVideoSessionParametersKHR)gpa(device, "vkCreateVideoSessionParametersKHR");
-    table->UpdateVideoSessionParametersKHR =
-        (PFN_vkUpdateVideoSessionParametersKHR)gpa(device, "vkUpdateVideoSessionParametersKHR");
-    table->DestroyVideoSessionParametersKHR =
-        (PFN_vkDestroyVideoSessionParametersKHR)gpa(device, "vkDestroyVideoSessionParametersKHR");
-    table->CmdBeginVideoCodingKHR = (PFN_vkCmdBeginVideoCodingKHR)gpa(device, "vkCmdBeginVideoCodingKHR");
-    table->CmdEndVideoCodingKHR = (PFN_vkCmdEndVideoCodingKHR)gpa(device, "vkCmdEndVideoCodingKHR");
-    table->CmdControlVideoCodingKHR = (PFN_vkCmdControlVideoCodingKHR)gpa(device, "vkCmdControlVideoCodingKHR");
-    table->CmdDecodeVideoKHR = (PFN_vkCmdDecodeVideoKHR)gpa(device, "vkCmdDecodeVideoKHR");
-    table->CmdBeginRenderingKHR = (PFN_vkCmdBeginRenderingKHR)gpa(device, "vkCmdBeginRenderingKHR");
-    table->CmdEndRenderingKHR = (PFN_vkCmdEndRenderingKHR)gpa(device, "vkCmdEndRenderingKHR");
-    table->GetDeviceGroupPeerMemoryFeaturesKHR =
-        (PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR)gpa(device, "vkGetDeviceGroupPeerMemoryFeaturesKHR");
-    table->CmdSetDeviceMaskKHR = (PFN_vkCmdSetDeviceMaskKHR)gpa(device, "vkCmdSetDeviceMaskKHR");
-    table->CmdDispatchBaseKHR = (PFN_vkCmdDispatchBaseKHR)gpa(device, "vkCmdDispatchBaseKHR");
-    table->TrimCommandPoolKHR = (PFN_vkTrimCommandPoolKHR)gpa(device, "vkTrimCommandPoolKHR");
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->GetMemoryWin32HandleKHR = (PFN_vkGetMemoryWin32HandleKHR)gpa(device, "vkGetMemoryWin32HandleKHR");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->GetMemoryWin32HandlePropertiesKHR =
-        (PFN_vkGetMemoryWin32HandlePropertiesKHR)gpa(device, "vkGetMemoryWin32HandlePropertiesKHR");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-    table->GetMemoryFdKHR = (PFN_vkGetMemoryFdKHR)gpa(device, "vkGetMemoryFdKHR");
-    table->GetMemoryFdPropertiesKHR = (PFN_vkGetMemoryFdPropertiesKHR)gpa(device, "vkGetMemoryFdPropertiesKHR");
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->ImportSemaphoreWin32HandleKHR = (PFN_vkImportSemaphoreWin32HandleKHR)gpa(device, "vkImportSemaphoreWin32HandleKHR");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->GetSemaphoreWin32HandleKHR = (PFN_vkGetSemaphoreWin32HandleKHR)gpa(device, "vkGetSemaphoreWin32HandleKHR");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-    table->ImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)gpa(device, "vkImportSemaphoreFdKHR");
-    table->GetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)gpa(device, "vkGetSemaphoreFdKHR");
-    table->CmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)gpa(device, "vkCmdPushDescriptorSetKHR");
-    table->CmdPushDescriptorSetWithTemplateKHR =
-        (PFN_vkCmdPushDescriptorSetWithTemplateKHR)gpa(device, "vkCmdPushDescriptorSetWithTemplateKHR");
-    table->CreateDescriptorUpdateTemplateKHR =
-        (PFN_vkCreateDescriptorUpdateTemplateKHR)gpa(device, "vkCreateDescriptorUpdateTemplateKHR");
-    table->DestroyDescriptorUpdateTemplateKHR =
-        (PFN_vkDestroyDescriptorUpdateTemplateKHR)gpa(device, "vkDestroyDescriptorUpdateTemplateKHR");
-    table->UpdateDescriptorSetWithTemplateKHR =
-        (PFN_vkUpdateDescriptorSetWithTemplateKHR)gpa(device, "vkUpdateDescriptorSetWithTemplateKHR");
-    table->CreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)gpa(device, "vkCreateRenderPass2KHR");
-    table->CmdBeginRenderPass2KHR = (PFN_vkCmdBeginRenderPass2KHR)gpa(device, "vkCmdBeginRenderPass2KHR");
-    table->CmdNextSubpass2KHR = (PFN_vkCmdNextSubpass2KHR)gpa(device, "vkCmdNextSubpass2KHR");
-    table->CmdEndRenderPass2KHR = (PFN_vkCmdEndRenderPass2KHR)gpa(device, "vkCmdEndRenderPass2KHR");
-    table->GetSwapchainStatusKHR = (PFN_vkGetSwapchainStatusKHR)gpa(device, "vkGetSwapchainStatusKHR");
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->ImportFenceWin32HandleKHR = (PFN_vkImportFenceWin32HandleKHR)gpa(device, "vkImportFenceWin32HandleKHR");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->GetFenceWin32HandleKHR = (PFN_vkGetFenceWin32HandleKHR)gpa(device, "vkGetFenceWin32HandleKHR");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-    table->ImportFenceFdKHR = (PFN_vkImportFenceFdKHR)gpa(device, "vkImportFenceFdKHR");
-    table->GetFenceFdKHR = (PFN_vkGetFenceFdKHR)gpa(device, "vkGetFenceFdKHR");
-    table->AcquireProfilingLockKHR = (PFN_vkAcquireProfilingLockKHR)gpa(device, "vkAcquireProfilingLockKHR");
-    table->ReleaseProfilingLockKHR = (PFN_vkReleaseProfilingLockKHR)gpa(device, "vkReleaseProfilingLockKHR");
-    table->GetImageMemoryRequirements2KHR = (PFN_vkGetImageMemoryRequirements2KHR)gpa(device, "vkGetImageMemoryRequirements2KHR");
-    table->GetBufferMemoryRequirements2KHR =
-        (PFN_vkGetBufferMemoryRequirements2KHR)gpa(device, "vkGetBufferMemoryRequirements2KHR");
-    table->GetImageSparseMemoryRequirements2KHR =
-        (PFN_vkGetImageSparseMemoryRequirements2KHR)gpa(device, "vkGetImageSparseMemoryRequirements2KHR");
-    table->CreateSamplerYcbcrConversionKHR =
-        (PFN_vkCreateSamplerYcbcrConversionKHR)gpa(device, "vkCreateSamplerYcbcrConversionKHR");
-    table->DestroySamplerYcbcrConversionKHR =
-        (PFN_vkDestroySamplerYcbcrConversionKHR)gpa(device, "vkDestroySamplerYcbcrConversionKHR");
-    table->BindBufferMemory2KHR = (PFN_vkBindBufferMemory2KHR)gpa(device, "vkBindBufferMemory2KHR");
-    table->BindImageMemory2KHR = (PFN_vkBindImageMemory2KHR)gpa(device, "vkBindImageMemory2KHR");
-    table->GetDescriptorSetLayoutSupportKHR =
-        (PFN_vkGetDescriptorSetLayoutSupportKHR)gpa(device, "vkGetDescriptorSetLayoutSupportKHR");
-    table->CmdDrawIndirectCountKHR = (PFN_vkCmdDrawIndirectCountKHR)gpa(device, "vkCmdDrawIndirectCountKHR");
-    table->CmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR)gpa(device, "vkCmdDrawIndexedIndirectCountKHR");
-    table->GetSemaphoreCounterValueKHR = (PFN_vkGetSemaphoreCounterValueKHR)gpa(device, "vkGetSemaphoreCounterValueKHR");
-    table->WaitSemaphoresKHR = (PFN_vkWaitSemaphoresKHR)gpa(device, "vkWaitSemaphoresKHR");
-    table->SignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR)gpa(device, "vkSignalSemaphoreKHR");
-    table->CmdSetFragmentShadingRateKHR = (PFN_vkCmdSetFragmentShadingRateKHR)gpa(device, "vkCmdSetFragmentShadingRateKHR");
-    table->WaitForPresentKHR = (PFN_vkWaitForPresentKHR)gpa(device, "vkWaitForPresentKHR");
-    table->GetBufferDeviceAddressKHR = (PFN_vkGetBufferDeviceAddressKHR)gpa(device, "vkGetBufferDeviceAddressKHR");
-    table->GetBufferOpaqueCaptureAddressKHR =
-        (PFN_vkGetBufferOpaqueCaptureAddressKHR)gpa(device, "vkGetBufferOpaqueCaptureAddressKHR");
-    table->GetDeviceMemoryOpaqueCaptureAddressKHR =
-        (PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)gpa(device, "vkGetDeviceMemoryOpaqueCaptureAddressKHR");
-    table->CreateDeferredOperationKHR = (PFN_vkCreateDeferredOperationKHR)gpa(device, "vkCreateDeferredOperationKHR");
-    table->DestroyDeferredOperationKHR = (PFN_vkDestroyDeferredOperationKHR)gpa(device, "vkDestroyDeferredOperationKHR");
-    table->GetDeferredOperationMaxConcurrencyKHR =
-        (PFN_vkGetDeferredOperationMaxConcurrencyKHR)gpa(device, "vkGetDeferredOperationMaxConcurrencyKHR");
-    table->GetDeferredOperationResultKHR = (PFN_vkGetDeferredOperationResultKHR)gpa(device, "vkGetDeferredOperationResultKHR");
-    table->DeferredOperationJoinKHR = (PFN_vkDeferredOperationJoinKHR)gpa(device, "vkDeferredOperationJoinKHR");
-    table->GetPipelineExecutablePropertiesKHR =
-        (PFN_vkGetPipelineExecutablePropertiesKHR)gpa(device, "vkGetPipelineExecutablePropertiesKHR");
-    table->GetPipelineExecutableStatisticsKHR =
-        (PFN_vkGetPipelineExecutableStatisticsKHR)gpa(device, "vkGetPipelineExecutableStatisticsKHR");
-    table->GetPipelineExecutableInternalRepresentationsKHR =
-        (PFN_vkGetPipelineExecutableInternalRepresentationsKHR)gpa(device, "vkGetPipelineExecutableInternalRepresentationsKHR");
-    table->MapMemory2KHR = (PFN_vkMapMemory2KHR)gpa(device, "vkMapMemory2KHR");
-    table->UnmapMemory2KHR = (PFN_vkUnmapMemory2KHR)gpa(device, "vkUnmapMemory2KHR");
-#if defined(VK_ENABLE_BETA_EXTENSIONS)
-    table->GetEncodedVideoSessionParametersKHR =
-        (PFN_vkGetEncodedVideoSessionParametersKHR)gpa(device, "vkGetEncodedVideoSessionParametersKHR");
-#endif  // VK_ENABLE_BETA_EXTENSIONS
-#if defined(VK_ENABLE_BETA_EXTENSIONS)
-    table->CmdEncodeVideoKHR = (PFN_vkCmdEncodeVideoKHR)gpa(device, "vkCmdEncodeVideoKHR");
-#endif  // VK_ENABLE_BETA_EXTENSIONS
-    table->CmdSetEvent2KHR = (PFN_vkCmdSetEvent2KHR)gpa(device, "vkCmdSetEvent2KHR");
-    table->CmdResetEvent2KHR = (PFN_vkCmdResetEvent2KHR)gpa(device, "vkCmdResetEvent2KHR");
-    table->CmdWaitEvents2KHR = (PFN_vkCmdWaitEvents2KHR)gpa(device, "vkCmdWaitEvents2KHR");
-    table->CmdPipelineBarrier2KHR = (PFN_vkCmdPipelineBarrier2KHR)gpa(device, "vkCmdPipelineBarrier2KHR");
-    table->CmdWriteTimestamp2KHR = (PFN_vkCmdWriteTimestamp2KHR)gpa(device, "vkCmdWriteTimestamp2KHR");
-    table->QueueSubmit2KHR = (PFN_vkQueueSubmit2KHR)gpa(device, "vkQueueSubmit2KHR");
-    table->CmdWriteBufferMarker2AMD = (PFN_vkCmdWriteBufferMarker2AMD)gpa(device, "vkCmdWriteBufferMarker2AMD");
-    table->GetQueueCheckpointData2NV = (PFN_vkGetQueueCheckpointData2NV)gpa(device, "vkGetQueueCheckpointData2NV");
-    table->CmdCopyBuffer2KHR = (PFN_vkCmdCopyBuffer2KHR)gpa(device, "vkCmdCopyBuffer2KHR");
-    table->CmdCopyImage2KHR = (PFN_vkCmdCopyImage2KHR)gpa(device, "vkCmdCopyImage2KHR");
-    table->CmdCopyBufferToImage2KHR = (PFN_vkCmdCopyBufferToImage2KHR)gpa(device, "vkCmdCopyBufferToImage2KHR");
-    table->CmdCopyImageToBuffer2KHR = (PFN_vkCmdCopyImageToBuffer2KHR)gpa(device, "vkCmdCopyImageToBuffer2KHR");
-    table->CmdBlitImage2KHR = (PFN_vkCmdBlitImage2KHR)gpa(device, "vkCmdBlitImage2KHR");
-    table->CmdResolveImage2KHR = (PFN_vkCmdResolveImage2KHR)gpa(device, "vkCmdResolveImage2KHR");
-    table->CmdTraceRaysIndirect2KHR = (PFN_vkCmdTraceRaysIndirect2KHR)gpa(device, "vkCmdTraceRaysIndirect2KHR");
-    table->GetDeviceBufferMemoryRequirementsKHR =
-        (PFN_vkGetDeviceBufferMemoryRequirementsKHR)gpa(device, "vkGetDeviceBufferMemoryRequirementsKHR");
-    table->GetDeviceImageMemoryRequirementsKHR =
-        (PFN_vkGetDeviceImageMemoryRequirementsKHR)gpa(device, "vkGetDeviceImageMemoryRequirementsKHR");
-    table->GetDeviceImageSparseMemoryRequirementsKHR =
-        (PFN_vkGetDeviceImageSparseMemoryRequirementsKHR)gpa(device, "vkGetDeviceImageSparseMemoryRequirementsKHR");
-    table->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)gpa(device, "vkDebugMarkerSetObjectTagEXT");
-    table->DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)gpa(device, "vkDebugMarkerSetObjectNameEXT");
-    table->CmdDebugMarkerBeginEXT = (PFN_vkCmdDebugMarkerBeginEXT)gpa(device, "vkCmdDebugMarkerBeginEXT");
-    table->CmdDebugMarkerEndEXT = (PFN_vkCmdDebugMarkerEndEXT)gpa(device, "vkCmdDebugMarkerEndEXT");
-    table->CmdDebugMarkerInsertEXT = (PFN_vkCmdDebugMarkerInsertEXT)gpa(device, "vkCmdDebugMarkerInsertEXT");
-    table->CmdBindTransformFeedbackBuffersEXT =
-        (PFN_vkCmdBindTransformFeedbackBuffersEXT)gpa(device, "vkCmdBindTransformFeedbackBuffersEXT");
-    table->CmdBeginTransformFeedbackEXT = (PFN_vkCmdBeginTransformFeedbackEXT)gpa(device, "vkCmdBeginTransformFeedbackEXT");
-    table->CmdEndTransformFeedbackEXT = (PFN_vkCmdEndTransformFeedbackEXT)gpa(device, "vkCmdEndTransformFeedbackEXT");
-    table->CmdBeginQueryIndexedEXT = (PFN_vkCmdBeginQueryIndexedEXT)gpa(device, "vkCmdBeginQueryIndexedEXT");
-    table->CmdEndQueryIndexedEXT = (PFN_vkCmdEndQueryIndexedEXT)gpa(device, "vkCmdEndQueryIndexedEXT");
-    table->CmdDrawIndirectByteCountEXT = (PFN_vkCmdDrawIndirectByteCountEXT)gpa(device, "vkCmdDrawIndirectByteCountEXT");
-    table->CreateCuModuleNVX = (PFN_vkCreateCuModuleNVX)gpa(device, "vkCreateCuModuleNVX");
-    table->CreateCuFunctionNVX = (PFN_vkCreateCuFunctionNVX)gpa(device, "vkCreateCuFunctionNVX");
-    table->DestroyCuModuleNVX = (PFN_vkDestroyCuModuleNVX)gpa(device, "vkDestroyCuModuleNVX");
-    table->DestroyCuFunctionNVX = (PFN_vkDestroyCuFunctionNVX)gpa(device, "vkDestroyCuFunctionNVX");
-    table->CmdCuLaunchKernelNVX = (PFN_vkCmdCuLaunchKernelNVX)gpa(device, "vkCmdCuLaunchKernelNVX");
-    table->GetImageViewHandleNVX = (PFN_vkGetImageViewHandleNVX)gpa(device, "vkGetImageViewHandleNVX");
-    table->GetImageViewAddressNVX = (PFN_vkGetImageViewAddressNVX)gpa(device, "vkGetImageViewAddressNVX");
-    table->CmdDrawIndirectCountAMD = (PFN_vkCmdDrawIndirectCountAMD)gpa(device, "vkCmdDrawIndirectCountAMD");
-    table->CmdDrawIndexedIndirectCountAMD = (PFN_vkCmdDrawIndexedIndirectCountAMD)gpa(device, "vkCmdDrawIndexedIndirectCountAMD");
-    table->GetShaderInfoAMD = (PFN_vkGetShaderInfoAMD)gpa(device, "vkGetShaderInfoAMD");
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->GetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV)gpa(device, "vkGetMemoryWin32HandleNV");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-    table->CmdBeginConditionalRenderingEXT =
-        (PFN_vkCmdBeginConditionalRenderingEXT)gpa(device, "vkCmdBeginConditionalRenderingEXT");
-    table->CmdEndConditionalRenderingEXT = (PFN_vkCmdEndConditionalRenderingEXT)gpa(device, "vkCmdEndConditionalRenderingEXT");
-    table->CmdSetViewportWScalingNV = (PFN_vkCmdSetViewportWScalingNV)gpa(device, "vkCmdSetViewportWScalingNV");
-    table->DisplayPowerControlEXT = (PFN_vkDisplayPowerControlEXT)gpa(device, "vkDisplayPowerControlEXT");
-    table->RegisterDeviceEventEXT = (PFN_vkRegisterDeviceEventEXT)gpa(device, "vkRegisterDeviceEventEXT");
-    table->RegisterDisplayEventEXT = (PFN_vkRegisterDisplayEventEXT)gpa(device, "vkRegisterDisplayEventEXT");
-    table->GetSwapchainCounterEXT = (PFN_vkGetSwapchainCounterEXT)gpa(device, "vkGetSwapchainCounterEXT");
-    table->GetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE)gpa(device, "vkGetRefreshCycleDurationGOOGLE");
-    table->GetPastPresentationTimingGOOGLE =
-        (PFN_vkGetPastPresentationTimingGOOGLE)gpa(device, "vkGetPastPresentationTimingGOOGLE");
-    table->CmdSetDiscardRectangleEXT = (PFN_vkCmdSetDiscardRectangleEXT)gpa(device, "vkCmdSetDiscardRectangleEXT");
-    table->CmdSetDiscardRectangleEnableEXT =
-        (PFN_vkCmdSetDiscardRectangleEnableEXT)gpa(device, "vkCmdSetDiscardRectangleEnableEXT");
-    table->CmdSetDiscardRectangleModeEXT = (PFN_vkCmdSetDiscardRectangleModeEXT)gpa(device, "vkCmdSetDiscardRectangleModeEXT");
-    table->SetHdrMetadataEXT = (PFN_vkSetHdrMetadataEXT)gpa(device, "vkSetHdrMetadataEXT");
-    table->SetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)gpa(device, "vkSetDebugUtilsObjectNameEXT");
-    table->SetDebugUtilsObjectTagEXT = (PFN_vkSetDebugUtilsObjectTagEXT)gpa(device, "vkSetDebugUtilsObjectTagEXT");
-    table->QueueBeginDebugUtilsLabelEXT = (PFN_vkQueueBeginDebugUtilsLabelEXT)gpa(device, "vkQueueBeginDebugUtilsLabelEXT");
-    table->QueueEndDebugUtilsLabelEXT = (PFN_vkQueueEndDebugUtilsLabelEXT)gpa(device, "vkQueueEndDebugUtilsLabelEXT");
-    table->QueueInsertDebugUtilsLabelEXT = (PFN_vkQueueInsertDebugUtilsLabelEXT)gpa(device, "vkQueueInsertDebugUtilsLabelEXT");
-    table->CmdBeginDebugUtilsLabelEXT = (PFN_vkCmdBeginDebugUtilsLabelEXT)gpa(device, "vkCmdBeginDebugUtilsLabelEXT");
-    table->CmdEndDebugUtilsLabelEXT = (PFN_vkCmdEndDebugUtilsLabelEXT)gpa(device, "vkCmdEndDebugUtilsLabelEXT");
-    table->CmdInsertDebugUtilsLabelEXT = (PFN_vkCmdInsertDebugUtilsLabelEXT)gpa(device, "vkCmdInsertDebugUtilsLabelEXT");
-#if defined(VK_USE_PLATFORM_ANDROID_KHR)
-    table->GetAndroidHardwareBufferPropertiesANDROID =
-        (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)gpa(device, "vkGetAndroidHardwareBufferPropertiesANDROID");
-#endif  // VK_USE_PLATFORM_ANDROID_KHR
-#if defined(VK_USE_PLATFORM_ANDROID_KHR)
-    table->GetMemoryAndroidHardwareBufferANDROID =
-        (PFN_vkGetMemoryAndroidHardwareBufferANDROID)gpa(device, "vkGetMemoryAndroidHardwareBufferANDROID");
-#endif  // VK_USE_PLATFORM_ANDROID_KHR
-    table->CmdSetSampleLocationsEXT = (PFN_vkCmdSetSampleLocationsEXT)gpa(device, "vkCmdSetSampleLocationsEXT");
-    table->GetImageDrmFormatModifierPropertiesEXT =
-        (PFN_vkGetImageDrmFormatModifierPropertiesEXT)gpa(device, "vkGetImageDrmFormatModifierPropertiesEXT");
-    table->CreateValidationCacheEXT = (PFN_vkCreateValidationCacheEXT)gpa(device, "vkCreateValidationCacheEXT");
-    table->DestroyValidationCacheEXT = (PFN_vkDestroyValidationCacheEXT)gpa(device, "vkDestroyValidationCacheEXT");
-    table->MergeValidationCachesEXT = (PFN_vkMergeValidationCachesEXT)gpa(device, "vkMergeValidationCachesEXT");
-    table->GetValidationCacheDataEXT = (PFN_vkGetValidationCacheDataEXT)gpa(device, "vkGetValidationCacheDataEXT");
-    table->CmdBindShadingRateImageNV = (PFN_vkCmdBindShadingRateImageNV)gpa(device, "vkCmdBindShadingRateImageNV");
-    table->CmdSetViewportShadingRatePaletteNV =
-        (PFN_vkCmdSetViewportShadingRatePaletteNV)gpa(device, "vkCmdSetViewportShadingRatePaletteNV");
-    table->CmdSetCoarseSampleOrderNV = (PFN_vkCmdSetCoarseSampleOrderNV)gpa(device, "vkCmdSetCoarseSampleOrderNV");
-    table->CreateAccelerationStructureNV = (PFN_vkCreateAccelerationStructureNV)gpa(device, "vkCreateAccelerationStructureNV");
-    table->DestroyAccelerationStructureNV = (PFN_vkDestroyAccelerationStructureNV)gpa(device, "vkDestroyAccelerationStructureNV");
-    table->GetAccelerationStructureMemoryRequirementsNV =
-        (PFN_vkGetAccelerationStructureMemoryRequirementsNV)gpa(device, "vkGetAccelerationStructureMemoryRequirementsNV");
-    table->BindAccelerationStructureMemoryNV =
-        (PFN_vkBindAccelerationStructureMemoryNV)gpa(device, "vkBindAccelerationStructureMemoryNV");
-    table->CmdBuildAccelerationStructureNV =
-        (PFN_vkCmdBuildAccelerationStructureNV)gpa(device, "vkCmdBuildAccelerationStructureNV");
-    table->CmdCopyAccelerationStructureNV = (PFN_vkCmdCopyAccelerationStructureNV)gpa(device, "vkCmdCopyAccelerationStructureNV");
-    table->CmdTraceRaysNV = (PFN_vkCmdTraceRaysNV)gpa(device, "vkCmdTraceRaysNV");
-    table->CreateRayTracingPipelinesNV = (PFN_vkCreateRayTracingPipelinesNV)gpa(device, "vkCreateRayTracingPipelinesNV");
-    table->GetRayTracingShaderGroupHandlesKHR =
-        (PFN_vkGetRayTracingShaderGroupHandlesKHR)gpa(device, "vkGetRayTracingShaderGroupHandlesKHR");
-    table->GetRayTracingShaderGroupHandlesNV =
-        (PFN_vkGetRayTracingShaderGroupHandlesNV)gpa(device, "vkGetRayTracingShaderGroupHandlesNV");
-    table->GetAccelerationStructureHandleNV =
-        (PFN_vkGetAccelerationStructureHandleNV)gpa(device, "vkGetAccelerationStructureHandleNV");
-    table->CmdWriteAccelerationStructuresPropertiesNV =
-        (PFN_vkCmdWriteAccelerationStructuresPropertiesNV)gpa(device, "vkCmdWriteAccelerationStructuresPropertiesNV");
-    table->CompileDeferredNV = (PFN_vkCompileDeferredNV)gpa(device, "vkCompileDeferredNV");
-    table->GetMemoryHostPointerPropertiesEXT =
-        (PFN_vkGetMemoryHostPointerPropertiesEXT)gpa(device, "vkGetMemoryHostPointerPropertiesEXT");
-    table->CmdWriteBufferMarkerAMD = (PFN_vkCmdWriteBufferMarkerAMD)gpa(device, "vkCmdWriteBufferMarkerAMD");
-    table->GetCalibratedTimestampsEXT = (PFN_vkGetCalibratedTimestampsEXT)gpa(device, "vkGetCalibratedTimestampsEXT");
-    table->CmdDrawMeshTasksNV = (PFN_vkCmdDrawMeshTasksNV)gpa(device, "vkCmdDrawMeshTasksNV");
-    table->CmdDrawMeshTasksIndirectNV = (PFN_vkCmdDrawMeshTasksIndirectNV)gpa(device, "vkCmdDrawMeshTasksIndirectNV");
-    table->CmdDrawMeshTasksIndirectCountNV =
-        (PFN_vkCmdDrawMeshTasksIndirectCountNV)gpa(device, "vkCmdDrawMeshTasksIndirectCountNV");
-    table->CmdSetExclusiveScissorEnableNV = (PFN_vkCmdSetExclusiveScissorEnableNV)gpa(device, "vkCmdSetExclusiveScissorEnableNV");
-    table->CmdSetExclusiveScissorNV = (PFN_vkCmdSetExclusiveScissorNV)gpa(device, "vkCmdSetExclusiveScissorNV");
-    table->CmdSetCheckpointNV = (PFN_vkCmdSetCheckpointNV)gpa(device, "vkCmdSetCheckpointNV");
-    table->GetQueueCheckpointDataNV = (PFN_vkGetQueueCheckpointDataNV)gpa(device, "vkGetQueueCheckpointDataNV");
-    table->InitializePerformanceApiINTEL = (PFN_vkInitializePerformanceApiINTEL)gpa(device, "vkInitializePerformanceApiINTEL");
-    table->UninitializePerformanceApiINTEL =
-        (PFN_vkUninitializePerformanceApiINTEL)gpa(device, "vkUninitializePerformanceApiINTEL");
-    table->CmdSetPerformanceMarkerINTEL = (PFN_vkCmdSetPerformanceMarkerINTEL)gpa(device, "vkCmdSetPerformanceMarkerINTEL");
-    table->CmdSetPerformanceStreamMarkerINTEL =
-        (PFN_vkCmdSetPerformanceStreamMarkerINTEL)gpa(device, "vkCmdSetPerformanceStreamMarkerINTEL");
-    table->CmdSetPerformanceOverrideINTEL = (PFN_vkCmdSetPerformanceOverrideINTEL)gpa(device, "vkCmdSetPerformanceOverrideINTEL");
-    table->AcquirePerformanceConfigurationINTEL =
-        (PFN_vkAcquirePerformanceConfigurationINTEL)gpa(device, "vkAcquirePerformanceConfigurationINTEL");
-    table->ReleasePerformanceConfigurationINTEL =
-        (PFN_vkReleasePerformanceConfigurationINTEL)gpa(device, "vkReleasePerformanceConfigurationINTEL");
-    table->QueueSetPerformanceConfigurationINTEL =
-        (PFN_vkQueueSetPerformanceConfigurationINTEL)gpa(device, "vkQueueSetPerformanceConfigurationINTEL");
-    table->GetPerformanceParameterINTEL = (PFN_vkGetPerformanceParameterINTEL)gpa(device, "vkGetPerformanceParameterINTEL");
-    table->SetLocalDimmingAMD = (PFN_vkSetLocalDimmingAMD)gpa(device, "vkSetLocalDimmingAMD");
-    table->GetBufferDeviceAddressEXT = (PFN_vkGetBufferDeviceAddressEXT)gpa(device, "vkGetBufferDeviceAddressEXT");
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->AcquireFullScreenExclusiveModeEXT =
-        (PFN_vkAcquireFullScreenExclusiveModeEXT)gpa(device, "vkAcquireFullScreenExclusiveModeEXT");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->ReleaseFullScreenExclusiveModeEXT =
-        (PFN_vkReleaseFullScreenExclusiveModeEXT)gpa(device, "vkReleaseFullScreenExclusiveModeEXT");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->GetDeviceGroupSurfacePresentModes2EXT =
-        (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)gpa(device, "vkGetDeviceGroupSurfacePresentModes2EXT");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-    table->CmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT)gpa(device, "vkCmdSetLineStippleEXT");
-    table->ResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)gpa(device, "vkResetQueryPoolEXT");
-    table->CmdSetCullModeEXT = (PFN_vkCmdSetCullModeEXT)gpa(device, "vkCmdSetCullModeEXT");
-    table->CmdSetFrontFaceEXT = (PFN_vkCmdSetFrontFaceEXT)gpa(device, "vkCmdSetFrontFaceEXT");
-    table->CmdSetPrimitiveTopologyEXT = (PFN_vkCmdSetPrimitiveTopologyEXT)gpa(device, "vkCmdSetPrimitiveTopologyEXT");
-    table->CmdSetViewportWithCountEXT = (PFN_vkCmdSetViewportWithCountEXT)gpa(device, "vkCmdSetViewportWithCountEXT");
-    table->CmdSetScissorWithCountEXT = (PFN_vkCmdSetScissorWithCountEXT)gpa(device, "vkCmdSetScissorWithCountEXT");
-    table->CmdBindVertexBuffers2EXT = (PFN_vkCmdBindVertexBuffers2EXT)gpa(device, "vkCmdBindVertexBuffers2EXT");
-    table->CmdSetDepthTestEnableEXT = (PFN_vkCmdSetDepthTestEnableEXT)gpa(device, "vkCmdSetDepthTestEnableEXT");
-    table->CmdSetDepthWriteEnableEXT = (PFN_vkCmdSetDepthWriteEnableEXT)gpa(device, "vkCmdSetDepthWriteEnableEXT");
-    table->CmdSetDepthCompareOpEXT = (PFN_vkCmdSetDepthCompareOpEXT)gpa(device, "vkCmdSetDepthCompareOpEXT");
-    table->CmdSetDepthBoundsTestEnableEXT = (PFN_vkCmdSetDepthBoundsTestEnableEXT)gpa(device, "vkCmdSetDepthBoundsTestEnableEXT");
-    table->CmdSetStencilTestEnableEXT = (PFN_vkCmdSetStencilTestEnableEXT)gpa(device, "vkCmdSetStencilTestEnableEXT");
-    table->CmdSetStencilOpEXT = (PFN_vkCmdSetStencilOpEXT)gpa(device, "vkCmdSetStencilOpEXT");
-    table->ReleaseSwapchainImagesEXT = (PFN_vkReleaseSwapchainImagesEXT)gpa(device, "vkReleaseSwapchainImagesEXT");
-    table->GetGeneratedCommandsMemoryRequirementsNV =
-        (PFN_vkGetGeneratedCommandsMemoryRequirementsNV)gpa(device, "vkGetGeneratedCommandsMemoryRequirementsNV");
-    table->CmdPreprocessGeneratedCommandsNV =
-        (PFN_vkCmdPreprocessGeneratedCommandsNV)gpa(device, "vkCmdPreprocessGeneratedCommandsNV");
-    table->CmdExecuteGeneratedCommandsNV = (PFN_vkCmdExecuteGeneratedCommandsNV)gpa(device, "vkCmdExecuteGeneratedCommandsNV");
-    table->CmdBindPipelineShaderGroupNV = (PFN_vkCmdBindPipelineShaderGroupNV)gpa(device, "vkCmdBindPipelineShaderGroupNV");
-    table->CreateIndirectCommandsLayoutNV = (PFN_vkCreateIndirectCommandsLayoutNV)gpa(device, "vkCreateIndirectCommandsLayoutNV");
-    table->DestroyIndirectCommandsLayoutNV =
-        (PFN_vkDestroyIndirectCommandsLayoutNV)gpa(device, "vkDestroyIndirectCommandsLayoutNV");
-    table->CreatePrivateDataSlotEXT = (PFN_vkCreatePrivateDataSlotEXT)gpa(device, "vkCreatePrivateDataSlotEXT");
-    table->DestroyPrivateDataSlotEXT = (PFN_vkDestroyPrivateDataSlotEXT)gpa(device, "vkDestroyPrivateDataSlotEXT");
-    table->SetPrivateDataEXT = (PFN_vkSetPrivateDataEXT)gpa(device, "vkSetPrivateDataEXT");
-    table->GetPrivateDataEXT = (PFN_vkGetPrivateDataEXT)gpa(device, "vkGetPrivateDataEXT");
-#if defined(VK_USE_PLATFORM_METAL_EXT)
-    table->ExportMetalObjectsEXT = (PFN_vkExportMetalObjectsEXT)gpa(device, "vkExportMetalObjectsEXT");
-#endif  // VK_USE_PLATFORM_METAL_EXT
-    table->GetDescriptorSetLayoutSizeEXT = (PFN_vkGetDescriptorSetLayoutSizeEXT)gpa(device, "vkGetDescriptorSetLayoutSizeEXT");
-    table->GetDescriptorSetLayoutBindingOffsetEXT =
-        (PFN_vkGetDescriptorSetLayoutBindingOffsetEXT)gpa(device, "vkGetDescriptorSetLayoutBindingOffsetEXT");
-    table->GetDescriptorEXT = (PFN_vkGetDescriptorEXT)gpa(device, "vkGetDescriptorEXT");
-    table->CmdBindDescriptorBuffersEXT = (PFN_vkCmdBindDescriptorBuffersEXT)gpa(device, "vkCmdBindDescriptorBuffersEXT");
-    table->CmdSetDescriptorBufferOffsetsEXT =
-        (PFN_vkCmdSetDescriptorBufferOffsetsEXT)gpa(device, "vkCmdSetDescriptorBufferOffsetsEXT");
-    table->CmdBindDescriptorBufferEmbeddedSamplersEXT =
-        (PFN_vkCmdBindDescriptorBufferEmbeddedSamplersEXT)gpa(device, "vkCmdBindDescriptorBufferEmbeddedSamplersEXT");
-    table->GetBufferOpaqueCaptureDescriptorDataEXT =
-        (PFN_vkGetBufferOpaqueCaptureDescriptorDataEXT)gpa(device, "vkGetBufferOpaqueCaptureDescriptorDataEXT");
-    table->GetImageOpaqueCaptureDescriptorDataEXT =
-        (PFN_vkGetImageOpaqueCaptureDescriptorDataEXT)gpa(device, "vkGetImageOpaqueCaptureDescriptorDataEXT");
-    table->GetImageViewOpaqueCaptureDescriptorDataEXT =
-        (PFN_vkGetImageViewOpaqueCaptureDescriptorDataEXT)gpa(device, "vkGetImageViewOpaqueCaptureDescriptorDataEXT");
-    table->GetSamplerOpaqueCaptureDescriptorDataEXT =
-        (PFN_vkGetSamplerOpaqueCaptureDescriptorDataEXT)gpa(device, "vkGetSamplerOpaqueCaptureDescriptorDataEXT");
-    table->GetAccelerationStructureOpaqueCaptureDescriptorDataEXT =
-        (PFN_vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT)gpa(
-            device, "vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT");
-    table->CmdSetFragmentShadingRateEnumNV =
-        (PFN_vkCmdSetFragmentShadingRateEnumNV)gpa(device, "vkCmdSetFragmentShadingRateEnumNV");
-    table->GetImageSubresourceLayout2EXT = (PFN_vkGetImageSubresourceLayout2EXT)gpa(device, "vkGetImageSubresourceLayout2EXT");
-    table->GetDeviceFaultInfoEXT = (PFN_vkGetDeviceFaultInfoEXT)gpa(device, "vkGetDeviceFaultInfoEXT");
-    table->CmdSetVertexInputEXT = (PFN_vkCmdSetVertexInputEXT)gpa(device, "vkCmdSetVertexInputEXT");
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    table->GetMemoryZirconHandleFUCHSIA = (PFN_vkGetMemoryZirconHandleFUCHSIA)gpa(device, "vkGetMemoryZirconHandleFUCHSIA");
-#endif  // VK_USE_PLATFORM_FUCHSIA
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    table->GetMemoryZirconHandlePropertiesFUCHSIA =
-        (PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA)gpa(device, "vkGetMemoryZirconHandlePropertiesFUCHSIA");
-#endif  // VK_USE_PLATFORM_FUCHSIA
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    table->ImportSemaphoreZirconHandleFUCHSIA =
-        (PFN_vkImportSemaphoreZirconHandleFUCHSIA)gpa(device, "vkImportSemaphoreZirconHandleFUCHSIA");
-#endif  // VK_USE_PLATFORM_FUCHSIA
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    table->GetSemaphoreZirconHandleFUCHSIA =
-        (PFN_vkGetSemaphoreZirconHandleFUCHSIA)gpa(device, "vkGetSemaphoreZirconHandleFUCHSIA");
-#endif  // VK_USE_PLATFORM_FUCHSIA
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    table->CreateBufferCollectionFUCHSIA = (PFN_vkCreateBufferCollectionFUCHSIA)gpa(device, "vkCreateBufferCollectionFUCHSIA");
-#endif  // VK_USE_PLATFORM_FUCHSIA
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    table->SetBufferCollectionImageConstraintsFUCHSIA =
-        (PFN_vkSetBufferCollectionImageConstraintsFUCHSIA)gpa(device, "vkSetBufferCollectionImageConstraintsFUCHSIA");
-#endif  // VK_USE_PLATFORM_FUCHSIA
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    table->SetBufferCollectionBufferConstraintsFUCHSIA =
-        (PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA)gpa(device, "vkSetBufferCollectionBufferConstraintsFUCHSIA");
-#endif  // VK_USE_PLATFORM_FUCHSIA
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    table->DestroyBufferCollectionFUCHSIA = (PFN_vkDestroyBufferCollectionFUCHSIA)gpa(device, "vkDestroyBufferCollectionFUCHSIA");
-#endif  // VK_USE_PLATFORM_FUCHSIA
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    table->GetBufferCollectionPropertiesFUCHSIA =
-        (PFN_vkGetBufferCollectionPropertiesFUCHSIA)gpa(device, "vkGetBufferCollectionPropertiesFUCHSIA");
-#endif  // VK_USE_PLATFORM_FUCHSIA
-    table->GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI =
-        (PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)gpa(device, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
-    table->CmdSubpassShadingHUAWEI = (PFN_vkCmdSubpassShadingHUAWEI)gpa(device, "vkCmdSubpassShadingHUAWEI");
-    table->CmdBindInvocationMaskHUAWEI = (PFN_vkCmdBindInvocationMaskHUAWEI)gpa(device, "vkCmdBindInvocationMaskHUAWEI");
-    table->GetMemoryRemoteAddressNV = (PFN_vkGetMemoryRemoteAddressNV)gpa(device, "vkGetMemoryRemoteAddressNV");
-    table->GetPipelinePropertiesEXT = (PFN_vkGetPipelinePropertiesEXT)gpa(device, "vkGetPipelinePropertiesEXT");
-    table->CmdSetPatchControlPointsEXT = (PFN_vkCmdSetPatchControlPointsEXT)gpa(device, "vkCmdSetPatchControlPointsEXT");
-    table->CmdSetRasterizerDiscardEnableEXT =
-        (PFN_vkCmdSetRasterizerDiscardEnableEXT)gpa(device, "vkCmdSetRasterizerDiscardEnableEXT");
-    table->CmdSetDepthBiasEnableEXT = (PFN_vkCmdSetDepthBiasEnableEXT)gpa(device, "vkCmdSetDepthBiasEnableEXT");
-    table->CmdSetLogicOpEXT = (PFN_vkCmdSetLogicOpEXT)gpa(device, "vkCmdSetLogicOpEXT");
-    table->CmdSetPrimitiveRestartEnableEXT =
-        (PFN_vkCmdSetPrimitiveRestartEnableEXT)gpa(device, "vkCmdSetPrimitiveRestartEnableEXT");
-    table->CmdSetColorWriteEnableEXT = (PFN_vkCmdSetColorWriteEnableEXT)gpa(device, "vkCmdSetColorWriteEnableEXT");
-    table->CmdDrawMultiEXT = (PFN_vkCmdDrawMultiEXT)gpa(device, "vkCmdDrawMultiEXT");
-    table->CmdDrawMultiIndexedEXT = (PFN_vkCmdDrawMultiIndexedEXT)gpa(device, "vkCmdDrawMultiIndexedEXT");
-    table->CreateMicromapEXT = (PFN_vkCreateMicromapEXT)gpa(device, "vkCreateMicromapEXT");
-    table->DestroyMicromapEXT = (PFN_vkDestroyMicromapEXT)gpa(device, "vkDestroyMicromapEXT");
-    table->CmdBuildMicromapsEXT = (PFN_vkCmdBuildMicromapsEXT)gpa(device, "vkCmdBuildMicromapsEXT");
-    table->BuildMicromapsEXT = (PFN_vkBuildMicromapsEXT)gpa(device, "vkBuildMicromapsEXT");
-    table->CopyMicromapEXT = (PFN_vkCopyMicromapEXT)gpa(device, "vkCopyMicromapEXT");
-    table->CopyMicromapToMemoryEXT = (PFN_vkCopyMicromapToMemoryEXT)gpa(device, "vkCopyMicromapToMemoryEXT");
-    table->CopyMemoryToMicromapEXT = (PFN_vkCopyMemoryToMicromapEXT)gpa(device, "vkCopyMemoryToMicromapEXT");
-    table->WriteMicromapsPropertiesEXT = (PFN_vkWriteMicromapsPropertiesEXT)gpa(device, "vkWriteMicromapsPropertiesEXT");
-    table->CmdCopyMicromapEXT = (PFN_vkCmdCopyMicromapEXT)gpa(device, "vkCmdCopyMicromapEXT");
-    table->CmdCopyMicromapToMemoryEXT = (PFN_vkCmdCopyMicromapToMemoryEXT)gpa(device, "vkCmdCopyMicromapToMemoryEXT");
-    table->CmdCopyMemoryToMicromapEXT = (PFN_vkCmdCopyMemoryToMicromapEXT)gpa(device, "vkCmdCopyMemoryToMicromapEXT");
-    table->CmdWriteMicromapsPropertiesEXT = (PFN_vkCmdWriteMicromapsPropertiesEXT)gpa(device, "vkCmdWriteMicromapsPropertiesEXT");
-    table->GetDeviceMicromapCompatibilityEXT =
-        (PFN_vkGetDeviceMicromapCompatibilityEXT)gpa(device, "vkGetDeviceMicromapCompatibilityEXT");
-    table->GetMicromapBuildSizesEXT = (PFN_vkGetMicromapBuildSizesEXT)gpa(device, "vkGetMicromapBuildSizesEXT");
-    table->CmdDrawClusterHUAWEI = (PFN_vkCmdDrawClusterHUAWEI)gpa(device, "vkCmdDrawClusterHUAWEI");
-    table->CmdDrawClusterIndirectHUAWEI = (PFN_vkCmdDrawClusterIndirectHUAWEI)gpa(device, "vkCmdDrawClusterIndirectHUAWEI");
-    table->SetDeviceMemoryPriorityEXT = (PFN_vkSetDeviceMemoryPriorityEXT)gpa(device, "vkSetDeviceMemoryPriorityEXT");
-    table->GetDescriptorSetLayoutHostMappingInfoVALVE =
-        (PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE)gpa(device, "vkGetDescriptorSetLayoutHostMappingInfoVALVE");
-    table->GetDescriptorSetHostMappingVALVE =
-        (PFN_vkGetDescriptorSetHostMappingVALVE)gpa(device, "vkGetDescriptorSetHostMappingVALVE");
-    table->CmdCopyMemoryIndirectNV = (PFN_vkCmdCopyMemoryIndirectNV)gpa(device, "vkCmdCopyMemoryIndirectNV");
-    table->CmdCopyMemoryToImageIndirectNV = (PFN_vkCmdCopyMemoryToImageIndirectNV)gpa(device, "vkCmdCopyMemoryToImageIndirectNV");
-    table->CmdDecompressMemoryNV = (PFN_vkCmdDecompressMemoryNV)gpa(device, "vkCmdDecompressMemoryNV");
-    table->CmdDecompressMemoryIndirectCountNV =
-        (PFN_vkCmdDecompressMemoryIndirectCountNV)gpa(device, "vkCmdDecompressMemoryIndirectCountNV");
-    table->CmdSetTessellationDomainOriginEXT =
-        (PFN_vkCmdSetTessellationDomainOriginEXT)gpa(device, "vkCmdSetTessellationDomainOriginEXT");
-    table->CmdSetDepthClampEnableEXT = (PFN_vkCmdSetDepthClampEnableEXT)gpa(device, "vkCmdSetDepthClampEnableEXT");
-    table->CmdSetPolygonModeEXT = (PFN_vkCmdSetPolygonModeEXT)gpa(device, "vkCmdSetPolygonModeEXT");
-    table->CmdSetRasterizationSamplesEXT = (PFN_vkCmdSetRasterizationSamplesEXT)gpa(device, "vkCmdSetRasterizationSamplesEXT");
-    table->CmdSetSampleMaskEXT = (PFN_vkCmdSetSampleMaskEXT)gpa(device, "vkCmdSetSampleMaskEXT");
-    table->CmdSetAlphaToCoverageEnableEXT = (PFN_vkCmdSetAlphaToCoverageEnableEXT)gpa(device, "vkCmdSetAlphaToCoverageEnableEXT");
-    table->CmdSetAlphaToOneEnableEXT = (PFN_vkCmdSetAlphaToOneEnableEXT)gpa(device, "vkCmdSetAlphaToOneEnableEXT");
-    table->CmdSetLogicOpEnableEXT = (PFN_vkCmdSetLogicOpEnableEXT)gpa(device, "vkCmdSetLogicOpEnableEXT");
-    table->CmdSetColorBlendEnableEXT = (PFN_vkCmdSetColorBlendEnableEXT)gpa(device, "vkCmdSetColorBlendEnableEXT");
-    table->CmdSetColorBlendEquationEXT = (PFN_vkCmdSetColorBlendEquationEXT)gpa(device, "vkCmdSetColorBlendEquationEXT");
-    table->CmdSetColorWriteMaskEXT = (PFN_vkCmdSetColorWriteMaskEXT)gpa(device, "vkCmdSetColorWriteMaskEXT");
-    table->CmdSetRasterizationStreamEXT = (PFN_vkCmdSetRasterizationStreamEXT)gpa(device, "vkCmdSetRasterizationStreamEXT");
-    table->CmdSetConservativeRasterizationModeEXT =
-        (PFN_vkCmdSetConservativeRasterizationModeEXT)gpa(device, "vkCmdSetConservativeRasterizationModeEXT");
-    table->CmdSetExtraPrimitiveOverestimationSizeEXT =
-        (PFN_vkCmdSetExtraPrimitiveOverestimationSizeEXT)gpa(device, "vkCmdSetExtraPrimitiveOverestimationSizeEXT");
-    table->CmdSetDepthClipEnableEXT = (PFN_vkCmdSetDepthClipEnableEXT)gpa(device, "vkCmdSetDepthClipEnableEXT");
-    table->CmdSetSampleLocationsEnableEXT = (PFN_vkCmdSetSampleLocationsEnableEXT)gpa(device, "vkCmdSetSampleLocationsEnableEXT");
-    table->CmdSetColorBlendAdvancedEXT = (PFN_vkCmdSetColorBlendAdvancedEXT)gpa(device, "vkCmdSetColorBlendAdvancedEXT");
-    table->CmdSetProvokingVertexModeEXT = (PFN_vkCmdSetProvokingVertexModeEXT)gpa(device, "vkCmdSetProvokingVertexModeEXT");
-    table->CmdSetLineRasterizationModeEXT = (PFN_vkCmdSetLineRasterizationModeEXT)gpa(device, "vkCmdSetLineRasterizationModeEXT");
-    table->CmdSetLineStippleEnableEXT = (PFN_vkCmdSetLineStippleEnableEXT)gpa(device, "vkCmdSetLineStippleEnableEXT");
-    table->CmdSetDepthClipNegativeOneToOneEXT =
-        (PFN_vkCmdSetDepthClipNegativeOneToOneEXT)gpa(device, "vkCmdSetDepthClipNegativeOneToOneEXT");
-    table->CmdSetViewportWScalingEnableNV = (PFN_vkCmdSetViewportWScalingEnableNV)gpa(device, "vkCmdSetViewportWScalingEnableNV");
-    table->CmdSetViewportSwizzleNV = (PFN_vkCmdSetViewportSwizzleNV)gpa(device, "vkCmdSetViewportSwizzleNV");
-    table->CmdSetCoverageToColorEnableNV = (PFN_vkCmdSetCoverageToColorEnableNV)gpa(device, "vkCmdSetCoverageToColorEnableNV");
-    table->CmdSetCoverageToColorLocationNV =
-        (PFN_vkCmdSetCoverageToColorLocationNV)gpa(device, "vkCmdSetCoverageToColorLocationNV");
-    table->CmdSetCoverageModulationModeNV = (PFN_vkCmdSetCoverageModulationModeNV)gpa(device, "vkCmdSetCoverageModulationModeNV");
-    table->CmdSetCoverageModulationTableEnableNV =
-        (PFN_vkCmdSetCoverageModulationTableEnableNV)gpa(device, "vkCmdSetCoverageModulationTableEnableNV");
-    table->CmdSetCoverageModulationTableNV =
-        (PFN_vkCmdSetCoverageModulationTableNV)gpa(device, "vkCmdSetCoverageModulationTableNV");
-    table->CmdSetShadingRateImageEnableNV = (PFN_vkCmdSetShadingRateImageEnableNV)gpa(device, "vkCmdSetShadingRateImageEnableNV");
-    table->CmdSetRepresentativeFragmentTestEnableNV =
-        (PFN_vkCmdSetRepresentativeFragmentTestEnableNV)gpa(device, "vkCmdSetRepresentativeFragmentTestEnableNV");
-    table->CmdSetCoverageReductionModeNV = (PFN_vkCmdSetCoverageReductionModeNV)gpa(device, "vkCmdSetCoverageReductionModeNV");
-    table->GetShaderModuleIdentifierEXT = (PFN_vkGetShaderModuleIdentifierEXT)gpa(device, "vkGetShaderModuleIdentifierEXT");
-    table->GetShaderModuleCreateInfoIdentifierEXT =
-        (PFN_vkGetShaderModuleCreateInfoIdentifierEXT)gpa(device, "vkGetShaderModuleCreateInfoIdentifierEXT");
-    table->CreateOpticalFlowSessionNV = (PFN_vkCreateOpticalFlowSessionNV)gpa(device, "vkCreateOpticalFlowSessionNV");
-    table->DestroyOpticalFlowSessionNV = (PFN_vkDestroyOpticalFlowSessionNV)gpa(device, "vkDestroyOpticalFlowSessionNV");
-    table->BindOpticalFlowSessionImageNV = (PFN_vkBindOpticalFlowSessionImageNV)gpa(device, "vkBindOpticalFlowSessionImageNV");
-    table->CmdOpticalFlowExecuteNV = (PFN_vkCmdOpticalFlowExecuteNV)gpa(device, "vkCmdOpticalFlowExecuteNV");
-    table->CreateShadersEXT = (PFN_vkCreateShadersEXT)gpa(device, "vkCreateShadersEXT");
-    table->DestroyShaderEXT = (PFN_vkDestroyShaderEXT)gpa(device, "vkDestroyShaderEXT");
-    table->GetShaderBinaryDataEXT = (PFN_vkGetShaderBinaryDataEXT)gpa(device, "vkGetShaderBinaryDataEXT");
-    table->CmdBindShadersEXT = (PFN_vkCmdBindShadersEXT)gpa(device, "vkCmdBindShadersEXT");
-    table->GetFramebufferTilePropertiesQCOM =
-        (PFN_vkGetFramebufferTilePropertiesQCOM)gpa(device, "vkGetFramebufferTilePropertiesQCOM");
-    table->GetDynamicRenderingTilePropertiesQCOM =
-        (PFN_vkGetDynamicRenderingTilePropertiesQCOM)gpa(device, "vkGetDynamicRenderingTilePropertiesQCOM");
-    table->CmdSetAttachmentFeedbackLoopEnableEXT =
-        (PFN_vkCmdSetAttachmentFeedbackLoopEnableEXT)gpa(device, "vkCmdSetAttachmentFeedbackLoopEnableEXT");
-    table->CreateAccelerationStructureKHR = (PFN_vkCreateAccelerationStructureKHR)gpa(device, "vkCreateAccelerationStructureKHR");
-    table->DestroyAccelerationStructureKHR =
-        (PFN_vkDestroyAccelerationStructureKHR)gpa(device, "vkDestroyAccelerationStructureKHR");
-    table->CmdBuildAccelerationStructuresKHR =
-        (PFN_vkCmdBuildAccelerationStructuresKHR)gpa(device, "vkCmdBuildAccelerationStructuresKHR");
-    table->CmdBuildAccelerationStructuresIndirectKHR =
-        (PFN_vkCmdBuildAccelerationStructuresIndirectKHR)gpa(device, "vkCmdBuildAccelerationStructuresIndirectKHR");
-    table->BuildAccelerationStructuresKHR = (PFN_vkBuildAccelerationStructuresKHR)gpa(device, "vkBuildAccelerationStructuresKHR");
-    table->CopyAccelerationStructureKHR = (PFN_vkCopyAccelerationStructureKHR)gpa(device, "vkCopyAccelerationStructureKHR");
-    table->CopyAccelerationStructureToMemoryKHR =
-        (PFN_vkCopyAccelerationStructureToMemoryKHR)gpa(device, "vkCopyAccelerationStructureToMemoryKHR");
-    table->CopyMemoryToAccelerationStructureKHR =
-        (PFN_vkCopyMemoryToAccelerationStructureKHR)gpa(device, "vkCopyMemoryToAccelerationStructureKHR");
-    table->WriteAccelerationStructuresPropertiesKHR =
-        (PFN_vkWriteAccelerationStructuresPropertiesKHR)gpa(device, "vkWriteAccelerationStructuresPropertiesKHR");
-    table->CmdCopyAccelerationStructureKHR =
-        (PFN_vkCmdCopyAccelerationStructureKHR)gpa(device, "vkCmdCopyAccelerationStructureKHR");
-    table->CmdCopyAccelerationStructureToMemoryKHR =
-        (PFN_vkCmdCopyAccelerationStructureToMemoryKHR)gpa(device, "vkCmdCopyAccelerationStructureToMemoryKHR");
-    table->CmdCopyMemoryToAccelerationStructureKHR =
-        (PFN_vkCmdCopyMemoryToAccelerationStructureKHR)gpa(device, "vkCmdCopyMemoryToAccelerationStructureKHR");
-    table->GetAccelerationStructureDeviceAddressKHR =
-        (PFN_vkGetAccelerationStructureDeviceAddressKHR)gpa(device, "vkGetAccelerationStructureDeviceAddressKHR");
-    table->CmdWriteAccelerationStructuresPropertiesKHR =
-        (PFN_vkCmdWriteAccelerationStructuresPropertiesKHR)gpa(device, "vkCmdWriteAccelerationStructuresPropertiesKHR");
-    table->GetDeviceAccelerationStructureCompatibilityKHR =
-        (PFN_vkGetDeviceAccelerationStructureCompatibilityKHR)gpa(device, "vkGetDeviceAccelerationStructureCompatibilityKHR");
-    table->GetAccelerationStructureBuildSizesKHR =
-        (PFN_vkGetAccelerationStructureBuildSizesKHR)gpa(device, "vkGetAccelerationStructureBuildSizesKHR");
-    table->CmdTraceRaysKHR = (PFN_vkCmdTraceRaysKHR)gpa(device, "vkCmdTraceRaysKHR");
-    table->CreateRayTracingPipelinesKHR = (PFN_vkCreateRayTracingPipelinesKHR)gpa(device, "vkCreateRayTracingPipelinesKHR");
-    table->GetRayTracingCaptureReplayShaderGroupHandlesKHR =
-        (PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR)gpa(device, "vkGetRayTracingCaptureReplayShaderGroupHandlesKHR");
-    table->CmdTraceRaysIndirectKHR = (PFN_vkCmdTraceRaysIndirectKHR)gpa(device, "vkCmdTraceRaysIndirectKHR");
-    table->GetRayTracingShaderGroupStackSizeKHR =
-        (PFN_vkGetRayTracingShaderGroupStackSizeKHR)gpa(device, "vkGetRayTracingShaderGroupStackSizeKHR");
-    table->CmdSetRayTracingPipelineStackSizeKHR =
-        (PFN_vkCmdSetRayTracingPipelineStackSizeKHR)gpa(device, "vkCmdSetRayTracingPipelineStackSizeKHR");
-    table->CmdDrawMeshTasksEXT = (PFN_vkCmdDrawMeshTasksEXT)gpa(device, "vkCmdDrawMeshTasksEXT");
-    table->CmdDrawMeshTasksIndirectEXT = (PFN_vkCmdDrawMeshTasksIndirectEXT)gpa(device, "vkCmdDrawMeshTasksIndirectEXT");
-    table->CmdDrawMeshTasksIndirectCountEXT =
-        (PFN_vkCmdDrawMeshTasksIndirectCountEXT)gpa(device, "vkCmdDrawMeshTasksIndirectCountEXT");
-}
-
-static inline void layer_init_instance_dispatch_table(VkInstance instance, VkLayerInstanceDispatchTable *table,
-                                                      PFN_vkGetInstanceProcAddr gpa) {
-    memset(table, 0, sizeof(*table));
-
-    // Instance function pointers
-    table->DestroyInstance = (PFN_vkDestroyInstance)gpa(instance, "vkDestroyInstance");
-    table->EnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices)gpa(instance, "vkEnumeratePhysicalDevices");
-    table->GetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures)gpa(instance, "vkGetPhysicalDeviceFeatures");
-    table->GetPhysicalDeviceFormatProperties =
-        (PFN_vkGetPhysicalDeviceFormatProperties)gpa(instance, "vkGetPhysicalDeviceFormatProperties");
-    table->GetPhysicalDeviceImageFormatProperties =
-        (PFN_vkGetPhysicalDeviceImageFormatProperties)gpa(instance, "vkGetPhysicalDeviceImageFormatProperties");
-    table->GetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)gpa(instance, "vkGetPhysicalDeviceProperties");
-    table->GetPhysicalDeviceQueueFamilyProperties =
-        (PFN_vkGetPhysicalDeviceQueueFamilyProperties)gpa(instance, "vkGetPhysicalDeviceQueueFamilyProperties");
-    table->GetPhysicalDeviceMemoryProperties =
-        (PFN_vkGetPhysicalDeviceMemoryProperties)gpa(instance, "vkGetPhysicalDeviceMemoryProperties");
-    table->GetInstanceProcAddr = gpa;
-    table->EnumerateDeviceExtensionProperties =
-        (PFN_vkEnumerateDeviceExtensionProperties)gpa(instance, "vkEnumerateDeviceExtensionProperties");
-    table->EnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties)gpa(instance, "vkEnumerateDeviceLayerProperties");
-    table->GetPhysicalDeviceSparseImageFormatProperties =
-        (PFN_vkGetPhysicalDeviceSparseImageFormatProperties)gpa(instance, "vkGetPhysicalDeviceSparseImageFormatProperties");
-    table->EnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups)gpa(instance, "vkEnumeratePhysicalDeviceGroups");
-    table->GetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2)gpa(instance, "vkGetPhysicalDeviceFeatures2");
-    table->GetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2)gpa(instance, "vkGetPhysicalDeviceProperties2");
-    table->GetPhysicalDeviceFormatProperties2 =
-        (PFN_vkGetPhysicalDeviceFormatProperties2)gpa(instance, "vkGetPhysicalDeviceFormatProperties2");
-    table->GetPhysicalDeviceImageFormatProperties2 =
-        (PFN_vkGetPhysicalDeviceImageFormatProperties2)gpa(instance, "vkGetPhysicalDeviceImageFormatProperties2");
-    table->GetPhysicalDeviceQueueFamilyProperties2 =
-        (PFN_vkGetPhysicalDeviceQueueFamilyProperties2)gpa(instance, "vkGetPhysicalDeviceQueueFamilyProperties2");
-    table->GetPhysicalDeviceMemoryProperties2 =
-        (PFN_vkGetPhysicalDeviceMemoryProperties2)gpa(instance, "vkGetPhysicalDeviceMemoryProperties2");
-    table->GetPhysicalDeviceSparseImageFormatProperties2 =
-        (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)gpa(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2");
-    table->GetPhysicalDeviceExternalBufferProperties =
-        (PFN_vkGetPhysicalDeviceExternalBufferProperties)gpa(instance, "vkGetPhysicalDeviceExternalBufferProperties");
-    table->GetPhysicalDeviceExternalFenceProperties =
-        (PFN_vkGetPhysicalDeviceExternalFenceProperties)gpa(instance, "vkGetPhysicalDeviceExternalFenceProperties");
-    table->GetPhysicalDeviceExternalSemaphoreProperties =
-        (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)gpa(instance, "vkGetPhysicalDeviceExternalSemaphoreProperties");
-    table->GetPhysicalDeviceToolProperties =
-        (PFN_vkGetPhysicalDeviceToolProperties)gpa(instance, "vkGetPhysicalDeviceToolProperties");
-    table->DestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)gpa(instance, "vkDestroySurfaceKHR");
-    table->GetPhysicalDeviceSurfaceSupportKHR =
-        (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
-    table->GetPhysicalDeviceSurfaceCapabilitiesKHR =
-        (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
-    table->GetPhysicalDeviceSurfaceFormatsKHR =
-        (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
-    table->GetPhysicalDeviceSurfacePresentModesKHR =
-        (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
-    table->GetPhysicalDevicePresentRectanglesKHR =
-        (PFN_vkGetPhysicalDevicePresentRectanglesKHR)gpa(instance, "vkGetPhysicalDevicePresentRectanglesKHR");
-    table->GetPhysicalDeviceDisplayPropertiesKHR =
-        (PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)gpa(instance, "vkGetPhysicalDeviceDisplayPropertiesKHR");
-    table->GetPhysicalDeviceDisplayPlanePropertiesKHR =
-        (PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)gpa(instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
-    table->GetDisplayPlaneSupportedDisplaysKHR =
-        (PFN_vkGetDisplayPlaneSupportedDisplaysKHR)gpa(instance, "vkGetDisplayPlaneSupportedDisplaysKHR");
-    table->GetDisplayModePropertiesKHR = (PFN_vkGetDisplayModePropertiesKHR)gpa(instance, "vkGetDisplayModePropertiesKHR");
-    table->CreateDisplayModeKHR = (PFN_vkCreateDisplayModeKHR)gpa(instance, "vkCreateDisplayModeKHR");
-    table->GetDisplayPlaneCapabilitiesKHR = (PFN_vkGetDisplayPlaneCapabilitiesKHR)gpa(instance, "vkGetDisplayPlaneCapabilitiesKHR");
-    table->CreateDisplayPlaneSurfaceKHR = (PFN_vkCreateDisplayPlaneSurfaceKHR)gpa(instance, "vkCreateDisplayPlaneSurfaceKHR");
-#if defined(VK_USE_PLATFORM_XLIB_KHR)
-    table->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)gpa(instance, "vkCreateXlibSurfaceKHR");
-#endif  // VK_USE_PLATFORM_XLIB_KHR
-#if defined(VK_USE_PLATFORM_XLIB_KHR)
-    table->GetPhysicalDeviceXlibPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
-#endif  // VK_USE_PLATFORM_XLIB_KHR
-#if defined(VK_USE_PLATFORM_XCB_KHR)
-    table->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)gpa(instance, "vkCreateXcbSurfaceKHR");
-#endif  // VK_USE_PLATFORM_XCB_KHR
-#if defined(VK_USE_PLATFORM_XCB_KHR)
-    table->GetPhysicalDeviceXcbPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
-#endif  // VK_USE_PLATFORM_XCB_KHR
-#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
-    table->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)gpa(instance, "vkCreateWaylandSurfaceKHR");
-#endif  // VK_USE_PLATFORM_WAYLAND_KHR
-#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
-    table->GetPhysicalDeviceWaylandPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
-#endif  // VK_USE_PLATFORM_WAYLAND_KHR
-#if defined(VK_USE_PLATFORM_ANDROID_KHR)
-    table->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)gpa(instance, "vkCreateAndroidSurfaceKHR");
-#endif  // VK_USE_PLATFORM_ANDROID_KHR
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)gpa(instance, "vkCreateWin32SurfaceKHR");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->GetPhysicalDeviceWin32PresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-    table->GetPhysicalDeviceVideoCapabilitiesKHR =
-        (PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR)gpa(instance, "vkGetPhysicalDeviceVideoCapabilitiesKHR");
-    table->GetPhysicalDeviceVideoFormatPropertiesKHR =
-        (PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR)gpa(instance, "vkGetPhysicalDeviceVideoFormatPropertiesKHR");
-    table->GetPhysicalDeviceFeatures2KHR = (PFN_vkGetPhysicalDeviceFeatures2KHR)gpa(instance, "vkGetPhysicalDeviceFeatures2KHR");
-    table->GetPhysicalDeviceProperties2KHR =
-        (PFN_vkGetPhysicalDeviceProperties2KHR)gpa(instance, "vkGetPhysicalDeviceProperties2KHR");
-    table->GetPhysicalDeviceFormatProperties2KHR =
-        (PFN_vkGetPhysicalDeviceFormatProperties2KHR)gpa(instance, "vkGetPhysicalDeviceFormatProperties2KHR");
-    table->GetPhysicalDeviceImageFormatProperties2KHR =
-        (PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)gpa(instance, "vkGetPhysicalDeviceImageFormatProperties2KHR");
-    table->GetPhysicalDeviceQueueFamilyProperties2KHR =
-        (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)gpa(instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR");
-    table->GetPhysicalDeviceMemoryProperties2KHR =
-        (PFN_vkGetPhysicalDeviceMemoryProperties2KHR)gpa(instance, "vkGetPhysicalDeviceMemoryProperties2KHR");
-    table->GetPhysicalDeviceSparseImageFormatProperties2KHR =
-        (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)gpa(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR");
-    table->EnumeratePhysicalDeviceGroupsKHR =
-        (PFN_vkEnumeratePhysicalDeviceGroupsKHR)gpa(instance, "vkEnumeratePhysicalDeviceGroupsKHR");
-    table->GetPhysicalDeviceExternalBufferPropertiesKHR =
-        (PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)gpa(instance, "vkGetPhysicalDeviceExternalBufferPropertiesKHR");
-    table->GetPhysicalDeviceExternalSemaphorePropertiesKHR =
-        (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)gpa(instance, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
-    table->GetPhysicalDeviceExternalFencePropertiesKHR =
-        (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)gpa(instance, "vkGetPhysicalDeviceExternalFencePropertiesKHR");
-    table->EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR =
-        (PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)gpa(
-            instance, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
-    table->GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR = (PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR)gpa(
-        instance, "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR");
-    table->GetPhysicalDeviceSurfaceCapabilities2KHR =
-        (PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilities2KHR");
-    table->GetPhysicalDeviceSurfaceFormats2KHR =
-        (PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)gpa(instance, "vkGetPhysicalDeviceSurfaceFormats2KHR");
-    table->GetPhysicalDeviceDisplayProperties2KHR =
-        (PFN_vkGetPhysicalDeviceDisplayProperties2KHR)gpa(instance, "vkGetPhysicalDeviceDisplayProperties2KHR");
-    table->GetPhysicalDeviceDisplayPlaneProperties2KHR =
-        (PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR)gpa(instance, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR");
-    table->GetDisplayModeProperties2KHR = (PFN_vkGetDisplayModeProperties2KHR)gpa(instance, "vkGetDisplayModeProperties2KHR");
-    table->GetDisplayPlaneCapabilities2KHR =
-        (PFN_vkGetDisplayPlaneCapabilities2KHR)gpa(instance, "vkGetDisplayPlaneCapabilities2KHR");
-    table->GetPhysicalDeviceFragmentShadingRatesKHR =
-        (PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR)gpa(instance, "vkGetPhysicalDeviceFragmentShadingRatesKHR");
-#if defined(VK_ENABLE_BETA_EXTENSIONS)
-    table->GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR = (PFN_vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR)gpa(
-        instance, "vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR");
-#endif  // VK_ENABLE_BETA_EXTENSIONS
-    table->CreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)gpa(instance, "vkCreateDebugReportCallbackEXT");
-    table->DestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)gpa(instance, "vkDestroyDebugReportCallbackEXT");
-    table->DebugReportMessageEXT = (PFN_vkDebugReportMessageEXT)gpa(instance, "vkDebugReportMessageEXT");
-#if defined(VK_USE_PLATFORM_GGP)
-    table->CreateStreamDescriptorSurfaceGGP =
-        (PFN_vkCreateStreamDescriptorSurfaceGGP)gpa(instance, "vkCreateStreamDescriptorSurfaceGGP");
-#endif  // VK_USE_PLATFORM_GGP
-    table->GetPhysicalDeviceExternalImageFormatPropertiesNV =
-        (PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV)gpa(instance, "vkGetPhysicalDeviceExternalImageFormatPropertiesNV");
-#if defined(VK_USE_PLATFORM_VI_NN)
-    table->CreateViSurfaceNN = (PFN_vkCreateViSurfaceNN)gpa(instance, "vkCreateViSurfaceNN");
-#endif  // VK_USE_PLATFORM_VI_NN
-    table->ReleaseDisplayEXT = (PFN_vkReleaseDisplayEXT)gpa(instance, "vkReleaseDisplayEXT");
-#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
-    table->AcquireXlibDisplayEXT = (PFN_vkAcquireXlibDisplayEXT)gpa(instance, "vkAcquireXlibDisplayEXT");
-#endif  // VK_USE_PLATFORM_XLIB_XRANDR_EXT
-#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
-    table->GetRandROutputDisplayEXT = (PFN_vkGetRandROutputDisplayEXT)gpa(instance, "vkGetRandROutputDisplayEXT");
-#endif  // VK_USE_PLATFORM_XLIB_XRANDR_EXT
-    table->GetPhysicalDeviceSurfaceCapabilities2EXT =
-        (PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilities2EXT");
-#if defined(VK_USE_PLATFORM_IOS_MVK)
-    table->CreateIOSSurfaceMVK = (PFN_vkCreateIOSSurfaceMVK)gpa(instance, "vkCreateIOSSurfaceMVK");
-#endif  // VK_USE_PLATFORM_IOS_MVK
-#if defined(VK_USE_PLATFORM_MACOS_MVK)
-    table->CreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)gpa(instance, "vkCreateMacOSSurfaceMVK");
-#endif  // VK_USE_PLATFORM_MACOS_MVK
-    table->CreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT)gpa(instance, "vkCreateDebugUtilsMessengerEXT");
-    table->DestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT)gpa(instance, "vkDestroyDebugUtilsMessengerEXT");
-    table->SubmitDebugUtilsMessageEXT = (PFN_vkSubmitDebugUtilsMessageEXT)gpa(instance, "vkSubmitDebugUtilsMessageEXT");
-    table->GetPhysicalDeviceMultisamplePropertiesEXT =
-        (PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT)gpa(instance, "vkGetPhysicalDeviceMultisamplePropertiesEXT");
-    table->GetPhysicalDeviceCalibrateableTimeDomainsEXT =
-        (PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)gpa(instance, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT");
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    table->CreateImagePipeSurfaceFUCHSIA = (PFN_vkCreateImagePipeSurfaceFUCHSIA)gpa(instance, "vkCreateImagePipeSurfaceFUCHSIA");
-#endif  // VK_USE_PLATFORM_FUCHSIA
-#if defined(VK_USE_PLATFORM_METAL_EXT)
-    table->CreateMetalSurfaceEXT = (PFN_vkCreateMetalSurfaceEXT)gpa(instance, "vkCreateMetalSurfaceEXT");
-#endif  // VK_USE_PLATFORM_METAL_EXT
-    table->GetPhysicalDeviceToolPropertiesEXT =
-        (PFN_vkGetPhysicalDeviceToolPropertiesEXT)gpa(instance, "vkGetPhysicalDeviceToolPropertiesEXT");
-    table->GetPhysicalDeviceCooperativeMatrixPropertiesNV =
-        (PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV)gpa(instance, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV");
-    table->GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV =
-        (PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV)gpa(
-            instance, "vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV");
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->GetPhysicalDeviceSurfacePresentModes2EXT =
-        (PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT)gpa(instance, "vkGetPhysicalDeviceSurfacePresentModes2EXT");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-    table->CreateHeadlessSurfaceEXT = (PFN_vkCreateHeadlessSurfaceEXT)gpa(instance, "vkCreateHeadlessSurfaceEXT");
-    table->AcquireDrmDisplayEXT = (PFN_vkAcquireDrmDisplayEXT)gpa(instance, "vkAcquireDrmDisplayEXT");
-    table->GetDrmDisplayEXT = (PFN_vkGetDrmDisplayEXT)gpa(instance, "vkGetDrmDisplayEXT");
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->AcquireWinrtDisplayNV = (PFN_vkAcquireWinrtDisplayNV)gpa(instance, "vkAcquireWinrtDisplayNV");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    table->GetWinrtDisplayNV = (PFN_vkGetWinrtDisplayNV)gpa(instance, "vkGetWinrtDisplayNV");
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
-    table->CreateDirectFBSurfaceEXT = (PFN_vkCreateDirectFBSurfaceEXT)gpa(instance, "vkCreateDirectFBSurfaceEXT");
-#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
-#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
-    table->GetPhysicalDeviceDirectFBPresentationSupportEXT =
-        (PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT)gpa(instance, "vkGetPhysicalDeviceDirectFBPresentationSupportEXT");
-#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
-#if defined(VK_USE_PLATFORM_SCREEN_QNX)
-    table->CreateScreenSurfaceQNX = (PFN_vkCreateScreenSurfaceQNX)gpa(instance, "vkCreateScreenSurfaceQNX");
-#endif  // VK_USE_PLATFORM_SCREEN_QNX
-#if defined(VK_USE_PLATFORM_SCREEN_QNX)
-    table->GetPhysicalDeviceScreenPresentationSupportQNX =
-        (PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX)gpa(instance, "vkGetPhysicalDeviceScreenPresentationSupportQNX");
-#endif  // VK_USE_PLATFORM_SCREEN_QNX
-    table->GetPhysicalDeviceOpticalFlowImageFormatsNV =
-        (PFN_vkGetPhysicalDeviceOpticalFlowImageFormatsNV)gpa(instance, "vkGetPhysicalDeviceOpticalFlowImageFormatsNV");
-}
diff --git a/tests/framework/layer/wrap_objects.cpp b/tests/framework/layer/wrap_objects.cpp
index 514f904..c40b1a0 100644
--- a/tests/framework/layer/wrap_objects.cpp
+++ b/tests/framework/layer/wrap_objects.cpp
@@ -28,7 +28,7 @@
 #include <vector>
 
 #include "vulkan/vk_layer.h"
-#include "vk_dispatch_table_helper.h"
+#include "generated/vk_dispatch_table_helper.h"
 #include "loader/vk_loader_layer.h"
 
 // Export full support of instance extension VK_EXT_direct_mode_display extension
diff --git a/tests/framework/shim/shim.h b/tests/framework/shim/shim.h
index 68699e7..897dcaa 100644
--- a/tests/framework/shim/shim.h
+++ b/tests/framework/shim/shim.h
@@ -27,12 +27,19 @@
 
 #pragma once
 
-#include "test_util.h"
-
-#include <unordered_set>
 #include <stdlib.h>
 
-#if defined(WIN32)
+#include <array>
+#include <filesystem>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#if defined(_WIN32)
+
+#include <direct.h>
+#include <Windows.h>
 #include <strsafe.h>
 #include <cfgmgr32.h>
 #include <initguid.h>
@@ -45,10 +52,24 @@
 #include <adapters.h>
 #endif
 
-enum class ManifestCategory { implicit_layer, explicit_layer, icd, settings };
+#include "util/test_defines.h"
+
+#if TESTING_COMMON_UNIX_PLATFORMS
+#include <dirent.h>
+#endif
+
+#include "util/folder_manager.h"
+#include "util/functions.h"
+
 enum class GpuType { unspecified, integrated, discrete, external };
 
-#if defined(WIN32)
+struct TempFile {
+    explicit TempFile(std::filesystem::path filename) : filename(filename) {}
+    ~TempFile() { std::filesystem::remove(filename); }
+    std::filesystem::path filename;
+};
+
+#if defined(_WIN32)
 #define VK_VARIANT_REG_STR ""
 #define VK_VARIANT_REG_STR_W L""
 
@@ -116,15 +137,15 @@
     D3DKMT_Adapter& add_path(std::filesystem::path src, std::vector<std::wstring>& dest);
 };
 
-#elif COMMON_UNIX_PLATFORMS
+#elif TESTING_COMMON_UNIX_PLATFORMS
 
 struct DirEntry {
     DIR* directory = nullptr;
-    std::string folder_path;
+    fs::Folder* folder_represented;
     std::vector<struct dirent*> contents;
     // the current item being read by an app (incremented by readdir, reset to zero by opendir & closedir)
     size_t current_index = 0;
-    bool is_fake_path = false;  // true when this entry is for folder redirection
+    // bool is_fake_path = false;  // true when this entry is for folder redirection
 };
 
 #endif
@@ -135,10 +156,9 @@
 // defined in the .cpp wont be found by the rest of the application
 struct PlatformShim {
     PlatformShim() { fputs_stderr_log.reserve(65536); }
-    PlatformShim(std::vector<fs::FolderManager>* folders) : folders(folders) { fputs_stderr_log.reserve(65536); }
 
     // Used to get info about which drivers & layers have been added to folders
-    std::vector<fs::FolderManager>* folders;
+    fs::FileSystemManager* file_system_manager;
 
     // Captures the output to stderr from fputs & fputc - aka the output of loader_log()
     std::string fputs_stderr_log;
@@ -146,28 +166,25 @@
     // Test Framework interface
     void reset();
 
-    void redirect_all_paths(std::filesystem::path const& path);
-    void redirect_category(std::filesystem::path const& new_path, ManifestCategory category);
-
     // fake paths are paths that the loader normally looks in but actually point to locations inside the test framework
-    void set_fake_path(ManifestCategory category, std::filesystem::path const& path);
+    // void set_fake_path(ManifestCategory category, std::filesystem::path const& path);
 
     // known paths are real paths but since the test framework guarantee's the order files are found in, files in these paths
     // need to be ordered correctly
-    void add_known_path(std::filesystem::path const& path);
-
-    void add_manifest(ManifestCategory category, std::filesystem::path const& path);
-    void add_unsecured_manifest(ManifestCategory category, std::filesystem::path const& path);
+    // void add_known_path(std::filesystem::path const& path);
 
     void clear_logs() { fputs_stderr_log.clear(); }
     bool find_in_log(std::string const& search_text) const { return fputs_stderr_log.find(search_text) != std::string::npos; }
 
 // platform specific shim interface
-#if defined(WIN32)
+#if defined(_WIN32)
     // Control Platform Elevation Level
     void set_elevated_privilege(bool elev) { elevation_level = (elev) ? SECURITY_MANDATORY_HIGH_RID : SECURITY_MANDATORY_LOW_RID; }
     unsigned long elevation_level = SECURITY_MANDATORY_LOW_RID;
 
+    void add_manifest_to_registry(ManifestCategory category, std::filesystem::path const& path);
+    void add_unsecured_manifest_to_registry(ManifestCategory category, std::filesystem::path const& path);
+
     void add_dxgi_adapter(GpuType gpu_preference, DXGI_ADAPTER_DESC1 desc1);
     void add_d3dkmt_adapter(D3DKMT_Adapter const& adapter);
     void set_app_package_path(std::filesystem::path const& path);
@@ -199,24 +216,17 @@
     size_t created_key_count = 0;
     std::vector<HKeyHandle> created_keys;
 
-#elif COMMON_UNIX_PLATFORMS
-    bool is_fake_path(std::filesystem::path const& path);
-    std::filesystem::path const& get_real_path_from_fake_path(std::filesystem::path const& path);
+#elif TESTING_COMMON_UNIX_PLATFORMS
+    // Add a filename that dlopen can "find" with no absolute or relative path given.
+    // EG, dlopen("libfoobar.so") gets turned into dlopen(actual_path)
+    void add_system_library(std::string const& filename, std::filesystem::path const& actual_path);
 
-    void redirect_path(std::filesystem::path const& path, std::filesystem::path const& new_path);
-    void remove_redirect(std::filesystem::path const& path);
+    // Returns the real path of the system library "filename", if it exists. Else returns empty path
+    std::filesystem::path get_system_library(std::string const& filename);
 
-    bool is_known_path(std::filesystem::path const& path);
-    void remove_known_path(std::filesystem::path const& path);
+    std::unordered_map<std::string, std::filesystem::path> system_library_redirection_map;
 
-    void redirect_dlopen_name(std::filesystem::path const& filename, std::filesystem::path const& actual_path);
-    bool is_dlopen_redirect_name(std::filesystem::path const& filename);
-
-    std::filesystem::path query_default_redirect_path(ManifestCategory category);
-
-    std::unordered_map<std::string, std::filesystem::path> redirection_map;
-    std::unordered_map<std::string, std::filesystem::path> dlopen_redirection_map;
-    std::unordered_set<std::string> known_path_set;
+    void set_app_package_path(std::filesystem::path const& path);
 
     void set_elevated_privilege(bool elev) { use_fake_elevation = elev; }
     bool use_fake_elevation = false;
@@ -227,23 +237,23 @@
     std::string bundle_contents;
 #endif
 #endif
+    std::vector<uint8_t> fuzz_data;
+    std::vector<TempFile> temp_fuzz_files;
+    bool is_finished_setup = false;
     bool is_during_destruction = false;
 };
 
 std::vector<std::string> parse_env_var_list(std::string const& var);
 std::string category_path_name(ManifestCategory category);
 
-std::vector<std::filesystem::path> get_folder_contents(std::vector<fs::FolderManager>* folders,
-                                                       std::filesystem::path folder_name) noexcept;
-
 extern "C" {
 // dynamically link on windows and macos
-#if defined(WIN32) || defined(__APPLE__)
-using PFN_get_platform_shim = PlatformShim* (*)(std::vector<fs::FolderManager>* folders);
+#if defined(_WIN32) || defined(__APPLE__)
+using PFN_get_platform_shim = PlatformShim* (*)();
 #define GET_PLATFORM_SHIM_STR "get_platform_shim"
 
 #elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__GNU__) || defined(__QNX__)
 // statically link on linux
-PlatformShim* get_platform_shim(std::vector<fs::FolderManager>* folders);
+PlatformShim* get_platform_shim();
 #endif
 }
diff --git a/tests/framework/shim/shim_common.cpp b/tests/framework/shim/shim_common.cpp
index 399ee8e..f3d021f 100644
--- a/tests/framework/shim/shim_common.cpp
+++ b/tests/framework/shim/shim_common.cpp
@@ -27,20 +27,16 @@
 
 #include "shim.h"
 
-void PlatformShim::redirect_all_paths(std::filesystem::path const& path) {
-    redirect_category(path, ManifestCategory::implicit_layer);
-    redirect_category(path, ManifestCategory::explicit_layer);
-    redirect_category(path, ManifestCategory::icd);
-}
+#include "env_var_wrapper.h"
 
 std::vector<std::string> parse_env_var_list(std::string const& var) {
     std::vector<std::string> items;
     size_t start = 0;
     size_t len = 0;
     for (size_t i = 0; i < var.size(); i++) {
-#if defined(WIN32)
+#if defined(_WIN32)
         if (var[i] == ';') {
-#elif COMMON_UNIX_PLATFORMS
+#elif TESTING_COMMON_UNIX_PLATFORMS
         if (var[i] == ':') {
 #endif
             if (len != 0) {
@@ -58,17 +54,7 @@
     return items;
 }
 
-std::vector<std::filesystem::path> get_folder_contents(std::vector<fs::FolderManager>* folders,
-                                                       std::filesystem::path folder_name) noexcept {
-    for (auto& folder : *folders) {
-        if (folder.location() == folder_name) {
-            return folder.get_files();
-        }
-    }
-    return {};
-}
-
-#if defined(WIN32)
+#if defined(_WIN32)
 
 D3DKMT_Adapter& D3DKMT_Adapter::add_driver_manifest_path(std::filesystem::path const& src) { return add_path(src, driver_paths); }
 D3DKMT_Adapter& D3DKMT_Adapter::add_implicit_layer_manifest_path(std::filesystem::path const& src) {
@@ -101,10 +87,7 @@
     hkey_current_user_settings.clear();
 }
 
-void PlatformShim::set_fake_path([[maybe_unused]] ManifestCategory category, [[maybe_unused]] std::filesystem::path const& path) {}
-void PlatformShim::add_known_path([[maybe_unused]] std::filesystem::path const& path) {}
-
-void PlatformShim::add_manifest(ManifestCategory category, std::filesystem::path const& path) {
+void PlatformShim::add_manifest_to_registry(ManifestCategory category, std::filesystem::path const& path) {
     if (category == ManifestCategory::settings) {
         hkey_local_machine_settings.emplace_back(path);
     } else if (category == ManifestCategory::implicit_layer) {
@@ -116,7 +99,7 @@
     }
 }
 
-void PlatformShim::add_unsecured_manifest(ManifestCategory category, std::filesystem::path const& path) {
+void PlatformShim::add_unsecured_manifest_to_registry(ManifestCategory category, std::filesystem::path const& path) {
     if (category == ManifestCategory::settings) {
         hkey_current_user_settings.emplace_back(path);
     } else if (category == ManifestCategory::implicit_layer) {
@@ -156,9 +139,7 @@
     //     // add_key_value_string(id_key, "VulkanLayerName", layer_path.c_str());
 }
 
-void PlatformShim::redirect_category(std::filesystem::path const&, ManifestCategory) {}
-
-#elif COMMON_UNIX_PLATFORMS
+#elif TESTING_COMMON_UNIX_PLATFORMS
 
 #include <dirent.h>
 #include <unistd.h>
@@ -172,91 +153,12 @@
         return "icd.d";
 }
 
-void PlatformShim::reset() { redirection_map.clear(); }
-
-bool PlatformShim::is_fake_path(std::filesystem::path const& path) { return redirection_map.count(path) > 0; }
-std::filesystem::path const& PlatformShim::get_real_path_from_fake_path(std::filesystem::path const& path) {
-    return redirection_map.at(path);
-}
-void PlatformShim::redirect_path(std::filesystem::path const& path, std::filesystem::path const& new_path) {
-    redirection_map[path] = new_path;
-}
-void PlatformShim::remove_redirect(std::filesystem::path const& path) { redirection_map.erase(path); }
-
-bool PlatformShim::is_known_path(std::filesystem::path const& path) { return known_path_set.count(path) > 0; }
-void PlatformShim::add_known_path(std::filesystem::path const& path) { known_path_set.insert(path); }
-void PlatformShim::remove_known_path(std::filesystem::path const& path) { known_path_set.erase(path); }
-
-void PlatformShim::add_manifest([[maybe_unused]] ManifestCategory category, [[maybe_unused]] std::filesystem::path const& path) {}
-void PlatformShim::add_unsecured_manifest([[maybe_unused]] ManifestCategory category,
-                                          [[maybe_unused]] std::filesystem::path const& path) {}
-
-void parse_and_add_env_var_override(std::vector<std::string>& paths, std::string env_var_contents) {
-    auto parsed_paths = parse_env_var_list(env_var_contents);
-    paths.insert(paths.end(), parsed_paths.begin(), parsed_paths.end());
+void PlatformShim::add_system_library(std::string const& filename, std::filesystem::path const& actual_path) {
+    system_library_redirection_map[filename] = actual_path;
 }
 
-void PlatformShim::redirect_category(std::filesystem::path const& new_path, ManifestCategory category) {
-    std::vector<std::string> paths;
-    auto home = std::filesystem::path(get_env_var("HOME"));
-    if (category == ManifestCategory::settings) {
-        redirect_path(home / ".local/share/vulkan" / category_path_name(category), new_path);
-        return;
-    }
-
-    if (!home.empty()) {
-        paths.push_back((home / ".config"));
-        paths.push_back((home / ".local/share"));
-    }
-    // Don't report errors on apple - these env-vars are not suppose to be defined
-    bool report_errors = true;
-#if defined(__APPLE__)
-    report_errors = false;
-#endif
-    parse_and_add_env_var_override(paths, get_env_var("XDG_CONFIG_HOME", report_errors));
-    if (category == ManifestCategory::explicit_layer) {
-        parse_and_add_env_var_override(paths, get_env_var("VK_LAYER_PATH", false));  // don't report failure
-    }
-    if (category == ManifestCategory::implicit_layer) {
-        parse_and_add_env_var_override(paths, get_env_var("VK_IMPLICIT_LAYER_PATH", false));  // don't report failure
-    }
-    parse_and_add_env_var_override(paths, FALLBACK_DATA_DIRS);
-    parse_and_add_env_var_override(paths, FALLBACK_CONFIG_DIRS);
-
-    auto sys_conf_dir = std::string(SYSCONFDIR);
-    if (!sys_conf_dir.empty()) {
-        paths.push_back(sys_conf_dir);
-    }
-#if defined(EXTRASYSCONFDIR)
-    // EXTRASYSCONFDIR default is /etc, if SYSCONFDIR wasn't defined, it will have /etc put
-    // as its default. Don't want to double add it
-    auto extra_sys_conf_dir = std::string(EXTRASYSCONFDIR);
-    if (!extra_sys_conf_dir.empty() && sys_conf_dir != extra_sys_conf_dir) {
-        paths.push_back(extra_sys_conf_dir);
-    }
-#endif
-
-    for (auto& path : paths) {
-        if (!path.empty()) {
-            redirect_path(std::filesystem::path(path) / "vulkan" / category_path_name(category), new_path);
-        }
-    }
-}
-
-void PlatformShim::set_fake_path(ManifestCategory category, std::filesystem::path const& path) {
-    // use /etc as the 'redirection path' by default since its always searched
-    redirect_path(std::filesystem::path(SYSCONFDIR) / "vulkan" / category_path_name(category), path);
-}
-
-void PlatformShim::redirect_dlopen_name(std::filesystem::path const& filename, std::filesystem::path const& actual_path) {
-    dlopen_redirection_map[filename] = actual_path;
-}
-
-bool PlatformShim::is_dlopen_redirect_name(std::filesystem::path const& filename) {
-    return dlopen_redirection_map.count(filename) == 1;
-}
-
-std::filesystem::path PlatformShim::query_default_redirect_path(ManifestCategory category) {
-    return std::filesystem::path(SYSCONFDIR) / "vulkan" / category_path_name(category);
+std::filesystem::path PlatformShim::get_system_library(std::string const& filename) {
+    return system_library_redirection_map.count(filename) == 1 ? system_library_redirection_map.at(filename)
+                                                               : std::filesystem::path{};
 }
 #endif
diff --git a/tests/framework/shim/unix_shim.cpp b/tests/framework/shim/unix_shim.cpp
index bdf352a..339285c 100644
--- a/tests/framework/shim/unix_shim.cpp
+++ b/tests/framework/shim/unix_shim.cpp
@@ -27,22 +27,31 @@
 
 #include "shim.h"
 
+#include <cstring>
+
 #include <algorithm>
+#include <iostream>
+#include <mutex>
 
 #if defined(__APPLE__)
 #include <CoreFoundation/CoreFoundation.h>
 #endif
 
+#include <dlfcn.h>
+
+#include "util/folder_manager.h"
+
+std::recursive_mutex shim_lock;
 PlatformShim platform_shim;
 extern "C" {
 #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__GNU__) || defined(__QNX__)
-PlatformShim* get_platform_shim(std::vector<fs::FolderManager>* folders) {
-    platform_shim = PlatformShim(folders);
+PlatformShim* get_platform_shim() {
+    platform_shim = PlatformShim();
     return &platform_shim;
 }
 #elif defined(__APPLE__)
-FRAMEWORK_EXPORT PlatformShim* get_platform_shim(std::vector<fs::FolderManager>* folders) {
-    platform_shim = PlatformShim(folders);
+FRAMEWORK_EXPORT PlatformShim* get_platform_shim() {
+    platform_shim = PlatformShim();
     return &platform_shim;
 }
 #endif
@@ -137,29 +146,35 @@
 PFN_FPUTC real_fputc = nullptr;
 #endif
 
+// It would be nicer to use a lock_guard but due to the interposer, it isn't possible because these functions get called
+// before the shim_lock variable is finished initializing.
+#define LOCK_IF_NOT_IN_SETUP                                      \
+    std::unique_lock<std::recursive_mutex> lock{};                \
+    if (platform_shim.is_finished_setup) {                        \
+        lock = std::unique_lock<std::recursive_mutex>(shim_lock); \
+    }
+
 FRAMEWORK_EXPORT DIR* OPENDIR_FUNC_NAME(const char* path_name) {
+    LOCK_IF_NOT_IN_SETUP
 #if !defined(__APPLE__)
     if (!real_opendir) real_opendir = (PFN_OPENDIR)dlsym(RTLD_NEXT, "opendir");
 #endif
-    if (platform_shim.is_during_destruction) {
+    if (platform_shim.is_during_destruction || !platform_shim.is_finished_setup) {
         return real_opendir(path_name);
     }
-    DIR* dir;
-    if (platform_shim.is_fake_path(path_name)) {
-        auto real_path_name = platform_shim.get_real_path_from_fake_path(std::filesystem::path(path_name));
-        dir = real_opendir(real_path_name.c_str());
-        platform_shim.dir_entries.push_back(DirEntry{dir, std::string(path_name), {}, 0, true});
-    } else if (platform_shim.is_known_path(path_name)) {
-        dir = real_opendir(path_name);
-        platform_shim.dir_entries.push_back(DirEntry{dir, std::string(path_name), {}, 0, false});
-    } else {
-        dir = real_opendir(path_name);
+    DIR* dir = nullptr;
+
+    if (auto* folder = platform_shim.file_system_manager->get_folder_for_given_path(path_name); folder != nullptr) {
+        dir = real_opendir(folder->location().c_str());
+        platform_shim.dir_entries.push_back(DirEntry{dir, folder, {}, 0});
     }
+    // Dont pass through as this allows non-test paths to escape containment
 
     return dir;
 }
 
 FRAMEWORK_EXPORT struct dirent* READDIR_FUNC_NAME(DIR* dir_stream) {
+    LOCK_IF_NOT_IN_SETUP
 #if !defined(__APPLE__)
     if (!real_readdir) {
         if (sizeof(void*) == 8) {
@@ -171,18 +186,19 @@
     }
 
 #endif
-    if (platform_shim.is_during_destruction) {
+    if (platform_shim.is_during_destruction || !platform_shim.is_finished_setup) {
         return real_readdir(dir_stream);
     }
     auto it = std::find_if(platform_shim.dir_entries.begin(), platform_shim.dir_entries.end(),
                            [dir_stream](DirEntry const& entry) { return entry.directory == dir_stream; });
 
+    // Folder has not been opened with opendir previously, probably not a loader call so we should ignore it
     if (it == platform_shim.dir_entries.end()) {
         return real_readdir(dir_stream);
     }
     // Folder was found but this is the first file to be read from it
     if (it->current_index == 0) {
-        std::vector<struct dirent*> folder_contents;
+        std::vector<struct dirent*> readdir_contents;
         std::vector<std::string> dirent_filenames;
         while (true) {
             errno = 0;
@@ -198,21 +214,17 @@
                 (dir_entry->d_name[0] == '.' && dir_entry->d_name[1] == '\0')) {
                 continue;
             }
-            folder_contents.push_back(dir_entry);
+            readdir_contents.push_back(dir_entry);
             dirent_filenames.push_back(&dir_entry->d_name[0]);
         }
-        auto real_path = it->folder_path;
-        if (it->is_fake_path) {
-            real_path = platform_shim.redirection_map.at(it->folder_path);
-        }
-        auto filenames = get_folder_contents(platform_shim.folders, real_path);
 
-        // Add the dirent structures in the order they appear in the FolderManager
-        // Ignore anything which wasn't in the FolderManager
-        for (auto const& file : filenames) {
+        // Add the dirent structures in the order they appear in the list of files provided by the Folder
+        // Ignore anything which wasn't in the Folder
+        auto folder_contents = it->folder_represented->get_files();
+        for (auto const& file : folder_contents) {
             for (size_t i = 0; i < dirent_filenames.size(); i++) {
                 if (file == dirent_filenames.at(i)) {
-                    it->contents.push_back(folder_contents.at(i));
+                    it->contents.push_back(readdir_contents.at(i));
                     break;
                 }
             }
@@ -223,10 +235,11 @@
 }
 
 FRAMEWORK_EXPORT int CLOSEDIR_FUNC_NAME(DIR* dir_stream) {
+    LOCK_IF_NOT_IN_SETUP
 #if !defined(__APPLE__)
     if (!real_closedir) real_closedir = (PFN_CLOSEDIR)dlsym(RTLD_NEXT, "closedir");
 #endif
-    if (platform_shim.is_during_destruction) {
+    if (platform_shim.is_during_destruction || !platform_shim.is_finished_setup) {
         return real_closedir(dir_stream);
     }
     auto it = std::find_if(platform_shim.dir_entries.begin(), platform_shim.dir_entries.end(),
@@ -240,54 +253,90 @@
 }
 
 FRAMEWORK_EXPORT int ACCESS_FUNC_NAME(const char* in_pathname, int mode) {
+    LOCK_IF_NOT_IN_SETUP
 #if !defined(__APPLE__)
     if (!real_access) real_access = (PFN_ACCESS)dlsym(RTLD_NEXT, "access");
 #endif
-    std::filesystem::path path{in_pathname};
-    if (!path.has_parent_path()) {
+    if (platform_shim.is_during_destruction || !platform_shim.is_finished_setup) {
         return real_access(in_pathname, mode);
     }
 
-    if (platform_shim.is_fake_path(path.parent_path())) {
-        std::filesystem::path real_path = platform_shim.get_real_path_from_fake_path(path.parent_path());
+    std::filesystem::path path{in_pathname};
+    if (!path.has_parent_path()) {
+        return real_access(in_pathname, mode);
+    } else if (auto real_path = platform_shim.file_system_manager->get_real_path_of_redirected_path(path.parent_path());
+               !real_path.empty()) {
         real_path /= path.filename();
         return real_access(real_path.c_str(), mode);
+    } else if (platform_shim.file_system_manager->is_folder_path(path.parent_path())) {
+        return real_access(in_pathname, mode);
+    } else {
+        return -1;
     }
-    return real_access(in_pathname, mode);
 }
 
 FRAMEWORK_EXPORT FILE* FOPEN_FUNC_NAME(const char* in_filename, const char* mode) {
+    LOCK_IF_NOT_IN_SETUP
 #if !defined(__APPLE__)
     if (!real_fopen) real_fopen = (PFN_FOPEN)dlsym(RTLD_NEXT, "fopen");
 #endif
-    std::filesystem::path path{in_filename};
-    if (!path.has_parent_path()) {
+    if (platform_shim.is_during_destruction || !platform_shim.is_finished_setup) {
         return real_fopen(in_filename, mode);
     }
-
-    FILE* f_ptr;
-    if (platform_shim.is_fake_path(path.parent_path())) {
-        auto real_path = platform_shim.get_real_path_from_fake_path(path.parent_path()) / path.filename();
-        f_ptr = real_fopen(real_path.c_str(), mode);
+    FILE* out_file = nullptr;
+    std::filesystem::path path{in_filename};
+    if (!path.has_parent_path()) {
+        out_file = real_fopen(in_filename, mode);
+    } else if (auto real_path = platform_shim.file_system_manager->get_real_path_of_redirected_path(path.parent_path());
+               !real_path.empty()) {
+        real_path /= path.filename();
+        out_file = real_fopen(real_path.c_str(), mode);
     } else {
-        f_ptr = real_fopen(in_filename, mode);
+        out_file = real_fopen(in_filename, mode);
     }
 
-    return f_ptr;
+    // Fuzz tests have sub files embedded in the input data file. This
+    if (!platform_shim.fuzz_data.empty() && out_file == NULL) {
+        FILE* fp = fopen(path.c_str(), "wb");
+        if (nullptr == fp) {
+            path.replace_filename("callback_file_" + std::to_string(platform_shim.temp_fuzz_files.size()));
+            fp = fopen(path.c_str(), "wb");
+            if (nullptr == fp) {
+                abort();
+            }
+        }
+        fwrite(platform_shim.fuzz_data.data(), platform_shim.fuzz_data.size(), 1, fp);
+        fclose(fp);
+        platform_shim.temp_fuzz_files.emplace_back(path.c_str());
+
+        out_file = fopen(path.c_str(), "rb");
+    }
+    return out_file;
 }
 
 FRAMEWORK_EXPORT void* DLOPEN_FUNC_NAME(const char* in_filename, int flags) {
+    LOCK_IF_NOT_IN_SETUP
 #if !defined(__APPLE__)
     if (!real_dlopen) real_dlopen = (PFN_DLOPEN)dlsym(RTLD_NEXT, "dlopen");
 #endif
-
-    if (platform_shim.is_dlopen_redirect_name(in_filename)) {
-        return real_dlopen(platform_shim.dlopen_redirection_map[in_filename].c_str(), flags);
+    if (platform_shim.is_during_destruction || !platform_shim.is_finished_setup) {
+        return real_dlopen(in_filename, flags);
     }
-    return real_dlopen(in_filename, flags);
+
+    std::filesystem::path path{in_filename};
+    if (auto real_path = platform_shim.get_system_library(path); !real_path.empty()) {
+        return real_dlopen(real_path.c_str(), flags);
+    } else if (auto real_path = platform_shim.file_system_manager->get_real_path_of_redirected_path(path.parent_path());
+               !real_path.empty()) {
+        real_path /= path.filename();
+        return real_dlopen(real_path.c_str(), flags);
+    } else {
+        return real_dlopen(in_filename, flags);
+    }
 }
 
 FRAMEWORK_EXPORT uid_t GETEUID_FUNC_NAME(void) {
+    LOCK_IF_NOT_IN_SETUP
 #if !defined(__APPLE__)
     if (!real_geteuid) real_geteuid = (PFN_GETEUID)dlsym(RTLD_NEXT, "geteuid");
 #endif
@@ -300,6 +349,7 @@
 }
 
 FRAMEWORK_EXPORT gid_t GETEGID_FUNC_NAME(void) {
+    LOCK_IF_NOT_IN_SETUP
 #if !defined(__APPLE__)
     if (!real_getegid) real_getegid = (PFN_GETEGID)dlsym(RTLD_NEXT, "getegid");
 #endif
@@ -314,6 +364,7 @@
 #if !defined(TARGET_OS_IPHONE)
 #if defined(HAVE_SECURE_GETENV)
 FRAMEWORK_EXPORT char* SECURE_GETENV_FUNC_NAME(const char* name) {
+    LOCK_IF_NOT_IN_SETUP
 #if !defined(__APPLE__)
     if (!real_secure_getenv) real_secure_getenv = (PFN_SEC_GETENV)dlsym(RTLD_NEXT, "secure_getenv");
 #endif
@@ -326,6 +377,7 @@
 #endif
 #if defined(HAVE___SECURE_GETENV)
 FRAMEWORK_EXPORT char* __SECURE_GETENV_FUNC_NAME(const char* name) {
+    LOCK_IF_NOT_IN_SETUP
 #if !defined(__APPLE__)
     if (!real__secure_getenv) real__secure_getenv = (PFN_SEC_GETENV)dlsym(RTLD_NEXT, "__secure_getenv");
 #endif
@@ -340,6 +392,7 @@
 #endif
 
 FRAMEWORK_EXPORT int FPUTS_FUNC_NAME(const char* str, FILE* stream) {
+    LOCK_IF_NOT_IN_SETUP
 #if !defined(__APPLE__)
     if (!real_fputs) real_fputs = (PFN_FPUTS)dlsym(RTLD_NEXT, "fputs");
 #endif
@@ -350,6 +403,7 @@
 }
 
 FRAMEWORK_EXPORT int FPUTC_FUNC_NAME(int ch, FILE* stream) {
+    LOCK_IF_NOT_IN_SETUP
 #if !defined(__APPLE__)
     if (!real_fputc) real_fputc = (PFN_FPUTC)dlsym(RTLD_NEXT, "fputc");
 #endif
@@ -361,16 +415,19 @@
 
 #if defined(__APPLE__)
 FRAMEWORK_EXPORT CFBundleRef my_CFBundleGetMainBundle() {
+    LOCK_IF_NOT_IN_SETUP
     static CFBundleRef global_bundle{};
     return reinterpret_cast<CFBundleRef>(&global_bundle);
 }
 FRAMEWORK_EXPORT CFURLRef my_CFBundleCopyResourcesDirectoryURL([[maybe_unused]] CFBundleRef bundle) {
+    LOCK_IF_NOT_IN_SETUP
     static CFURLRef global_url{};
     return reinterpret_cast<CFURLRef>(&global_url);
 }
 FRAMEWORK_EXPORT Boolean my_CFURLGetFileSystemRepresentation([[maybe_unused]] CFURLRef url,
                                                              [[maybe_unused]] Boolean resolveAgainstBase, UInt8* buffer,
                                                              CFIndex maxBufLen) {
+    LOCK_IF_NOT_IN_SETUP
     if (!platform_shim.bundle_contents.empty()) {
         CFIndex copy_len = (CFIndex)platform_shim.bundle_contents.size();
         if (copy_len > maxBufLen) {
diff --git a/tests/framework/shim/windows_shim.cpp b/tests/framework/shim/windows_shim.cpp
index eb42fcd..1c6bc0b 100644
--- a/tests/framework/shim/windows_shim.cpp
+++ b/tests/framework/shim/windows_shim.cpp
@@ -31,6 +31,10 @@
 #include <ntstatus.h>
 #endif
 
+#include <iostream>
+
+#include <assert.h>
+
 #include <windows.h>
 #include <debugapi.h>
 
@@ -38,6 +42,9 @@
 
 #include "detours.h"
 
+#include "util/dynamic_library_wrapper.h"
+#include "util/wide_char_handling.h"
+
 static PlatformShim platform_shim;
 
 extern "C" {
@@ -512,8 +519,5 @@
     }
     return TRUE;
 }
-FRAMEWORK_EXPORT PlatformShim *get_platform_shim(std::vector<fs::FolderManager> *folders) {
-    platform_shim = PlatformShim(folders);
-    return &platform_shim;
-}
+FRAMEWORK_EXPORT PlatformShim *get_platform_shim() { return &platform_shim; }
 }
diff --git a/tests/framework/test_environment.cpp b/tests/framework/test_environment.cpp
index efa4706..21f9f66 100644
--- a/tests/framework/test_environment.cpp
+++ b/tests/framework/test_environment.cpp
@@ -27,152 +27,14 @@
 
 #include "test_environment.h"
 
+#include <array>
+#include <filesystem>
 #include <fstream>
+#include <string>
+#include <utility>
 
-std::filesystem::path get_loader_path() {
-    auto loader_path = std::filesystem::path(FRAMEWORK_VULKAN_LIBRARY_PATH);
-    auto env_var_res = get_env_var("VK_LOADER_TEST_LOADER_PATH", false);
-    if (!env_var_res.empty()) {
-        loader_path = std::filesystem::path(env_var_res);
-    }
-    return loader_path;
-}
-
-void init_vulkan_functions(VulkanFunctions& funcs) {
-#if defined(APPLE_STATIC_LOADER)
-#define GPA(name) name
-#else
-#define GPA(name) funcs.loader.get_symbol(#name)
-#endif
-
-    // clang-format off
-    funcs.vkGetInstanceProcAddr = GPA(vkGetInstanceProcAddr);
-    funcs.vkEnumerateInstanceExtensionProperties = GPA(vkEnumerateInstanceExtensionProperties);
-    funcs.vkEnumerateInstanceLayerProperties = GPA(vkEnumerateInstanceLayerProperties);
-    funcs.vkEnumerateInstanceVersion = GPA(vkEnumerateInstanceVersion);
-    funcs.vkCreateInstance = GPA(vkCreateInstance);
-    funcs.vkDestroyInstance = GPA(vkDestroyInstance);
-    funcs.vkEnumeratePhysicalDevices = GPA(vkEnumeratePhysicalDevices);
-    funcs.vkEnumeratePhysicalDeviceGroups = GPA(vkEnumeratePhysicalDeviceGroups);
-    funcs.vkGetPhysicalDeviceFeatures = GPA(vkGetPhysicalDeviceFeatures);
-    funcs.vkGetPhysicalDeviceFeatures2 = GPA(vkGetPhysicalDeviceFeatures2);
-    funcs.vkGetPhysicalDeviceFormatProperties = GPA(vkGetPhysicalDeviceFormatProperties);
-    funcs.vkGetPhysicalDeviceFormatProperties2 = GPA(vkGetPhysicalDeviceFormatProperties2);
-    funcs.vkGetPhysicalDeviceImageFormatProperties = GPA(vkGetPhysicalDeviceImageFormatProperties);
-    funcs.vkGetPhysicalDeviceImageFormatProperties2 = GPA(vkGetPhysicalDeviceImageFormatProperties2);
-    funcs.vkGetPhysicalDeviceSparseImageFormatProperties = GPA(vkGetPhysicalDeviceSparseImageFormatProperties);
-    funcs.vkGetPhysicalDeviceSparseImageFormatProperties2 = GPA(vkGetPhysicalDeviceSparseImageFormatProperties2);
-    funcs.vkGetPhysicalDeviceProperties = GPA(vkGetPhysicalDeviceProperties);
-    funcs.vkGetPhysicalDeviceProperties2 = GPA(vkGetPhysicalDeviceProperties2);
-    funcs.vkGetPhysicalDeviceQueueFamilyProperties = GPA(vkGetPhysicalDeviceQueueFamilyProperties);
-    funcs.vkGetPhysicalDeviceQueueFamilyProperties2 = GPA(vkGetPhysicalDeviceQueueFamilyProperties2);
-    funcs.vkGetPhysicalDeviceMemoryProperties = GPA(vkGetPhysicalDeviceMemoryProperties);
-    funcs.vkGetPhysicalDeviceMemoryProperties2 = GPA(vkGetPhysicalDeviceMemoryProperties2);
-    funcs.vkGetPhysicalDeviceSurfaceSupportKHR = GPA(vkGetPhysicalDeviceSurfaceSupportKHR);
-    funcs.vkGetPhysicalDeviceSurfaceFormatsKHR = GPA(vkGetPhysicalDeviceSurfaceFormatsKHR);
-    funcs.vkGetPhysicalDeviceSurfacePresentModesKHR = GPA(vkGetPhysicalDeviceSurfacePresentModesKHR);
-    funcs.vkGetPhysicalDeviceSurfaceCapabilitiesKHR = GPA(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
-    funcs.vkEnumerateDeviceExtensionProperties = GPA(vkEnumerateDeviceExtensionProperties);
-    funcs.vkEnumerateDeviceLayerProperties = GPA(vkEnumerateDeviceLayerProperties);
-    funcs.vkGetPhysicalDeviceExternalBufferProperties = GPA(vkGetPhysicalDeviceExternalBufferProperties);
-    funcs.vkGetPhysicalDeviceExternalFenceProperties = GPA(vkGetPhysicalDeviceExternalFenceProperties);
-    funcs.vkGetPhysicalDeviceExternalSemaphoreProperties = GPA(vkGetPhysicalDeviceExternalSemaphoreProperties);
-
-    funcs.vkDestroySurfaceKHR = GPA(vkDestroySurfaceKHR);
-    funcs.vkGetDeviceProcAddr = GPA(vkGetDeviceProcAddr);
-    funcs.vkCreateDevice = GPA(vkCreateDevice);
-
-    funcs.vkCreateHeadlessSurfaceEXT = GPA(vkCreateHeadlessSurfaceEXT);
-    funcs.vkCreateDisplayPlaneSurfaceKHR = GPA(vkCreateDisplayPlaneSurfaceKHR);
-    funcs.vkGetPhysicalDeviceDisplayPropertiesKHR = GPA(vkGetPhysicalDeviceDisplayPropertiesKHR);
-    funcs.vkGetPhysicalDeviceDisplayPlanePropertiesKHR = GPA(vkGetPhysicalDeviceDisplayPlanePropertiesKHR);
-    funcs.vkGetDisplayPlaneSupportedDisplaysKHR = GPA(vkGetDisplayPlaneSupportedDisplaysKHR);
-    funcs.vkGetDisplayModePropertiesKHR = GPA(vkGetDisplayModePropertiesKHR);
-    funcs.vkCreateDisplayModeKHR = GPA(vkCreateDisplayModeKHR);
-    funcs.vkGetDisplayPlaneCapabilitiesKHR = GPA(vkGetDisplayPlaneCapabilitiesKHR);
-    funcs.vkGetPhysicalDevicePresentRectanglesKHR = GPA(vkGetPhysicalDevicePresentRectanglesKHR);
-    funcs.vkGetPhysicalDeviceDisplayProperties2KHR = GPA(vkGetPhysicalDeviceDisplayProperties2KHR);
-    funcs.vkGetPhysicalDeviceDisplayPlaneProperties2KHR = GPA(vkGetPhysicalDeviceDisplayPlaneProperties2KHR);
-    funcs.vkGetDisplayModeProperties2KHR = GPA(vkGetDisplayModeProperties2KHR);
-    funcs.vkGetDisplayPlaneCapabilities2KHR = GPA(vkGetDisplayPlaneCapabilities2KHR);
-    funcs.vkGetPhysicalDeviceSurfaceCapabilities2KHR = GPA(vkGetPhysicalDeviceSurfaceCapabilities2KHR);
-    funcs.vkGetPhysicalDeviceSurfaceFormats2KHR = GPA(vkGetPhysicalDeviceSurfaceFormats2KHR);
-
-#if defined(VK_USE_PLATFORM_ANDROID_KHR)
-    funcs.vkCreateAndroidSurfaceKHR = GPA(vkCreateAndroidSurfaceKHR);
-#endif  // VK_USE_PLATFORM_ANDROID_KHR
-#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
-    funcs.vkCreateDirectFBSurfaceEXT = GPA(vkCreateDirectFBSurfaceEXT);
-    funcs.vkGetPhysicalDeviceDirectFBPresentationSupportEXT = GPA(vkGetPhysicalDeviceDirectFBPresentationSupportEXT);
-#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    funcs.vkCreateImagePipeSurfaceFUCHSIA = GPA(vkCreateImagePipeSurfaceFUCHSIA);
-#endif  // VK_USE_PLATFORM_FUCHSIA
-#if defined(VK_USE_PLATFORM_GGP)
-    funcs.vkCreateStreamDescriptorSurfaceGGP = GPA(vkCreateStreamDescriptorSurfaceGGP);
-#endif  // VK_USE_PLATFORM_GGP
-#if defined(VK_USE_PLATFORM_IOS_MVK)
-    funcs.vkCreateIOSSurfaceMVK = GPA(vkCreateIOSSurfaceMVK);
-#endif  // VK_USE_PLATFORM_IOS_MVK
-#if defined(VK_USE_PLATFORM_MACOS_MVK)
-    funcs.vkCreateMacOSSurfaceMVK = GPA(vkCreateMacOSSurfaceMVK);
-#endif  // VK_USE_PLATFORM_MACOS_MVK
-#if defined(VK_USE_PLATFORM_METAL_EXT)
-    funcs.vkCreateMetalSurfaceEXT = GPA(vkCreateMetalSurfaceEXT);
-#endif  // VK_USE_PLATFORM_METAL_EXT
-#if defined(VK_USE_PLATFORM_SCREEN_QNX)
-    funcs.vkCreateScreenSurfaceQNX = GPA(vkCreateScreenSurfaceQNX);
-    funcs.vkGetPhysicalDeviceScreenPresentationSupportQNX = GPA(vkGetPhysicalDeviceScreenPresentationSupportQNX);
-#endif  // VK_USE_PLATFORM_SCREEN_QNX
-#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
-    funcs.vkCreateWaylandSurfaceKHR = GPA(vkCreateWaylandSurfaceKHR);
-    funcs.vkGetPhysicalDeviceWaylandPresentationSupportKHR = GPA(vkGetPhysicalDeviceWaylandPresentationSupportKHR);
-#endif  // VK_USE_PLATFORM_WAYLAND_KHR
-#if defined(VK_USE_PLATFORM_XCB_KHR)
-    funcs.vkCreateXcbSurfaceKHR = GPA(vkCreateXcbSurfaceKHR);
-    funcs.vkGetPhysicalDeviceXcbPresentationSupportKHR = GPA(vkGetPhysicalDeviceXcbPresentationSupportKHR);
-#endif  // VK_USE_PLATFORM_XCB_KHR
-#if defined(VK_USE_PLATFORM_XLIB_KHR)
-    funcs.vkCreateXlibSurfaceKHR = GPA(vkCreateXlibSurfaceKHR);
-    funcs.vkGetPhysicalDeviceXlibPresentationSupportKHR = GPA(vkGetPhysicalDeviceXlibPresentationSupportKHR);
-#endif  // VK_USE_PLATFORM_XLIB_KHR
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    funcs.vkCreateWin32SurfaceKHR = GPA(vkCreateWin32SurfaceKHR);
-    funcs.vkGetPhysicalDeviceWin32PresentationSupportKHR = GPA(vkGetPhysicalDeviceWin32PresentationSupportKHR);
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-
-    funcs.vkDestroyDevice = GPA(vkDestroyDevice);
-    funcs.vkGetDeviceQueue = GPA(vkGetDeviceQueue);
-#undef GPA
-    // clang-format on
-}
-
-#if defined(APPLE_STATIC_LOADER)
-VulkanFunctions::VulkanFunctions() {
-#else
-VulkanFunctions::VulkanFunctions() : loader(get_loader_path()) {
-#endif
-    init_vulkan_functions(*this);
-}
-
-void VulkanFunctions::load_instance_functions(VkInstance instance) {
-    vkCreateDebugReportCallbackEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"));
-    vkDestroyDebugReportCallbackEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"));
-    vkCreateDebugUtilsMessengerEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"));
-    vkDestroyDebugUtilsMessengerEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT"));
-}
-
-DeviceFunctions::DeviceFunctions(const VulkanFunctions& vulkan_functions, VkDevice device) {
-    vkGetDeviceProcAddr = vulkan_functions.vkGetDeviceProcAddr;
-    vkDestroyDevice = load(device, "vkDestroyDevice");
-    vkGetDeviceQueue = load(device, "vkGetDeviceQueue");
-    vkCreateCommandPool = load(device, "vkCreateCommandPool");
-    vkAllocateCommandBuffers = load(device, "vkAllocateCommandBuffers");
-    vkDestroyCommandPool = load(device, "vkDestroyCommandPool");
-    vkCreateSwapchainKHR = load(device, "vkCreateSwapchainKHR");
-    vkGetSwapchainImagesKHR = load(device, "vkGetSwapchainImagesKHR");
-    vkDestroySwapchainKHR = load(device, "vkDestroySwapchainKHR");
-}
+#include "json_writer.h"
+#include "test_defines.h"
 
 InstWrapper::InstWrapper(VulkanFunctions& functions, VkAllocationCallbacks* callbacks) noexcept
     : functions(&functions), callbacks(callbacks) {}
@@ -202,13 +64,13 @@
 void InstWrapper::CheckCreate(VkResult result_to_check) {
     handle_assert_null(inst);
     ASSERT_EQ(result_to_check, functions->vkCreateInstance(create_info.get(), callbacks, &inst));
-    functions->load_instance_functions(inst);
+    instance_functions = InstanceFunctions(functions->vkGetInstanceProcAddr, inst);
 }
 
 void InstWrapper::CheckCreateWithInfo(InstanceCreateInfo& create_info, VkResult result_to_check) {
     handle_assert_null(inst);
     ASSERT_EQ(result_to_check, functions->vkCreateInstance(create_info.get(), callbacks, &inst));
-    functions->load_instance_functions(inst);
+    instance_functions = InstanceFunctions(functions->vkGetInstanceProcAddr, inst);
 }
 
 std::vector<VkPhysicalDevice> InstWrapper::GetPhysDevs(uint32_t phys_dev_count, VkResult result_to_check) {
@@ -342,308 +204,323 @@
     return env_log.find_prefix_then_postfix(prefix, postfix);
 }
 
-PlatformShimWrapper::PlatformShimWrapper(std::vector<fs::FolderManager>* folders, const char* log_filter) noexcept
+PlatformShimWrapper::PlatformShimWrapper(fs::FileSystemManager& file_system_manager, const char* log_filter) noexcept
     : loader_logging{"VK_LOADER_DEBUG"} {
 #if defined(WIN32) || defined(__APPLE__)
     shim_library = LibraryWrapper(SHIM_LIBRARY_NAME);
-    PFN_get_platform_shim get_platform_shim_func = shim_library.get_symbol(GET_PLATFORM_SHIM_STR);
-    assert(get_platform_shim_func != NULL && "Must be able to get \"platform_shim\"");
-    platform_shim = get_platform_shim_func(folders);
+    PFN_get_platform_shim get_platform_shim = shim_library.get_symbol(GET_PLATFORM_SHIM_STR);
+    assert(get_platform_shim != NULL && "Must be able to get \"platform_shim\"");
+    platform_shim = get_platform_shim();
 #elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__GNU__)
-    platform_shim = get_platform_shim(folders);
+    platform_shim = get_platform_shim();
 #endif
-    platform_shim->reset();
+    platform_shim->file_system_manager = &file_system_manager;
 
     if (log_filter) {
         loader_logging.set_new_value(log_filter);
     }
 }
 
-PlatformShimWrapper::~PlatformShimWrapper() noexcept { platform_shim->reset(); }
+template <>
+TestBinaryHandle<TestICD, GetTestICDFunc, GetNewTestICDFunc>::TestBinaryHandle(std::filesystem::path const& binary_path) noexcept
+    : library(binary_path) {
+    proc_addr_get_test_binary = library.get_symbol(GET_TEST_ICD_FUNC_STR);
+    proc_addr_reset_binary = library.get_symbol(RESET_ICD_FUNC_STR);
+}
 
-TestICDHandle::TestICDHandle() noexcept {}
-TestICDHandle::TestICDHandle(std::filesystem::path const& icd_path) noexcept : icd_library(icd_path) {
-    proc_addr_get_test_icd = icd_library.get_symbol(GET_TEST_ICD_FUNC_STR);
-    proc_addr_reset_icd = icd_library.get_symbol(RESET_ICD_FUNC_STR);
+template <>
+TestBinaryHandle<TestLayer, GetTestLayerFunc, GetNewTestLayerFunc>::TestBinaryHandle(
+    std::filesystem::path const& binary_path) noexcept
+    : library(binary_path) {
+    proc_addr_get_test_binary = library.get_symbol(GET_TEST_LAYER_FUNC_STR);
+    proc_addr_reset_binary = library.get_symbol(RESET_LAYER_FUNC_STR);
 }
-TestICD& TestICDHandle::get_test_icd() noexcept {
-    assert(proc_addr_get_test_icd != NULL && "symbol must be loaded before use");
-    return *proc_addr_get_test_icd();
-}
-TestICD& TestICDHandle::reset_icd() noexcept {
-    assert(proc_addr_reset_icd != NULL && "symbol must be loaded before use");
-    return *proc_addr_reset_icd();
-}
-std::filesystem::path TestICDHandle::get_icd_full_path() noexcept { return icd_library.lib_path; }
-std::filesystem::path TestICDHandle::get_icd_manifest_path() noexcept { return manifest_path; }
-std::filesystem::path TestICDHandle::get_shimmed_manifest_path() noexcept { return shimmed_manifest_path; }
-
-TestLayerHandle::TestLayerHandle() noexcept {}
-TestLayerHandle::TestLayerHandle(std::filesystem::path const& layer_path) noexcept : layer_library(layer_path) {
-    proc_addr_get_test_layer = layer_library.get_symbol(GET_TEST_LAYER_FUNC_STR);
-    proc_addr_reset_layer = layer_library.get_symbol(RESET_LAYER_FUNC_STR);
-}
-TestLayer& TestLayerHandle::get_test_layer() noexcept {
-    assert(proc_addr_get_test_layer != NULL && "symbol must be loaded before use");
-    return *proc_addr_get_test_layer();
-}
-TestLayer& TestLayerHandle::reset_layer() noexcept {
-    assert(proc_addr_reset_layer != NULL && "symbol must be loaded before use");
-    return *proc_addr_reset_layer();
-}
-std::filesystem::path TestLayerHandle::get_layer_full_path() noexcept { return layer_library.lib_path; }
-std::filesystem::path TestLayerHandle::get_layer_manifest_path() noexcept { return manifest_path; }
-std::filesystem::path TestLayerHandle::get_shimmed_manifest_path() noexcept { return shimmed_manifest_path; }
 
 FrameworkEnvironment::FrameworkEnvironment() noexcept : FrameworkEnvironment(FrameworkSettings{}) {}
 FrameworkEnvironment::FrameworkEnvironment(FrameworkSettings const& settings) noexcept
-    : settings(settings), platform_shim(&folders, settings.log_filter) {
-    // This order is important, it matches the enum ManifestLocation, used to index the folders vector
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("null_dir"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("icd_manifests"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("icd_env_vars_manifests"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_layer_manifests"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_env_var_layer_folder"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_add_env_var_layer_folder"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_layer_manifests"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_env_var_layer_manifests"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_add_env_var_layer_manifests"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("override_layer_manifests"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("app_package_manifests"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("macos_bundle"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("unsecured_location"));
-    folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("settings_location"));
+    : settings(settings), platform_shim(file_system_manager, settings.log_filter) {
+    // Setup default path redirections
 
-    platform_shim->redirect_all_paths(get_folder(ManifestLocation::null).location());
-    if (settings.enable_default_search_paths) {
-        platform_shim->set_fake_path(ManifestCategory::icd, get_folder(ManifestLocation::driver).location());
-        platform_shim->set_fake_path(ManifestCategory::explicit_layer, get_folder(ManifestLocation::explicit_layer).location());
-        platform_shim->set_fake_path(ManifestCategory::implicit_layer, get_folder(ManifestLocation::implicit_layer).location());
-#if COMMON_UNIX_PLATFORMS
-        auto home = get_env_var("HOME");
-        auto unsecured_location = get_folder(ManifestLocation::unsecured_location).location();
-        platform_shim->redirect_path(home + "/.local/share/vulkan/icd.d", unsecured_location);
-        platform_shim->redirect_path(home + "/.local/share/vulkan/implicit_layer.d", unsecured_location);
-        platform_shim->redirect_path(home + "/.local/share/vulkan/explicit_layer.d", unsecured_location);
+    platform_shim->set_elevated_privilege(settings.run_as_if_with_elevated_privleges);
+
+#if TESTING_COMMON_UNIX_PLATFORMS
+    if (!settings.home_env_var.empty()) env_var_home.set_new_value(settings.home_env_var);
+#if !defined(__APPLE__)
+    if (!settings.xdg_config_home_env_var.empty()) env_var_xdg_config_home.set_new_value(settings.xdg_config_home_env_var);
+    if (!settings.xdg_config_dirs_env_var.empty()) env_var_xdg_config_dirs.set_new_value(settings.xdg_config_dirs_env_var);
+    if (!settings.xdg_data_home_env_var.empty()) env_var_xdg_data_home.set_new_value(settings.xdg_data_home_env_var);
+    if (!settings.xdg_data_dirs_env_var.empty()) env_var_xdg_data_dirs.set_new_value(settings.xdg_data_dirs_env_var);
 #endif
+#endif
+
+    const std::array<std::pair<const char*, ManifestLocation>, 4> secured_redirection_map = {
+        std::pair{"icd.d", ManifestLocation::driver},
+        std::pair{"implicit_layer.d", ManifestLocation::implicit_layer},
+        std::pair{"explicit_layer.d", ManifestLocation::explicit_layer},
+        std::pair{"loader_settings.d", ManifestLocation::settings_location},
+    };
+
+    const std::array<std::pair<const char*, ManifestLocation>, 4> unsecured_redirection_map = {
+        std::pair{"icd.d", ManifestLocation::unsecured_driver},
+        std::pair{"implicit_layer.d", ManifestLocation::unsecured_implicit_layer},
+        std::pair{"explicit_layer.d", ManifestLocation::unsecured_explicit_layer},
+        std::pair{"loader_settings.d", ManifestLocation::unsecured_settings},
+    };
+
+#if TESTING_COMMON_UNIX_PLATFORMS && !defined(__APPLE__)
+    // Always are searching SYSCONFDIR on unix (but not apple, which is handled separately)
+    secure_manifest_base_location = SYSCONFDIR;
+
+    for (auto const& [redirect, location] : secured_redirection_map) {
+        file_system_manager.add_path_redirect(secure_manifest_base_location + "/vulkan/" + redirect, location);
     }
-#if COMMON_UNIX_PLATFORMS
-    if (settings.secure_loader_settings) {
-        platform_shim->redirect_path("/etc/vulkan/loader_settings.d", get_folder(ManifestLocation::settings_location).location());
-    } else {
-        platform_shim->redirect_path(get_env_var("HOME") + "/.local/share/vulkan/loader_settings.d",
-                                     get_folder(ManifestLocation::settings_location).location());
+
+    // Determines which unsecure path should be used
+    if (!settings.run_as_if_with_elevated_privleges) {
+        if (!settings.xdg_config_home_env_var.empty()) {
+            auto env_var_list = split_env_var_as_list(settings.xdg_config_home_env_var);
+            unsecure_manifest_base_location = env_var_list.at(0);
+            if (!env_var_list.empty()) {
+                for (auto const& [redirect, location] : unsecured_redirection_map) {
+                    file_system_manager.add_path_redirect(env_var_list.at(0) + "/vulkan/" + redirect, location);
+                }
+            }
+        } else if (!settings.xdg_data_home_env_var.empty()) {
+            auto env_var_list = split_env_var_as_list(settings.xdg_data_home_env_var);
+            if (!env_var_list.empty()) {
+                unsecure_manifest_base_location = env_var_list.at(0);
+                for (auto const& [redirect, location] : unsecured_redirection_map) {
+                    file_system_manager.add_path_redirect(env_var_list.at(0) + "/vulkan/" + redirect, location);
+                }
+            }
+        } else {
+            std::string home = settings.home_env_var;
+            for (auto const& [redirect, location] : unsecured_redirection_map) {
+                unsecure_manifest_base_location = home + "/.config";
+                file_system_manager.add_path_redirect(home + "/.config/vulkan/" + redirect, location);
+            }
+        }
     }
 #endif
 
 #if defined(__APPLE__)
+    // Since XDG env-var shouldn't ever be defined on apple, FALLBACK_DATA_DIRS takes over as the 'global' location to search, eg
+    // /usr/local/share
+    auto env_var_list = split_env_var_as_list(FALLBACK_DATA_DIRS);
+    assert(env_var_list.size() > 0 && "FALLBACK_DATA_DIRS was set to an empty path");
+    secure_manifest_base_location = env_var_list.at(0);
+    for (auto const& [redirect, location] : secured_redirection_map) {
+        file_system_manager.add_path_redirect(secure_manifest_base_location + "/vulkan/" + redirect, location);
+    }
+
+    std::string home = settings.home_env_var;
+    unsecure_manifest_base_location = home + "/.config";
+    for (auto const& [redirect, location] : unsecured_redirection_map) {
+        file_system_manager.add_path_redirect(home + "/.config/vulkan/" + redirect, location);
+    }
+
     // Necessary since bundles look in sub folders for manifests, not the test framework folder itself
     auto bundle_location = get_folder(ManifestLocation::macos_bundle).location();
-    platform_shim->redirect_path(bundle_location / "vulkan/icd.d", bundle_location);
-    platform_shim->redirect_path(bundle_location / "vulkan/explicit_layer.d", bundle_location);
-    platform_shim->redirect_path(bundle_location / "vulkan/implicit_layer.d", bundle_location);
+    file_system_manager.add_path_redirect(bundle_location / "vulkan/icd.d", ManifestLocation::macos_bundle);
+    file_system_manager.add_path_redirect(bundle_location / "vulkan/explicit_layer.d", ManifestLocation::macos_bundle);
+    file_system_manager.add_path_redirect(bundle_location / "vulkan/implicit_layer.d", ManifestLocation::macos_bundle);
 #endif
-    // only set the settings file if there are elements in the app_specific_settings vector
-    if (!settings.loader_settings.app_specific_settings.empty()) {
-        update_loader_settings(settings.loader_settings);
-    }
+
+    platform_shim->is_finished_setup = true;
 }
 
 FrameworkEnvironment::~FrameworkEnvironment() {
     // This is necessary to prevent the folder manager from using dead memory during destruction.
-    // What happens is that each folder manager tries to cleanup itself. Except, folders that were never called did not have their
-    // DirEntry array's filled out. So when that folder calls delete_folder, which calls readdir, the shim tries to order the files.
-    // Except, the list of files is in a object that is currently being destroyed.
+    // What happens is that each folder manager tries to cleanup itself. Except, folders that were never called did not have
+    // their DirEntry array's filled out. So when that folder calls delete_folder, which calls readdir, the shim tries to order
+    // the files. Except, the list of files is in a object that is currently being destroyed.
     platform_shim->is_during_destruction = true;
 }
 
-TestICD& FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept {
+ManifestLocation FrameworkEnvironment::map_discovery_type_to_location(ManifestDiscoveryType discovery_type,
+                                                                      ManifestCategory category) {
+    switch (discovery_type) {
+        case (ManifestDiscoveryType::env_var):
+            switch (category) {
+                case (ManifestCategory::explicit_layer):
+                    return ManifestLocation::explicit_layer_env_var;
+                case (ManifestCategory::implicit_layer):
+                    return ManifestLocation::implicit_layer_env_var;
+                case (ManifestCategory::icd):
+                    return ManifestLocation::driver_env_var;
+                default:
+                    return ManifestLocation::null;
+            }
+        case (ManifestDiscoveryType::add_env_var):
+            switch (category) {
+                case (ManifestCategory::explicit_layer):
+                    return ManifestLocation::explicit_layer_add_env_var;
+                case (ManifestCategory::implicit_layer):
+                    return ManifestLocation::implicit_layer_add_env_var;
+                case (ManifestCategory::icd):
+                    return ManifestLocation::driver_env_var;
+                default:
+                    return ManifestLocation::null;
+            }
+#if defined(WIN32)
+        case (ManifestDiscoveryType::windows_app_package):
+            return ManifestLocation::windows_app_package;
+#endif
+        case (ManifestDiscoveryType::override_folder):
+            return ManifestLocation::override_layer;
+#if defined(__APPLE__)
+        case (ManifestDiscoveryType::macos_bundle):
+            return ManifestLocation::macos_bundle;
+#endif
+        case (ManifestDiscoveryType::unsecured_generic):
+            switch (category) {
+                case (ManifestCategory::explicit_layer):
+                    return ManifestLocation::unsecured_explicit_layer;
+                case (ManifestCategory::implicit_layer):
+                    return ManifestLocation::unsecured_implicit_layer;
+                case (ManifestCategory::icd):
+                    return ManifestLocation::unsecured_driver;
+                case (ManifestCategory::settings):
+                    return ManifestLocation::unsecured_settings;
+                default:
+                    return ManifestLocation::null;
+            }
+        case (ManifestDiscoveryType::null_dir):
+        case (ManifestDiscoveryType::none):
+            return ManifestLocation::null;
+        default:
+        case (ManifestDiscoveryType::generic):
+            switch (category) {
+                case (ManifestCategory::explicit_layer):
+                    return ManifestLocation::explicit_layer;
+                case (ManifestCategory::implicit_layer):
+                    return ManifestLocation::implicit_layer;
+                case (ManifestCategory::icd):
+                    return ManifestLocation::driver;
+                case (ManifestCategory::settings):
+                    return ManifestLocation::settings_location;
+                default:
+                    return ManifestLocation::null;
+            }
+    }
+}
+
+TestICD& FrameworkEnvironment::add_icd(std::filesystem::path const& path, ManifestOptions args, ManifestICD manifest) noexcept {
+    manifest.set_lib_path(path);
+
+    if (args.json_name.empty()) {
+        args.json_name = "test_icd_" + std::to_string(icds.size()) + ".json";
+    }
+
     size_t cur_icd_index = icds.size();
-    fs::FolderManager* folder = &get_folder(ManifestLocation::driver);
-    if (icd_details.discovery_type == ManifestDiscoveryType::env_var ||
-        icd_details.discovery_type == ManifestDiscoveryType::add_env_var) {
-        folder = &get_folder(ManifestLocation::driver_env_var);
+    auto& folder = get_folder(map_discovery_type_to_location(args.discovery_type, ManifestCategory::icd));
+
+    if (args.discovery_type == ManifestDiscoveryType::env_var) {
+        if (args.is_dir) {
+            env_var_vk_icd_filenames.add_to_list(folder.location());
+        } else {
+            env_var_vk_icd_filenames.add_to_list(folder.location() / args.json_name);
+        }
+    } else if (args.discovery_type == ManifestDiscoveryType::add_env_var) {
+        if (args.is_dir) {
+            add_env_var_vk_icd_filenames.add_to_list(folder.location());
+        } else {
+            add_env_var_vk_icd_filenames.add_to_list(folder.location() / args.json_name);
+        }
     }
-    if (icd_details.discovery_type == ManifestDiscoveryType::windows_app_package) {
-        folder = &get_folder(ManifestLocation::windows_app_package);
-    }
-    if (icd_details.discovery_type == ManifestDiscoveryType::macos_bundle) {
-        folder = &get_folder(ManifestLocation::macos_bundle);
-    }
-    if (icd_details.discovery_type == ManifestDiscoveryType::unsecured_generic) {
-        folder = &get_folder(ManifestLocation::unsecured_location);
-    }
-    if (icd_details.discovery_type == ManifestDiscoveryType::null_dir ||
-        icd_details.discovery_type == ManifestDiscoveryType::none) {
-        folder = &get_folder(ManifestLocation::null);
-    }
-    if (!icd_details.is_fake) {
-        std::filesystem::path new_lib_name = icd_details.icd_manifest.lib_path.stem();
+    if (!args.is_fake) {
+        std::filesystem::path new_lib_name = manifest.lib_path.stem();
         new_lib_name += "_";
         new_lib_name += std::to_string(cur_icd_index);
-        new_lib_name += icd_details.icd_manifest.lib_path.extension();
-        auto new_driver_location = folder->copy_file(icd_details.icd_manifest.lib_path, new_lib_name);
+        new_lib_name += manifest.lib_path.extension();
+        auto new_driver_location = folder.copy_file(manifest.lib_path, new_lib_name);
 
-#if COMMON_UNIX_PLATFORMS
-        if (icd_details.library_path_type == LibraryPathType::default_search_paths) {
-            platform_shim->redirect_dlopen_name(new_lib_name, new_driver_location);
-        } else if (icd_details.library_path_type == LibraryPathType::relative) {
-            platform_shim->redirect_dlopen_name(std::filesystem::path(SYSCONFDIR) / "vulkan" / "icd.d" / "." / new_lib_name,
-                                                new_driver_location);
+#if TESTING_COMMON_UNIX_PLATFORMS
+        if (args.library_path_type == LibraryPathType::default_search_paths) {
+            platform_shim->add_system_library(new_lib_name, new_driver_location);
         }
 #endif
 #if defined(WIN32)
-        if (icd_details.library_path_type == LibraryPathType::default_search_paths) {
+        if (args.library_path_type == LibraryPathType::default_search_paths) {
             SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_USER_DIRS);
             AddDllDirectory(new_driver_location.parent_path().native().c_str());
         }
 #endif
         icds.push_back(TestICDHandle(new_driver_location));
-        icds.back().reset_icd();
-        if (icd_details.library_path_type == LibraryPathType::relative) {
-            icd_details.icd_manifest.lib_path = std::filesystem::path(".") / new_lib_name;
-        } else if (icd_details.library_path_type == LibraryPathType::default_search_paths) {
-            icd_details.icd_manifest.lib_path = new_lib_name;
+        icds.back().reset();
+        if (args.library_path_type == LibraryPathType::relative) {
+            manifest.lib_path = std::filesystem::path(".") / new_lib_name;
+        } else if (args.library_path_type == LibraryPathType::default_search_paths) {
+            manifest.lib_path = new_lib_name;
         } else {
-            icd_details.icd_manifest.lib_path = new_driver_location;
+            manifest.lib_path = new_driver_location;
         }
     }
-    if (icd_details.discovery_type != ManifestDiscoveryType::none) {
-        std::filesystem::path new_manifest_path = icd_details.json_name.stem();
-        if (!icd_details.disable_icd_inc) {
-            new_manifest_path += "_";
-            new_manifest_path += std::to_string(cur_icd_index);
-        }
-        new_manifest_path += ".json";
-        icds.back().manifest_path = folder->write_manifest(new_manifest_path, icd_details.icd_manifest.get_manifest_str());
+    if (args.discovery_type != ManifestDiscoveryType::none) {
+        icds.back().manifest_path = folder.write_manifest(args.json_name, manifest.get_manifest_str());
         icds.back().shimmed_manifest_path = icds.back().manifest_path;
-        switch (icd_details.discovery_type) {
-            default:
-            case (ManifestDiscoveryType::generic):
-                platform_shim->add_manifest(ManifestCategory::icd, icds.back().manifest_path);
-#if COMMON_UNIX_PLATFORMS
-                icds.back().shimmed_manifest_path =
-                    platform_shim->query_default_redirect_path(ManifestCategory::icd) / new_manifest_path;
+
+#if defined(WIN32)
+        // only add the manifest to the registry if its a generic location (as if it was installed) - both system and user local
+        if (args.discovery_type == ManifestDiscoveryType::generic) {
+            platform_shim->add_manifest_to_registry(ManifestCategory::icd, icds.back().manifest_path);
+        }
+        if (args.discovery_type == ManifestDiscoveryType::unsecured_generic) {
+            platform_shim->add_unsecured_manifest_to_registry(ManifestCategory::icd, icds.back().manifest_path);
+        }
+        if (args.discovery_type == ManifestDiscoveryType::windows_app_package) {
+            platform_shim->set_app_package_path(folder.location());
+        }
 #endif
-                break;
-            case (ManifestDiscoveryType::env_var):
-                if (icd_details.is_dir) {
-                    env_var_vk_icd_filenames.add_to_list(folder->location());
-                } else {
-                    env_var_vk_icd_filenames.add_to_list(folder->location() / new_manifest_path);
-                }
-                platform_shim->add_known_path(folder->location());
-                break;
-            case (ManifestDiscoveryType::add_env_var):
-                if (icd_details.is_dir) {
-                    add_env_var_vk_icd_filenames.add_to_list(folder->location());
-                } else {
-                    add_env_var_vk_icd_filenames.add_to_list(folder->location() / new_manifest_path);
-                }
-                platform_shim->add_known_path(folder->location());
-                break;
-            case (ManifestDiscoveryType::macos_bundle):
-                platform_shim->add_manifest(ManifestCategory::icd, icds.back().manifest_path);
-                break;
-            case (ManifestDiscoveryType::unsecured_generic):
-                platform_shim->add_unsecured_manifest(ManifestCategory::icd, icds.back().manifest_path);
-                break;
-            case (ManifestDiscoveryType::null_dir):
-                break;
-#if defined(_WIN32)
-            case (ManifestDiscoveryType::windows_app_package):
-                platform_shim->set_app_package_path(folder->location());
-                break;
+#if TESTING_COMMON_UNIX_PLATFORMS
+        if (args.discovery_type == ManifestDiscoveryType::generic ||
+            args.discovery_type == ManifestDiscoveryType::unsecured_generic) {
+            icds.back().shimmed_manifest_path =
+                file_system_manager.get_path_redirect_by_manifest_location(
+                    args.discovery_type == ManifestDiscoveryType::unsecured_generic ? ManifestLocation::driver
+                                                                                    : ManifestLocation::unsecured_driver) /
+                args.json_name;
+        }
 #endif
+    }
+    return icds.back().get_test_binary();
+}
+
+void FrameworkEnvironment::add_implicit_layer(ManifestOptions args, ManifestLayer layer_manifest) noexcept {
+    add_layer_impl(args, layer_manifest, ManifestCategory::implicit_layer);
+}
+void FrameworkEnvironment::add_explicit_layer(ManifestOptions args, ManifestLayer layer_manifest) noexcept {
+    add_layer_impl(args, layer_manifest, ManifestCategory::explicit_layer);
+}
+
+void FrameworkEnvironment::add_layer_impl(ManifestOptions args, ManifestLayer manifest, ManifestCategory category) {
+    if (args.json_name.empty()) {
+        args.json_name = "test_layer_" + std::to_string(created_layer_count) + ".json";
+        created_layer_count++;
+    }
+
+    auto& folder = get_folder(map_discovery_type_to_location(args.discovery_type, category));
+
+    if (args.discovery_type == ManifestDiscoveryType::env_var || args.discovery_type == ManifestDiscoveryType::add_env_var) {
+        std::filesystem::path path_to_add = folder.location();
+        if (!args.is_dir) {
+            path_to_add /= args.json_name;
+        }
+
+        EnvVarWrapper* env_var_to_use = nullptr;
+        if (args.discovery_type == ManifestDiscoveryType::env_var && category == ManifestCategory::explicit_layer) {
+            env_var_vk_layer_paths.add_to_list(path_to_add);
+        } else if (args.discovery_type == ManifestDiscoveryType::env_var && category == ManifestCategory::implicit_layer) {
+            env_var_vk_implicit_layer_paths.add_to_list(path_to_add);
+        } else if (args.discovery_type == ManifestDiscoveryType::add_env_var && category == ManifestCategory::explicit_layer) {
+            add_env_var_vk_layer_paths.add_to_list(path_to_add);
+        } else if (args.discovery_type == ManifestDiscoveryType::add_env_var && category == ManifestCategory::implicit_layer) {
+            add_env_var_vk_implicit_layer_paths.add_to_list(path_to_add);
         }
     }
-    return icds.back().get_test_icd();
-}
 
-void FrameworkEnvironment::add_implicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept {
-    add_layer_impl(TestLayerDetails{layer_manifest, json_name}, ManifestCategory::implicit_layer);
-}
-void FrameworkEnvironment::add_explicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept {
-    add_layer_impl(TestLayerDetails{layer_manifest, json_name}, ManifestCategory::explicit_layer);
-}
-void FrameworkEnvironment::add_fake_implicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept {
-    add_layer_impl(TestLayerDetails{layer_manifest, json_name}.set_is_fake(true), ManifestCategory::implicit_layer);
-}
-void FrameworkEnvironment::add_fake_explicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept {
-    add_layer_impl(TestLayerDetails{layer_manifest, json_name}.set_is_fake(true), ManifestCategory::explicit_layer);
-}
-void FrameworkEnvironment::add_implicit_layer(TestLayerDetails layer_details) noexcept {
-    add_layer_impl(layer_details, ManifestCategory::implicit_layer);
-}
-void FrameworkEnvironment::add_explicit_layer(TestLayerDetails layer_details) noexcept {
-    add_layer_impl(layer_details, ManifestCategory::explicit_layer);
-}
-
-void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, ManifestCategory category) {
-    fs::FolderManager* fs_ptr = &get_folder(ManifestLocation::explicit_layer);
-    switch (layer_details.discovery_type) {
-        default:
-        case (ManifestDiscoveryType::generic):
-            if (category == ManifestCategory::implicit_layer) fs_ptr = &get_folder(ManifestLocation::implicit_layer);
-            break;
-        case (ManifestDiscoveryType::env_var):
-            if (category == ManifestCategory::explicit_layer) {
-                fs_ptr = &get_folder(ManifestLocation::explicit_layer_env_var);
-                if (layer_details.is_dir) {
-                    env_var_vk_layer_paths.add_to_list(fs_ptr->location());
-                } else {
-                    env_var_vk_layer_paths.add_to_list(fs_ptr->location() / layer_details.json_name);
-                }
-            }
-            if (category == ManifestCategory::implicit_layer) {
-                fs_ptr = &get_folder(ManifestLocation::implicit_layer_env_var);
-                if (layer_details.is_dir) {
-                    env_var_vk_implicit_layer_paths.add_to_list(fs_ptr->location());
-                } else {
-                    env_var_vk_implicit_layer_paths.add_to_list(fs_ptr->location() / layer_details.json_name);
-                }
-            }
-            platform_shim->add_known_path(fs_ptr->location());
-            break;
-        case (ManifestDiscoveryType::add_env_var):
-            if (category == ManifestCategory::explicit_layer) {
-                fs_ptr = &get_folder(ManifestLocation::explicit_layer_add_env_var);
-                if (layer_details.is_dir) {
-                    add_env_var_vk_layer_paths.add_to_list(fs_ptr->location());
-                } else {
-                    add_env_var_vk_layer_paths.add_to_list(fs_ptr->location() / layer_details.json_name);
-                }
-            }
-            if (category == ManifestCategory::implicit_layer) {
-                fs_ptr = &get_folder(ManifestLocation::implicit_layer_add_env_var);
-                if (layer_details.is_dir) {
-                    add_env_var_vk_implicit_layer_paths.add_to_list(fs_ptr->location());
-                } else {
-                    add_env_var_vk_implicit_layer_paths.add_to_list(fs_ptr->location() / layer_details.json_name);
-                }
-            }
-            platform_shim->add_known_path(fs_ptr->location());
-            break;
-        case (ManifestDiscoveryType::override_folder):
-            fs_ptr = &get_folder(ManifestLocation::override_layer);
-            break;
-        case (ManifestDiscoveryType::macos_bundle):
-            fs_ptr = &(get_folder(ManifestLocation::macos_bundle));
-            break;
-        case (ManifestDiscoveryType::unsecured_generic):
-            fs_ptr = &(get_folder(ManifestLocation::unsecured_location));
-            break;
-        case (ManifestDiscoveryType::windows_app_package):
-            fs_ptr = &(get_folder(ManifestLocation::windows_app_package));
-            break;
-        case (ManifestDiscoveryType::none):
-        case (ManifestDiscoveryType::null_dir):
-            fs_ptr = &(get_folder(ManifestLocation::null));
-            break;
-    }
-    auto& folder = *fs_ptr;
     size_t new_layers_start = layers.size();
-    for (auto& layer : layer_details.layer_manifest.layers) {
+    for (auto& layer : manifest.layers) {
         if (!layer.lib_path.empty()) {
             std::filesystem::path new_lib_path = layer.lib_path.stem();
             new_lib_path += "_";
@@ -652,18 +529,13 @@
 
             auto new_layer_location = folder.copy_file(layer.lib_path, new_lib_path);
 
-#if COMMON_UNIX_PLATFORMS
-            if (layer_details.library_path_type == LibraryPathType::default_search_paths) {
-                platform_shim->redirect_dlopen_name(new_lib_path, new_layer_location);
-            }
-            if (layer_details.library_path_type == LibraryPathType::relative) {
-                platform_shim->redirect_dlopen_name(
-                    std::filesystem::path(SYSCONFDIR) / "vulkan" / category_path_name(category) / "." / new_lib_path,
-                    new_layer_location);
+#if TESTING_COMMON_UNIX_PLATFORMS
+            if (args.library_path_type == LibraryPathType::default_search_paths) {
+                platform_shim->add_system_library(new_lib_path, new_layer_location);
             }
 #endif
 #if defined(WIN32)
-            if (layer_details.library_path_type == LibraryPathType::default_search_paths) {
+            if (args.library_path_type == LibraryPathType::default_search_paths) {
                 SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_USER_DIRS);
                 AddDllDirectory(new_layer_location.parent_path().native().c_str());
             }
@@ -671,42 +543,51 @@
 
             // Don't load the layer binary if using any of the wrap objects layers, since it doesn't export the same interface
             // functions
-            if (!layer_details.is_fake &&
-                layer.lib_path.stem().string().find(std::filesystem::path(TEST_LAYER_WRAP_OBJECTS).stem().string()) ==
-                    std::string::npos) {
+            if (!args.is_fake && layer.lib_path.stem().string().find(
+                                     std::filesystem::path(TEST_LAYER_WRAP_OBJECTS).stem().string()) == std::string::npos) {
                 layers.push_back(TestLayerHandle(new_layer_location));
-                layers.back().reset_layer();
+                layers.back().reset();
             }
-            if (layer_details.library_path_type == LibraryPathType::relative) {
+            if (args.library_path_type == LibraryPathType::relative) {
                 layer.lib_path = std::filesystem::path(".") / new_lib_path;
-            } else if (layer_details.library_path_type == LibraryPathType::default_search_paths) {
+            } else if (args.library_path_type == LibraryPathType::default_search_paths) {
                 layer.lib_path = new_lib_path;
             } else {
                 layer.lib_path = new_layer_location;
             }
         }
     }
-    if (layer_details.discovery_type != ManifestDiscoveryType::none) {
+    if (args.discovery_type != ManifestDiscoveryType::none) {
         // Write a manifest file to a folder as long as the discovery type isn't none
-        auto layer_manifest_loc = folder.write_manifest(layer_details.json_name, layer_details.layer_manifest.get_manifest_str());
+        auto layer_manifest_loc = folder.write_manifest(args.json_name, manifest.get_manifest_str());
+#if defined(WIN32)
         // only add the manifest to the registry if its a generic location (as if it was installed) - both system and user local
-        if (layer_details.discovery_type == ManifestDiscoveryType::generic) {
-            platform_shim->add_manifest(category, layer_manifest_loc);
+        if (args.discovery_type == ManifestDiscoveryType::generic) {
+            platform_shim->add_manifest_to_registry(category, layer_manifest_loc);
         }
-        if (layer_details.discovery_type == ManifestDiscoveryType::unsecured_generic) {
-            platform_shim->add_unsecured_manifest(category, layer_manifest_loc);
+        if (args.discovery_type == ManifestDiscoveryType::unsecured_generic) {
+            platform_shim->add_unsecured_manifest_to_registry(category, layer_manifest_loc);
         }
-#if defined(_WIN32)
-        if (layer_details.discovery_type == ManifestDiscoveryType::windows_app_package) {
-            platform_shim->set_app_package_path(layer_manifest_loc);
+        if (args.discovery_type == ManifestDiscoveryType::windows_app_package) {
+            platform_shim->set_app_package_path(folder.location());
         }
 #endif
         for (size_t i = new_layers_start; i < layers.size(); i++) {
             layers.at(i).manifest_path = layer_manifest_loc;
             layers.at(i).shimmed_manifest_path = layer_manifest_loc;
-#if COMMON_UNIX_PLATFORMS
-            if (layer_details.discovery_type == ManifestDiscoveryType::generic) {
-                layers.at(i).shimmed_manifest_path = platform_shim->query_default_redirect_path(category) / layer_details.json_name;
+#if TESTING_COMMON_UNIX_PLATFORMS
+            if (args.discovery_type == ManifestDiscoveryType::generic ||
+                args.discovery_type == ManifestDiscoveryType::unsecured_generic) {
+                ManifestLocation location = ManifestLocation::null;
+                if (args.discovery_type == ManifestDiscoveryType::generic) {
+                    location = (category == ManifestCategory::explicit_layer ? ManifestLocation::explicit_layer
+                                                                             : ManifestLocation::implicit_layer);
+                } else if (args.discovery_type == ManifestDiscoveryType::unsecured_generic) {
+                    location = (category == ManifestCategory::explicit_layer ? ManifestLocation::unsecured_explicit_layer
+                                                                             : ManifestLocation::unsecured_implicit_layer);
+                }
+                layers.at(i).shimmed_manifest_path =
+                    file_system_manager.get_path_redirect_by_manifest_location(location) / args.json_name;
             }
 #endif
         }
@@ -772,6 +653,42 @@
             }
             writer.EndArray();
         }
+        if (!setting.driver_configurations.empty()) {
+            writer.AddKeyedBool("additional_drivers_use_exclusively", setting.additional_drivers_use_exclusively);
+            writer.StartKeyedArray("additional_drivers");
+            for (const auto& driver : setting.driver_configurations) {
+                writer.StartObject();
+                writer.AddKeyedString("path", driver.path);
+                writer.EndObject();
+            }
+            writer.EndArray();
+        }
+        if (!setting.device_configurations.empty()) {
+            writer.StartKeyedArray("device_configurations");
+            for (const auto& device : setting.device_configurations) {
+                writer.StartObject();
+                if (!device.deviceName.empty()) {
+                    writer.AddKeyedString("deviceName", device.deviceName);
+                }
+                if (!device.driverName.empty()) {
+                    writer.AddKeyedString("driverName", device.driverName);
+                }
+                writer.StartKeyedArray("deviceUUID");
+                for (const auto& u : device.deviceUUID) {
+                    writer.AddInteger(u);
+                }
+                writer.EndArray();
+
+                writer.StartKeyedArray("driverUUID");
+                for (const auto& u : device.driverUUID) {
+                    writer.AddInteger(u);
+                }
+                writer.EndArray();
+                writer.AddKeyedInteger("driverVersion", device.driverVersion);
+                writer.EndObject();
+            }
+            writer.EndArray();
+        }
         writer.EndObject();
     }
     if (!one_setting_file) {
@@ -781,73 +698,79 @@
     writer.EndObject();
     return writer.output;
 }
-void FrameworkEnvironment::write_settings_file(std::string const& file_contents) {
-    auto out_path = get_folder(ManifestLocation::settings_location).write_manifest("vk_loader_settings.json", file_contents);
+void FrameworkEnvironment::write_settings_file(std::string const& file_contents, bool write_to_secure_location) {
+    auto location = write_to_secure_location ? ManifestLocation::settings_location : ManifestLocation::unsecured_settings;
+    auto out_path = get_folder(location).write_manifest("vk_loader_settings.json", file_contents);
 #if defined(WIN32)
-    platform_shim->hkey_current_user_settings.clear();
-    platform_shim->hkey_local_machine_settings.clear();
+    if (write_to_secure_location) {
+        platform_shim->hkey_local_machine_settings.clear();
+        platform_shim->add_manifest_to_registry(ManifestCategory::settings, out_path);
+    } else {
+        platform_shim->hkey_current_user_settings.clear();
+        platform_shim->add_unsecured_manifest_to_registry(ManifestCategory::settings, out_path);
+    }
 #endif
-    if (settings.secure_loader_settings)
-        platform_shim->add_manifest(ManifestCategory::settings, out_path);
-    else
-        platform_shim->add_unsecured_manifest(ManifestCategory::settings, out_path);
 }
-void FrameworkEnvironment::update_loader_settings(const LoaderSettings& settings) noexcept {
-    write_settings_file(get_loader_settings_file_contents(settings));
+void FrameworkEnvironment::update_loader_settings(const LoaderSettings& settings, bool write_to_secure_location) noexcept {
+    write_settings_file(get_loader_settings_file_contents(settings), write_to_secure_location);
 }
 void FrameworkEnvironment::remove_loader_settings() {
     get_folder(ManifestLocation::settings_location).remove("vk_loader_settings.json");
 }
+void FrameworkEnvironment::write_file_from_string(std::string const& source_string, ManifestCategory category,
+                                                  ManifestLocation location, std::string const& file_name) {
+    auto out_path = get_folder(location).write_manifest(file_name, source_string);
+
+#if defined(WIN32)
+    // Only writes to the hkey_local_machine registries, doesn't support hkey_current_user registries
+    platform_shim->add_manifest_to_registry(category, out_path);
+#endif
+}
 void FrameworkEnvironment::write_file_from_source(const char* source_file, ManifestCategory category, ManifestLocation location,
                                                   std::string const& file_name) {
     std::fstream file{source_file, std::ios_base::in};
     ASSERT_TRUE(file.is_open());
     std::stringstream file_stream;
     file_stream << file.rdbuf();
-
-    auto out_path = get_folder(location).write_manifest(file_name, file_stream.str());
-
-    if (settings.secure_loader_settings)
-        platform_shim->add_manifest(category, out_path);
-    else
-        platform_shim->add_unsecured_manifest(category, out_path);
+    write_file_from_string(file_stream.str(), category, location, file_name);
 }
 
-TestICD& FrameworkEnvironment::get_test_icd(size_t index) noexcept { return icds[index].get_test_icd(); }
-TestICD& FrameworkEnvironment::reset_icd(size_t index) noexcept { return icds[index].reset_icd(); }
-std::filesystem::path FrameworkEnvironment::get_test_icd_path(size_t index) noexcept { return icds[index].get_icd_full_path(); }
-std::filesystem::path FrameworkEnvironment::get_icd_manifest_path(size_t index) noexcept {
-    return icds[index].get_icd_manifest_path();
-}
+TestICD& FrameworkEnvironment::get_test_icd(size_t index) noexcept { return icds[index].get_test_binary(); }
+TestICD& FrameworkEnvironment::reset_icd(size_t index) noexcept { return icds[index].reset(); }
+std::filesystem::path FrameworkEnvironment::get_test_icd_path(size_t index) noexcept { return icds[index].get_full_path(); }
+std::filesystem::path FrameworkEnvironment::get_icd_manifest_path(size_t index) noexcept { return icds[index].get_manifest_path(); }
 std::filesystem::path FrameworkEnvironment::get_shimmed_icd_manifest_path(size_t index) noexcept {
     return icds[index].get_shimmed_manifest_path();
 }
 
-TestLayer& FrameworkEnvironment::get_test_layer(size_t index) noexcept { return layers[index].get_test_layer(); }
-TestLayer& FrameworkEnvironment::reset_layer(size_t index) noexcept { return layers[index].reset_layer(); }
-std::filesystem::path FrameworkEnvironment::get_test_layer_path(size_t index) noexcept {
-    return layers[index].get_layer_full_path();
-}
+TestLayer& FrameworkEnvironment::get_test_layer(size_t index) noexcept { return layers[index].get_test_binary(); }
+TestLayer& FrameworkEnvironment::reset_layer(size_t index) noexcept { return layers[index].reset(); }
+std::filesystem::path FrameworkEnvironment::get_test_layer_path(size_t index) noexcept { return layers[index].get_full_path(); }
 std::filesystem::path FrameworkEnvironment::get_layer_manifest_path(size_t index) noexcept {
-    return layers[index].get_layer_manifest_path();
+    return layers[index].get_manifest_path();
 }
 std::filesystem::path FrameworkEnvironment::get_shimmed_layer_manifest_path(size_t index) noexcept {
     return layers[index].get_shimmed_manifest_path();
 }
 
-fs::FolderManager& FrameworkEnvironment::get_folder(ManifestLocation location) noexcept {
-    // index it directly using the enum location since they will always be in that order
-    return folders.at(static_cast<size_t>(location));
+fs::Folder& FrameworkEnvironment::get_folder(ManifestLocation location) noexcept {
+    return file_system_manager.get_folder(location);
 }
-fs::FolderManager const& FrameworkEnvironment::get_folder(ManifestLocation location) const noexcept {
-    return folders.at(static_cast<size_t>(location));
+fs::Folder const& FrameworkEnvironment::get_folder(ManifestLocation location) const noexcept {
+    return file_system_manager.get_folder(location);
 }
 #if defined(__APPLE__)
 void FrameworkEnvironment::setup_macos_bundle() noexcept {
-    platform_shim->bundle_contents = get_folder(ManifestLocation::macos_bundle).location();
+    platform_shim->bundle_contents = file_system_manager.get_folder(ManifestLocation::macos_bundle).location();
 }
 #endif
 
+void FrameworkEnvironment::add_symlink(ManifestLocation location, std::filesystem::path const& target,
+                                       std::filesystem::path const& link_name) {
+    auto symlinked_path = get_folder(location).add_symlink(target, link_name);
+    file_system_manager.add_path_redirect(symlinked_path, location);
+}
+
 std::vector<VkExtensionProperties> FrameworkEnvironment::GetInstanceExtensions(uint32_t expected_count, const char* layer_name) {
     uint32_t count = 0;
     VkResult res = vulkan_functions.vkEnumerateInstanceExtensionProperties(layer_name, &count, nullptr);
@@ -872,69 +795,72 @@
 }
 
 template <typename CreationFunc, typename CreateInfo>
-VkResult create_surface_helper(VulkanFunctions* functions, VkInstance inst, VkSurfaceKHR& surface, const char* load_func_name) {
+VkResult create_surface_helper(VulkanFunctions* functions, VkInstance inst, VkSurfaceKHR& surface, const char* load_func_name,
+                               VkStructureType stype) {
     CreationFunc pfn_CreateSurface = functions->load(inst, load_func_name);
     if (!pfn_CreateSurface) return VK_ERROR_EXTENSION_NOT_PRESENT;
-    CreateInfo surf_create_info{};
+    CreateInfo surf_create_info{stype};
     return pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface);
 }
 VkResult create_surface(VulkanFunctions* functions, VkInstance inst, VkSurfaceKHR& surface,
                         [[maybe_unused]] const char* api_selection) {
 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
-    return create_surface_helper<PFN_vkCreateAndroidSurfaceKHR, VkAndroidSurfaceCreateInfoKHR>(functions, inst, surface,
-                                                                                               "vkCreateAndroidSurfaceKHR");
+    return create_surface_helper<PFN_vkCreateAndroidSurfaceKHR, VkAndroidSurfaceCreateInfoKHR>(
+        functions, inst, surface, "vkCreateAndroidSurfaceKHR", VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR);
 #elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
-    return create_surface_helper<PFN_vkCreateDirectFBSurfaceEXT, VkDirectFBSurfaceCreateInfoEXT>(functions, inst, surface,
-                                                                                                 "vkCreateDirectFBSurfaceEXT");
+    return create_surface_helper<PFN_vkCreateDirectFBSurfaceEXT, VkDirectFBSurfaceCreateInfoEXT>(
+        functions, inst, surface, "vkCreateDirectFBSurfaceEXT", VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT);
 #elif defined(VK_USE_PLATFORM_FUCHSIA)
     return create_surface_helper<PFN_vkCreateImagePipeSurfaceFUCHSIA, VkImagePipeSurfaceCreateInfoFUCHSIA>(
-        functions, inst, surface, "vkCreateImagePipeSurfaceFUCHSIA");
+        functions, inst, surface, "vkCreateImagePipeSurfaceFUCHSIA", VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA);
 #elif defined(VK_USE_PLATFORM_GGP)
     return create_surface_helper<PFN__vkCreateStreamDescriptorSurfaceGGP, VkStreamDescriptorSurfaceCreateInfoGGP>(
-        functions, inst, surface, "vkCreateStreamDescriptorSurfaceGGP");
+        functions, inst, surface, "vkCreateStreamDescriptorSurfaceGGP",
+        VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP);
 #elif defined(VK_USE_PLATFORM_IOS_MVK)
-    return create_surface_helper<PFN_vkCreateIOSSurfaceMVK, VkIOSSurfaceCreateInfoMVK>(functions, inst, surface,
-                                                                                       "vkCreateIOSSurfaceMVK");
+    return create_surface_helper<PFN_vkCreateIOSSurfaceMVK, VkIOSSurfaceCreateInfoMVK>(
+        functions, inst, surface, "vkCreateIOSSurfaceMVK", VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK);
 #elif defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)
 #if defined(VK_USE_PLATFORM_MACOS_MVK)
     if (api_selection != nullptr && string_eq(api_selection, "VK_USE_PLATFORM_MACOS_MVK"))
-        return create_surface_helper<PFN_vkCreateMacOSSurfaceMVK, VkMacOSSurfaceCreateInfoMVK>(functions, inst, surface,
-                                                                                               "vkCreateMacOSSurfaceMVK");
+        return create_surface_helper<PFN_vkCreateMacOSSurfaceMVK, VkMacOSSurfaceCreateInfoMVK>(
+            functions, inst, surface, "vkCreateMacOSSurfaceMVK", VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK);
 #endif
 #if defined(VK_USE_PLATFORM_METAL_EXT)
     if (api_selection == nullptr || (api_selection != nullptr && string_eq(api_selection, "VK_USE_PLATFORM_METAL_EXT")))
-        return create_surface_helper<PFN_vkCreateMetalSurfaceEXT, VkMetalSurfaceCreateInfoEXT>(functions, inst, surface,
-                                                                                               "vkCreateMetalSurfaceEXT");
+        return create_surface_helper<PFN_vkCreateMetalSurfaceEXT, VkMetalSurfaceCreateInfoEXT>(
+            functions, inst, surface, "vkCreateMetalSurfaceEXT", VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT);
 #endif
     return VK_ERROR_NOT_PERMITTED_KHR;
 #elif defined(VK_USE_PLATFORM_SCREEN_QNX)
-    return create_surface_helper<PFN_vkCreateScreenSurfaceQNX, VkScreenSurfaceCreateInfoQNX>(functions, inst, surface,
-                                                                                             "vkCreateScreenSurfaceQNX");
+    return create_surface_helper<PFN_vkCreateScreenSurfaceQNX, VkScreenSurfaceCreateInfoQNX>(
+        functions, inst, surface, "vkCreateScreenSurfaceQNX", VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX);
 #elif defined(VK_USE_PLATFORM_VI_NN)
-    return create_surface_helper<PFN_vkCreateViSurfaceNN, VkViSurfaceCreateInfoNN>(functions, inst, surface, "vkCreateViSurfaceNN");
+    return create_surface_helper<PFN_vkCreateViSurfaceNN, VkViSurfaceCreateInfoNN>(functions, inst, surface, "vkCreateViSurfaceNN",
+                                                                                   VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN);
 #elif defined(VK_USE_PLATFORM_WIN32_KHR)
-    return create_surface_helper<PFN_vkCreateWin32SurfaceKHR, VkWin32SurfaceCreateInfoKHR>(functions, inst, surface,
-                                                                                           "vkCreateWin32SurfaceKHR");
+    return create_surface_helper<PFN_vkCreateWin32SurfaceKHR, VkWin32SurfaceCreateInfoKHR>(
+        functions, inst, surface, "vkCreateWin32SurfaceKHR", VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR);
 #elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
 #if defined(VK_USE_PLATFORM_XLIB_KHR)
     if (string_eq(api_selection, "VK_USE_PLATFORM_XLIB_KHR"))
-        return create_surface_helper<PFN_vkCreateXlibSurfaceKHR, VkXlibSurfaceCreateInfoKHR>(functions, inst, surface,
-                                                                                             "vkCreateXlibSurfaceKHR");
+        return create_surface_helper<PFN_vkCreateXlibSurfaceKHR, VkXlibSurfaceCreateInfoKHR>(
+            functions, inst, surface, "vkCreateXlibSurfaceKHR", VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR);
 #endif
 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
     if (string_eq(api_selection, "VK_USE_PLATFORM_WAYLAND_KHR"))
-        return create_surface_helper<PFN_vkCreateWaylandSurfaceKHR, VkWaylandSurfaceCreateInfoKHR>(functions, inst, surface,
-                                                                                                   "vkCreateWaylandSurfaceKHR");
+        return create_surface_helper<PFN_vkCreateWaylandSurfaceKHR, VkWaylandSurfaceCreateInfoKHR>(
+            functions, inst, surface, "vkCreateWaylandSurfaceKHR", VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR);
 #endif
 #if defined(VK_USE_PLATFORM_XCB_KHR)
     if (api_selection == nullptr || string_eq(api_selection, "VK_USE_PLATFORM_XCB_KHR"))
-        return create_surface_helper<PFN_vkCreateXcbSurfaceKHR, VkXcbSurfaceCreateInfoKHR>(functions, inst, surface,
-                                                                                           "vkCreateXcbSurfaceKHR");
+        return create_surface_helper<PFN_vkCreateXcbSurfaceKHR, VkXcbSurfaceCreateInfoKHR>(
+            functions, inst, surface, "vkCreateXcbSurfaceKHR", VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR);
 #endif
     return VK_ERROR_NOT_PERMITTED_KHR;
 #else
     return create_surface_helper<PFN_vkCreateDisplayPlaneSurfaceKHR, VkDisplaySurfaceCreateInfoKHR>(
-        functions, inst, surface, "vkCreateDisplayPlaneSurfaceKHR");
+        functions, inst, surface, "vkCreateDisplayPlaneSurfaceKHR", VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR);
 #endif
 }
 VkResult create_surface(InstWrapper& inst, VkSurfaceKHR& surface, const char* api_selection) {
@@ -943,7 +869,7 @@
 
 VkResult create_debug_callback(InstWrapper& inst, const VkDebugReportCallbackCreateInfoEXT& create_info,
                                VkDebugReportCallbackEXT& callback) {
-    return inst.functions->vkCreateDebugReportCallbackEXT(inst.inst, &create_info, nullptr, &callback);
+    return inst.instance_functions.vkCreateDebugReportCallbackEXT(inst.inst, &create_info, nullptr, &callback);
 }
 
 extern "C" {
diff --git a/tests/framework/test_environment.h b/tests/framework/test_environment.h
index 903bfd8..fe164d4 100644
--- a/tests/framework/test_environment.h
+++ b/tests/framework/test_environment.h
@@ -33,20 +33,6 @@
 #pragma once
 
 // Must include gtest first to guard against Xlib colliding due to redefinitions of "None" and "Bool"
-
-#if defined(_MSC_VER)
-#pragma warning(push)
-/*
-    MSVC warnings 4251 and 4275 have to do with potential dll-interface mismatch
-    between library (gtest) and users. Since we build the gtest library
-    as part of the test build we know that the dll-interface will match and
-    can disable these warnings.
- */
-#pragma warning(disable : 4251)
-#pragma warning(disable : 4275)
-#endif
-
-// GTest and Xlib collide due to redefinitions of "None" and "Bool"
 #if defined(VK_USE_PLATFORM_XLIB_KHR)
 #pragma push_macro("None")
 #pragma push_macro("Bool")
@@ -60,10 +46,18 @@
 #endif
 #endif
 
-// Use the NDK's header on Android
 #include "gtest/gtest.h"
 
-#include "test_util.h"
+#include "util/builder_defines.h"
+#include "util/dispatch_table.h"
+#include "util/dynamic_library_wrapper.h"
+#include "util/env_var_wrapper.h"
+#include "util/equality_helpers.h"
+#include "util/folder_manager.h"
+#include "util/functions.h"
+#include "util/manifest_builders.h"
+#include "util/test_defines.h"
+#include "util/vulkan_object_wrappers.h"
 
 #include "shim/shim.h"
 
@@ -71,14 +65,7 @@
 
 #include "layer/test_layer.h"
 
-#include FRAMEWORK_CONFIG_HEADER
-
-// Useful defines
-#if COMMON_UNIX_PLATFORMS
-#define HOME_DIR "/home/fake_home"
-#define USER_LOCAL_SHARE_DIR HOME_DIR "/.local/share"
-#define ETC_DIR "/etc"
-#endif
+#include "generated/vk_result_to_string_helper.h"
 
 // handle checking
 template <typename T>
@@ -125,152 +112,26 @@
     }
 }
 
-// VulkanFunctions - loads vulkan functions for tests to use
-
-struct VulkanFunctions {
-#if !defined(APPLE_STATIC_LOADER)
-    LibraryWrapper loader;
-#endif
-    // Pre-Instance
-    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = nullptr;
-    PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties = nullptr;
-    PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties = nullptr;
-    PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion = nullptr;
-    PFN_vkCreateInstance vkCreateInstance = nullptr;
-
-    // Instance
-    PFN_vkDestroyInstance vkDestroyInstance = nullptr;
-    PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices = nullptr;
-    PFN_vkEnumeratePhysicalDeviceGroups vkEnumeratePhysicalDeviceGroups = nullptr;
-    PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures = nullptr;
-    PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2 = nullptr;
-    PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties = nullptr;
-    PFN_vkGetPhysicalDeviceFormatProperties2 vkGetPhysicalDeviceFormatProperties2 = nullptr;
-    PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties = nullptr;
-    PFN_vkGetPhysicalDeviceImageFormatProperties2 vkGetPhysicalDeviceImageFormatProperties2 = nullptr;
-    PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties = nullptr;
-    PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 vkGetPhysicalDeviceSparseImageFormatProperties2 = nullptr;
-    PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties = nullptr;
-    PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2 = nullptr;
-    PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties = nullptr;
-    PFN_vkGetPhysicalDeviceQueueFamilyProperties2 vkGetPhysicalDeviceQueueFamilyProperties2 = nullptr;
-    PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties = nullptr;
-    PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2 = nullptr;
-    PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR = nullptr;
-    PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR = nullptr;
-    PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR = nullptr;
-    PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr;
-    PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties = nullptr;
-    PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties = nullptr;
-    PFN_vkGetPhysicalDeviceExternalBufferProperties vkGetPhysicalDeviceExternalBufferProperties = nullptr;
-    PFN_vkGetPhysicalDeviceExternalFenceProperties vkGetPhysicalDeviceExternalFenceProperties = nullptr;
-    PFN_vkGetPhysicalDeviceExternalSemaphoreProperties vkGetPhysicalDeviceExternalSemaphoreProperties = nullptr;
-
-    PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr = nullptr;
-    PFN_vkCreateDevice vkCreateDevice = nullptr;
-
-    // WSI
-    PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT = nullptr;
-    PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR = nullptr;
-    PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR = nullptr;
-    PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR = nullptr;
-    PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR = nullptr;
-    PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR = nullptr;
-    PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR = nullptr;
-    PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR = nullptr;
-    PFN_vkGetPhysicalDevicePresentRectanglesKHR vkGetPhysicalDevicePresentRectanglesKHR = nullptr;
-    PFN_vkGetPhysicalDeviceDisplayProperties2KHR vkGetPhysicalDeviceDisplayProperties2KHR = nullptr;
-    PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR vkGetPhysicalDeviceDisplayPlaneProperties2KHR = nullptr;
-    PFN_vkGetDisplayModeProperties2KHR vkGetDisplayModeProperties2KHR = nullptr;
-    PFN_vkGetDisplayPlaneCapabilities2KHR vkGetDisplayPlaneCapabilities2KHR = nullptr;
-    PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR = nullptr;
-    PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR = nullptr;
-
-#if defined(VK_USE_PLATFORM_ANDROID_KHR)
-    PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR = nullptr;
-#endif  // VK_USE_PLATFORM_ANDROID_KHR
-#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
-    PFN_vkCreateDirectFBSurfaceEXT vkCreateDirectFBSurfaceEXT = nullptr;
-    PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT vkGetPhysicalDeviceDirectFBPresentationSupportEXT = nullptr;
-#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
-#if defined(VK_USE_PLATFORM_FUCHSIA)
-    PFN_vkCreateImagePipeSurfaceFUCHSIA vkCreateImagePipeSurfaceFUCHSIA = nullptr;
-#endif  // VK_USE_PLATFORM_FUCHSIA
-#if defined(VK_USE_PLATFORM_GGP)
-    PFN_vkCreateStreamDescriptorSurfaceGGP vkCreateStreamDescriptorSurfaceGGP = nullptr;
-#endif  // VK_USE_PLATFORM_GGP
-#if defined(VK_USE_PLATFORM_IOS_MVK)
-    PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK = nullptr;
-#endif  // VK_USE_PLATFORM_IOS_MVK
-#if defined(VK_USE_PLATFORM_MACOS_MVK)
-    PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK = nullptr;
-#endif  // VK_USE_PLATFORM_MACOS_MVK
-#if defined(VK_USE_PLATFORM_METAL_EXT)
-    PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT = nullptr;
-#endif  // VK_USE_PLATFORM_METAL_EXT
-#if defined(VK_USE_PLATFORM_SCREEN_QNX)
-    PFN_vkCreateScreenSurfaceQNX vkCreateScreenSurfaceQNX = nullptr;
-    PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX vkGetPhysicalDeviceScreenPresentationSupportQNX = nullptr;
-#endif  // VK_USE_PLATFORM_SCREEN_QNX
-#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
-    PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR = nullptr;
-    PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR = nullptr;
-#endif  // VK_USE_PLATFORM_WAYLAND_KHR
-#if defined(VK_USE_PLATFORM_XCB_KHR)
-    PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR = nullptr;
-    PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR = nullptr;
-#endif  // VK_USE_PLATFORM_XCB_KHR
-#if defined(VK_USE_PLATFORM_XLIB_KHR)
-    PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR = nullptr;
-    PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR = nullptr;
-#endif  // VK_USE_PLATFORM_XLIB_KHR
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR = nullptr;
-    PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR = nullptr;
-#endif  // VK_USE_PLATFORM_WIN32_KHR
-    PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR = nullptr;
-
-    // instance extensions functions (can only be loaded with a valid instance)
-    PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = nullptr;    // Null unless the extension is enabled
-    PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT = nullptr;  // Null unless the extension is enabled
-    PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = nullptr;    // Null unless the extension is enabled
-    PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT = nullptr;  // Null unless the extension is enabled
-
-    // device functions
-    PFN_vkDestroyDevice vkDestroyDevice = nullptr;
-    PFN_vkGetDeviceQueue vkGetDeviceQueue = nullptr;
-
-    VulkanFunctions();
-
-    void load_instance_functions(VkInstance instance);
-
-    FromVoidStarFunc load(VkInstance inst, const char* func_name) const {
-        return FromVoidStarFunc(vkGetInstanceProcAddr(inst, func_name));
+template <typename T, size_t U>
+bool check_permutation(std::initializer_list<const char*> expected, std::array<T, U> const& returned) {
+    if (expected.size() != returned.size()) return false;
+    for (uint32_t i = 0; i < expected.size(); i++) {
+        auto found = std::find_if(std::begin(returned), std::end(returned),
+                                  [&](T elem) { return string_eq(*(expected.begin() + i), elem.layerName); });
+        if (found == std::end(returned)) return false;
     }
-
-    FromVoidStarFunc load(VkDevice device, const char* func_name) const {
-        return FromVoidStarFunc(vkGetDeviceProcAddr(device, func_name));
+    return true;
+}
+template <typename T>
+bool check_permutation(std::initializer_list<const char*> expected, std::vector<T> const& returned) {
+    if (expected.size() != returned.size()) return false;
+    for (uint32_t i = 0; i < expected.size(); i++) {
+        auto found = std::find_if(std::begin(returned), std::end(returned),
+                                  [&](T elem) { return string_eq(*(expected.begin() + i), elem.layerName); });
+        if (found == std::end(returned)) return false;
     }
-};
-
-struct DeviceFunctions {
-    PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr = nullptr;
-    PFN_vkDestroyDevice vkDestroyDevice = nullptr;
-    PFN_vkGetDeviceQueue vkGetDeviceQueue = nullptr;
-    PFN_vkCreateCommandPool vkCreateCommandPool = nullptr;
-    PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers = nullptr;
-    PFN_vkDestroyCommandPool vkDestroyCommandPool = nullptr;
-    PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR = nullptr;
-    PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR = nullptr;
-    PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR = nullptr;
-
-    DeviceFunctions() = default;
-    DeviceFunctions(const VulkanFunctions& vulkan_functions, VkDevice device);
-
-    FromVoidStarFunc load(VkDevice device, const char* func_name) const {
-        return FromVoidStarFunc(vkGetDeviceProcAddr(device, func_name));
-    }
-};
+    return true;
+}
 
 // InstWrapper & DeviceWrapper - used to make creating instances & devices easier when writing tests
 struct InstWrapper {
@@ -316,6 +177,7 @@
     VkInstance inst = VK_NULL_HANDLE;
     VkAllocationCallbacks* callbacks = nullptr;
     InstanceCreateInfo create_info{};
+    InstanceFunctions instance_functions{};
 };
 
 struct DeviceWrapper {
@@ -478,11 +340,12 @@
 void FillDebugUtilsCreateDetails(InstanceCreateInfo& create_info, DebugUtilsWrapper& wrapper);
 
 struct LoaderSettingsLayerConfiguration {
-    BUILDER_VALUE(LoaderSettingsLayerConfiguration, std::string, name, {})
-    BUILDER_VALUE(LoaderSettingsLayerConfiguration, std::filesystem::path, path, {})
-    BUILDER_VALUE(LoaderSettingsLayerConfiguration, std::string, control, {})
-    BUILDER_VALUE(LoaderSettingsLayerConfiguration, bool, treat_as_implicit_manifest, false)
+    BUILDER_VALUE(std::string, name)
+    BUILDER_VALUE(std::filesystem::path, path)
+    BUILDER_VALUE(std::string, control)
+    BUILDER_VALUE(bool, treat_as_implicit_manifest)
 };
+// Needed for next_permutation
 inline bool operator==(LoaderSettingsLayerConfiguration const& a, LoaderSettingsLayerConfiguration const& b) {
     return a.name == b.name && a.path == b.path && a.control == b.control &&
            a.treat_as_implicit_manifest == b.treat_as_implicit_manifest;
@@ -495,28 +358,42 @@
 inline bool operator<=(LoaderSettingsLayerConfiguration const& a, LoaderSettingsLayerConfiguration const& b) { return !(b < a); }
 inline bool operator>=(LoaderSettingsLayerConfiguration const& a, LoaderSettingsLayerConfiguration const& b) { return !(a < b); }
 
+struct LoaderSettingsDriverConfiguration {
+    BUILDER_VALUE(std::filesystem::path, path)
+};
+
+using VulkanUUID = std::array<uint8_t, VK_UUID_SIZE>;
+
+struct LoaderSettingsDeviceConfiguration {
+    BUILDER_VALUE(VulkanUUID, deviceUUID)
+    BUILDER_VALUE(VulkanUUID, driverUUID)
+    BUILDER_VALUE(uint32_t, driverVersion)
+    BUILDER_VALUE(std::string, deviceName)
+    BUILDER_VALUE(std::string, driverName)
+};
+
 // Log files and their associated filter
 struct LoaderLogConfiguration {
-    BUILDER_VECTOR(LoaderLogConfiguration, std::string, destinations, destination)
-    BUILDER_VECTOR(LoaderLogConfiguration, std::string, filters, filter)
+    BUILDER_VECTOR(std::string, destinations, destination)
+    BUILDER_VECTOR(std::string, filters, filter)
 };
 struct AppSpecificSettings {
-    BUILDER_VECTOR(AppSpecificSettings, std::string, app_keys, app_key)
-    BUILDER_VECTOR(AppSpecificSettings, LoaderSettingsLayerConfiguration, layer_configurations, layer_configuration)
-    BUILDER_VECTOR(AppSpecificSettings, std::string, stderr_log, stderr_log_filter)
-    BUILDER_VECTOR(AppSpecificSettings, LoaderLogConfiguration, log_configurations, log_configuration)
+    BUILDER_VECTOR(std::string, app_keys, app_key)
+    BUILDER_VECTOR(LoaderSettingsLayerConfiguration, layer_configurations, layer_configuration)
+    BUILDER_VECTOR(LoaderSettingsDriverConfiguration, driver_configurations, driver_configuration)
+    BUILDER_VECTOR(LoaderSettingsDeviceConfiguration, device_configurations, device_configuration)
+    BUILDER_VALUE(bool, additional_drivers_use_exclusively)
+    BUILDER_VECTOR(std::string, stderr_log, stderr_log_filter)
+    BUILDER_VECTOR(LoaderLogConfiguration, log_configurations, log_configuration)
 };
 
 struct LoaderSettings {
-    BUILDER_VALUE(LoaderSettings, ManifestVersion, file_format_version, {})
-    BUILDER_VECTOR(LoaderSettings, AppSpecificSettings, app_specific_settings, app_specific_setting);
+    BUILDER_VALUE(ManifestVersion, file_format_version)
+    BUILDER_VECTOR(AppSpecificSettings, app_specific_settings, app_specific_setting);
 };
 
-struct FrameworkEnvironment;  // forward declaration
-
 struct PlatformShimWrapper {
-    PlatformShimWrapper(std::vector<fs::FolderManager>* folders, const char* log_filter) noexcept;
-    ~PlatformShimWrapper() noexcept;
+    PlatformShimWrapper(fs::FileSystemManager& file_system_manager, const char* log_filter) noexcept;
     PlatformShimWrapper(PlatformShimWrapper const&) = delete;
     PlatformShimWrapper& operator=(PlatformShimWrapper const&) = delete;
 
@@ -528,114 +405,58 @@
     EnvVarWrapper loader_logging;
 };
 
-struct TestICDHandle {
-    TestICDHandle() noexcept;
-    TestICDHandle(std::filesystem::path const& icd_path) noexcept;
-    TestICD& reset_icd() noexcept;
-    TestICD& get_test_icd() noexcept;
-    std::filesystem::path get_icd_full_path() noexcept;
-    std::filesystem::path get_icd_manifest_path() noexcept;
-    std::filesystem::path get_shimmed_manifest_path() noexcept;
+template <typename BinaryObject, typename GetTestBinaryFunc, typename GetNewTestBinaryFunc>
+struct TestBinaryHandle {
+    TestBinaryHandle() noexcept {}
+    TestBinaryHandle(std::filesystem::path const& binary_path) noexcept;
 
-    // Must use statically
-    LibraryWrapper icd_library;
-    GetTestICDFunc proc_addr_get_test_icd = nullptr;
-    GetNewTestICDFunc proc_addr_reset_icd = nullptr;
-    std::filesystem::path
-        manifest_path;  // path to the manifest file is on the actual filesystem (aka <build_folder>/tests/framework/<...>)
-    std::filesystem::path
-        shimmed_manifest_path;  // path to where the loader will find the manifest file (eg /usr/local/share/vulkan/<...>)
-};
-struct TestLayerHandle {
-    TestLayerHandle() noexcept;
-    TestLayerHandle(std::filesystem::path const& layer_path) noexcept;
-    TestLayer& reset_layer() noexcept;
-    TestLayer& get_test_layer() noexcept;
-    std::filesystem::path get_layer_full_path() noexcept;
-    std::filesystem::path get_layer_manifest_path() noexcept;
-    std::filesystem::path get_shimmed_manifest_path() noexcept;
-
-    // Must use statically
-    LibraryWrapper layer_library;
-    GetTestLayerFunc proc_addr_get_test_layer = nullptr;
-    GetNewTestLayerFunc proc_addr_reset_layer = nullptr;
-    std::filesystem::path
-        manifest_path;  // path to the manifest file is on the actual filesystem (aka <build_folder>/tests/framework/<...>)
-    std::filesystem::path
-        shimmed_manifest_path;  // path to where the loader will find the manifest file (eg /usr/local/share/vulkan/<...>)
-};
-
-// Controls whether to create a manifest and where to put it
-enum class ManifestDiscoveryType {
-    generic,              // put the manifest in the regular locations
-    unsecured_generic,    // put the manifest in a user folder rather than system
-    none,                 // Do not write the manifest anywhere (for Direct Driver Loading)
-    null_dir,             // put the manifest in the 'null_dir' which the loader does not search in (D3DKMT for instance)
-    env_var,              // use the corresponding env-var for it
-    add_env_var,          // use the corresponding add-env-var for it
-    override_folder,      // add to a special folder for the override layer to use
-    windows_app_package,  // let the app package search find it
-    macos_bundle,         // place it in a location only accessible to macos bundles
-};
-
-enum class LibraryPathType {
-    absolute,              // default for testing - the exact path of the binary
-    relative,              // Relative to the manifest file
-    default_search_paths,  // Dont add any path information to the library_path - force the use of the default search paths
-};
-
-struct TestICDDetails {
-    TestICDDetails(ManifestICD icd_manifest) noexcept : icd_manifest(icd_manifest) {}
-    TestICDDetails(std::filesystem::path icd_binary_path, uint32_t api_version = VK_API_VERSION_1_0) noexcept {
-        icd_manifest.set_lib_path(icd_binary_path).set_api_version(api_version);
+    BinaryObject& get_test_binary() noexcept {
+        assert(proc_addr_get_test_binary != NULL && "symbol must be loaded before use");
+        return *proc_addr_get_test_binary();
     }
-    BUILDER_VALUE(TestICDDetails, ManifestICD, icd_manifest, {});
-    BUILDER_VALUE(TestICDDetails, std::filesystem::path, json_name, "test_icd");
-    // Uses the json_name without modification - default is to append _1 in the json file to distinguish drivers
-    BUILDER_VALUE(TestICDDetails, bool, disable_icd_inc, false);
-    BUILDER_VALUE(TestICDDetails, ManifestDiscoveryType, discovery_type, ManifestDiscoveryType::generic);
-    BUILDER_VALUE(TestICDDetails, bool, is_fake, false);
-    // If discovery type is env-var, is_dir controls whether to use the path to the file or folder the manifest is in
-    BUILDER_VALUE(TestICDDetails, bool, is_dir, false);
-    BUILDER_VALUE(TestICDDetails, LibraryPathType, library_path_type, LibraryPathType::absolute);
+    BinaryObject& reset() noexcept {
+        assert(proc_addr_reset_binary != NULL && "symbol must be loaded before use");
+        return *proc_addr_reset_binary();
+    }
+    std::filesystem::path get_full_path() noexcept { return library.get_path(); }
+    std::filesystem::path get_manifest_path() noexcept { return manifest_path; }
+    std::filesystem::path get_shimmed_manifest_path() noexcept { return shimmed_manifest_path; }
+
+    // Must use statically
+    LibraryWrapper library;
+    GetTestBinaryFunc proc_addr_get_test_binary = nullptr;
+    GetNewTestBinaryFunc proc_addr_reset_binary = nullptr;
+    std::filesystem::path
+        manifest_path;  // path to the manifest file is on the actual filesystem (aka <build_folder>/tests/framework/<...>)
+    std::filesystem::path
+        shimmed_manifest_path;  // path to where the loader will find the manifest file (eg /usr/local/share/vulkan/<...>)
 };
 
-struct TestLayerDetails {
-    TestLayerDetails(ManifestLayer layer_manifest, const std::string& json_name) noexcept
-        : layer_manifest(layer_manifest), json_name(json_name) {}
-    BUILDER_VALUE(TestLayerDetails, ManifestLayer, layer_manifest, {});
-    BUILDER_VALUE(TestLayerDetails, std::string, json_name, "test_layer");
-    BUILDER_VALUE(TestLayerDetails, ManifestDiscoveryType, discovery_type, ManifestDiscoveryType::generic);
-    BUILDER_VALUE(TestLayerDetails, bool, is_fake, false);
-    // If discovery type is env-var, is_dir controls whether to use the path to the file or folder the manifest is in
-    BUILDER_VALUE(TestLayerDetails, bool, is_dir, true);
-    BUILDER_VALUE(TestLayerDetails, LibraryPathType, library_path_type, LibraryPathType::absolute);
-};
+using TestICDHandle = TestBinaryHandle<TestICD, GetTestICDFunc, GetNewTestICDFunc>;
+using TestLayerHandle = TestBinaryHandle<TestLayer, GetTestLayerFunc, GetNewTestLayerFunc>;
 
-// Locations manifests can go in the test framework
-// If this enum is added to - the contructor of FrameworkEnvironment also needs to be updated with the new enum value
-enum class ManifestLocation {
-    null = 0,
-    driver = 1,
-    driver_env_var = 2,
-    explicit_layer = 3,
-    explicit_layer_env_var = 4,
-    explicit_layer_add_env_var = 5,
-    implicit_layer = 6,
-    implicit_layer_env_var = 7,
-    implicit_layer_add_env_var = 8,
-    override_layer = 9,
-    windows_app_package = 10,
-    macos_bundle = 11,
-    unsecured_location = 12,
-    settings_location = 13,
+struct ManifestOptions {
+    BUILDER_VALUE(std::filesystem::path, json_name);
+    BUILDER_VALUE_WITH_DEFAULT(ManifestDiscoveryType, discovery_type, ManifestDiscoveryType::generic);
+    BUILDER_VALUE(bool, is_fake);
+    // If discovery type is env-var, is_dir controls whether to use the path to the file or folder the manifest is in
+    BUILDER_VALUE(bool, is_dir);
+    BUILDER_VALUE_WITH_DEFAULT(LibraryPathType, library_path_type, LibraryPathType::absolute);
 };
 
 struct FrameworkSettings {
-    BUILDER_VALUE(FrameworkSettings, const char*, log_filter, "all");
-    BUILDER_VALUE(FrameworkSettings, bool, enable_default_search_paths, true);
-    BUILDER_VALUE(FrameworkSettings, LoaderSettings, loader_settings, {});
-    BUILDER_VALUE(FrameworkSettings, bool, secure_loader_settings, false);
+    BUILDER_VALUE_WITH_DEFAULT(const char*, log_filter, "all");
+    BUILDER_VALUE_WITH_DEFAULT(bool, run_as_if_with_elevated_privleges, false);
+
+#if TESTING_COMMON_UNIX_PLATFORMS
+    BUILDER_VALUE_WITH_DEFAULT(std::string, home_env_var, "/home/fake_home");
+#if !defined(__APPLE__)
+    BUILDER_VALUE(std::string, xdg_config_home_env_var);
+    BUILDER_VALUE(std::string, xdg_config_dirs_env_var);
+    BUILDER_VALUE(std::string, xdg_data_home_env_var);
+    BUILDER_VALUE(std::string, xdg_data_dirs_env_var);
+#endif
+#endif
 };
 
 struct FrameworkEnvironment {
@@ -646,20 +467,26 @@
     FrameworkEnvironment(const FrameworkEnvironment&) = delete;
     FrameworkEnvironment& operator=(const FrameworkEnvironment&) = delete;
 
-    TestICD& add_icd(TestICDDetails icd_details) noexcept;
-    void add_implicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept;
-    void add_implicit_layer(TestLayerDetails layer_details) noexcept;
-    void add_explicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept;
-    void add_explicit_layer(TestLayerDetails layer_details) noexcept;
-    void add_fake_implicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept;
-    void add_fake_explicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept;
+    TestICD& add_icd(std::filesystem::path const& path, ManifestOptions args = ManifestOptions{},
+                     ManifestICD manifest = ManifestICD{}) noexcept;
 
-    // resets the current settings with the values contained in loader_settings
-    void write_settings_file(std::string const& file_contents);
-    // apply any changes made to FrameworkEnvironment's loader_settings member
-    void update_loader_settings(const LoaderSettings& loader_settings) noexcept;
+    void add_implicit_layer(ManifestOptions args, ManifestLayer layer_manifest) noexcept;
+    void add_explicit_layer(ManifestOptions args, ManifestLayer layer_manifest) noexcept;
+
+    // Resets the current settings with the values contained in loader_settings.
+    // Write_to_secure_location determines whether to write to the secure or unsecure settings folder.
+    void write_settings_file(std::string const& file_contents, bool write_to_secure_location);
+
+    // Apply any changes made to FrameworkEnvironment's loader_settings member.
+    // By default writes to the secure settings location
+    void update_loader_settings(const LoaderSettings& loader_settings, bool write_to_secure_location = true) noexcept;
+
     void remove_loader_settings();
 
+    // Creates a file called `file_name` for the given `category` in the given `location` with `source_string` as the contents
+    void write_file_from_string(std::string const& source_string, ManifestCategory category, ManifestLocation location,
+                                std::string const& file_name);
+    // Creates a file called `file_name` for the given `category` in the given `location` with contents copied from `source_file`
     void write_file_from_source(const char* source_file, ManifestCategory category, ManifestLocation location,
                                 std::string const& file_name);
 
@@ -675,15 +502,19 @@
     std::filesystem::path get_layer_manifest_path(size_t index = 0) noexcept;
     std::filesystem::path get_shimmed_layer_manifest_path(size_t index = 0) noexcept;
 
-    fs::FolderManager& get_folder(ManifestLocation location) noexcept;
-    fs::FolderManager const& get_folder(ManifestLocation location) const noexcept;
+    fs::Folder& get_folder(ManifestLocation location) noexcept;
+    fs::Folder const& get_folder(ManifestLocation location) const noexcept;
 #if defined(__APPLE__)
     // Set the path of the app bundle to the appropriate test framework bundle
     void setup_macos_bundle() noexcept;
 #endif
 
+    void add_symlink(ManifestLocation location, std::filesystem::path const& target, std::filesystem::path const& link_name);
+
     FrameworkSettings settings;
 
+    fs::FileSystemManager file_system_manager;
+
     // Query the global extensions
     // Optional: use layer_name to query the extensions of a specific layer
     std::vector<VkExtensionProperties> GetInstanceExtensions(uint32_t count, const char* layer_name = nullptr);
@@ -691,24 +522,41 @@
     std::vector<VkLayerProperties> GetLayerProperties(uint32_t count);
 
     PlatformShimWrapper platform_shim;
-    std::vector<fs::FolderManager> folders;
-
-    DebugUtilsLogger debug_log;
-    VulkanFunctions vulkan_functions;
 
     std::vector<TestICDHandle> icds;
     std::vector<TestLayerHandle> layers;
 
+    DebugUtilsLogger debug_log;
+    VulkanFunctions vulkan_functions;
+
     EnvVarWrapper env_var_vk_icd_filenames{"VK_DRIVER_FILES"};
     EnvVarWrapper add_env_var_vk_icd_filenames{"VK_ADD_DRIVER_FILES"};
     EnvVarWrapper env_var_vk_layer_paths{"VK_LAYER_PATH"};
     EnvVarWrapper add_env_var_vk_layer_paths{"VK_ADD_LAYER_PATH"};
     EnvVarWrapper env_var_vk_implicit_layer_paths{"VK_IMPLICIT_LAYER_PATH"};
     EnvVarWrapper add_env_var_vk_implicit_layer_paths{"VK_ADD_IMPLICIT_LAYER_PATH"};
+    EnvVarWrapper env_var_vk_loader_device_id_filter{"VK_LOADER_DEVICE_ID_FILTER"};
+    EnvVarWrapper env_var_vk_loader_vendor_id_filter{"VK_LOADER_VENDOR_ID_FILTER"};
+    EnvVarWrapper env_var_vk_loader_driver_id_filter{"VK_LOADER_DRIVER_ID_FILTER"};
+
+#if TESTING_COMMON_UNIX_PLATFORMS
+    EnvVarWrapper env_var_home{"HOME", "/home/fake_home"};
+#if !defined(__APPLE__)
+    EnvVarWrapper env_var_xdg_config_home{"XDG_CONFIG_HOME"};
+    EnvVarWrapper env_var_xdg_config_dirs{"XDG_CONFIG_DIRS"};
+    EnvVarWrapper env_var_xdg_data_home{"XDG_DATA_HOME"};
+    EnvVarWrapper env_var_xdg_data_dirs{"XDG_DATA_DIRS"};
+#endif
+    std::string secure_manifest_base_location;
+    std::string unsecure_manifest_base_location;
+#endif
 
     LoaderSettings loader_settings;  // the current settings written to disk
    private:
-    void add_layer_impl(TestLayerDetails layer_details, ManifestCategory category);
+    uint32_t created_layer_count = 0;
+    void add_layer_impl(ManifestOptions args, ManifestLayer manifest, ManifestCategory category);
+
+    static ManifestLocation map_discovery_type_to_location(ManifestDiscoveryType type, ManifestCategory category);
 };
 
 // Create a surface using a platform specific API
diff --git a/tests/framework/test_util.cpp b/tests/framework/test_util.cpp
deleted file mode 100644
index 2a433c7..0000000
--- a/tests/framework/test_util.cpp
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Copyright (c) 2021-2023 The Khronos Group Inc.
- * Copyright (c) 2021-2023 Valve Corporation
- * Copyright (c) 2021-2023 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and/or associated documentation files (the "Materials"), to
- * deal in the Materials without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Materials, and to permit persons to whom the Materials are
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice(s) and this permission notice shall be included in
- * all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- *
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
- * USE OR OTHER DEALINGS IN THE MATERIALS.
- *
- * Author: Charles Giessen <charles@lunarg.com>
- */
-
-#include "test_util.h"
-
-#include <fstream>
-
-#if defined(WIN32)
-#include <wchar.h>
-#include <strsafe.h>
-const char* win_api_error_str(LSTATUS status) {
-    if (status == ERROR_INVALID_FUNCTION) return "ERROR_INVALID_FUNCTION";
-    if (status == ERROR_FILE_NOT_FOUND) return "ERROR_FILE_NOT_FOUND";
-    if (status == ERROR_PATH_NOT_FOUND) return "ERROR_PATH_NOT_FOUND";
-    if (status == ERROR_TOO_MANY_OPEN_FILES) return "ERROR_TOO_MANY_OPEN_FILES";
-    if (status == ERROR_ACCESS_DENIED) return "ERROR_ACCESS_DENIED";
-    if (status == ERROR_INVALID_HANDLE) return "ERROR_INVALID_HANDLE";
-    if (status == ERROR_ENVVAR_NOT_FOUND) return "ERROR_ENVVAR_NOT_FOUND";
-    if (status == ERROR_SETENV_FAILED) return "ERROR_SETENV_FAILED";
-    return "UNKNOWN ERROR";
-}
-
-void print_error_message(LSTATUS status, const char* function_name, std::string optional_message) {
-    LPVOID lpMsgBuf;
-    DWORD dw = GetLastError();
-
-    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, dw,
-                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPTSTR>(&lpMsgBuf), 0, nullptr);
-
-    std::cerr << function_name << " failed with " << win_api_error_str(status) << ": "
-              << std::string(reinterpret_cast<LPTSTR>(lpMsgBuf));
-    if (optional_message != "") {
-        std::cerr << " | " << optional_message;
-    }
-    std::cerr << "\n";
-    LocalFree(lpMsgBuf);
-}
-
-void EnvVarWrapper::set_env_var() {
-    BOOL ret = SetEnvironmentVariableW(widen(name).c_str(), widen(cur_value).c_str());
-    if (ret == 0) {
-        print_error_message(ERROR_SETENV_FAILED, "SetEnvironmentVariableW");
-    }
-}
-void EnvVarWrapper::remove_env_var() const { SetEnvironmentVariableW(widen(name).c_str(), nullptr); }
-std::string get_env_var(std::string const& name, bool report_failure) {
-    std::wstring name_utf16 = widen(name);
-    DWORD value_size = GetEnvironmentVariableW(name_utf16.c_str(), nullptr, 0);
-    if (0 == value_size) {
-        if (report_failure) print_error_message(ERROR_ENVVAR_NOT_FOUND, "GetEnvironmentVariableW");
-        return {};
-    }
-    std::wstring value(value_size, L'\0');
-    if (GetEnvironmentVariableW(name_utf16.c_str(), &value[0], value_size) != value_size - 1) {
-        return {};
-    }
-    return narrow(value);
-}
-#elif COMMON_UNIX_PLATFORMS
-
-void EnvVarWrapper::set_env_var() { setenv(name.c_str(), cur_value.c_str(), 1); }
-void EnvVarWrapper::remove_env_var() const { unsetenv(name.c_str()); }
-std::string get_env_var(std::string const& name, bool report_failure) {
-    char* ret = getenv(name.c_str());
-    if (ret == nullptr) {
-        if (report_failure) std::cerr << "Failed to get environment variable:" << name << "\n";
-        return std::string();
-    }
-    return ret;
-}
-#endif
-
-template <typename T>
-void print_object_of_t(JsonWriter& writer, const char* object_name, std::vector<T> const& vec) {
-    if (vec.size() == 0) return;
-    writer.StartKeyedObject(object_name);
-    for (auto& element : vec) {
-        element.get_manifest_str(writer);
-    }
-    writer.EndObject();
-}
-
-template <typename T>
-void print_array_of_t(JsonWriter& writer, const char* object_name, std::vector<T> const& vec) {
-    if (vec.size() == 0) return;
-    writer.StartKeyedArray(object_name);
-    for (auto& element : vec) {
-        element.get_manifest_str(writer);
-    }
-    writer.EndArray();
-}
-void print_vector_of_strings(JsonWriter& writer, const char* object_name, std::vector<std::string> const& strings) {
-    if (strings.size() == 0) return;
-    writer.StartKeyedArray(object_name);
-    for (auto const& str : strings) {
-        writer.AddString(std::filesystem::path(str).native());
-    }
-    writer.EndArray();
-}
-void print_vector_of_strings(JsonWriter& writer, const char* object_name, std::vector<std::filesystem::path> const& paths) {
-    if (paths.size() == 0) return;
-    writer.StartKeyedArray(object_name);
-    for (auto const& path : paths) {
-        writer.AddString(path.native());
-    }
-    writer.EndArray();
-}
-
-std::string to_text(bool b) { return b ? std::string("true") : std::string("false"); }
-
-std::string ManifestICD::get_manifest_str() const {
-    JsonWriter writer;
-    writer.StartObject();
-    writer.AddKeyedString("file_format_version", file_format_version.get_version_str());
-    writer.StartKeyedObject("ICD");
-    writer.AddKeyedString("library_path", lib_path.native());
-    writer.AddKeyedString("api_version", version_to_string(api_version));
-    writer.AddKeyedBool("is_portability_driver", is_portability_driver);
-    if (!library_arch.empty()) writer.AddKeyedString("library_arch", library_arch);
-    writer.EndObject();
-    writer.EndObject();
-    return writer.output;
-}
-
-void ManifestLayer::LayerDescription::Extension::get_manifest_str(JsonWriter& writer) const {
-    writer.StartObject();
-    writer.AddKeyedString("name", name);
-    writer.AddKeyedString("spec_version", std::to_string(spec_version));
-    writer.AddKeyedString("spec_version", std::to_string(spec_version));
-    print_vector_of_strings(writer, "entrypoints", entrypoints);
-    writer.EndObject();
-}
-
-void ManifestLayer::LayerDescription::get_manifest_str(JsonWriter& writer) const {
-    writer.AddKeyedString("name", name);
-    writer.AddKeyedString("type", get_type_str(type));
-    if (!lib_path.empty()) {
-        writer.AddKeyedString("library_path", lib_path.native());
-    }
-    writer.AddKeyedString("api_version", version_to_string(api_version));
-    writer.AddKeyedString("implementation_version", std::to_string(implementation_version));
-    writer.AddKeyedString("description", description);
-    print_object_of_t(writer, "functions", functions);
-    print_array_of_t(writer, "instance_extensions", instance_extensions);
-    print_array_of_t(writer, "device_extensions", device_extensions);
-    if (!enable_environment.empty()) {
-        writer.StartKeyedObject("enable_environment");
-        writer.AddKeyedString(enable_environment, "1");
-        writer.EndObject();
-    }
-    if (!disable_environment.empty()) {
-        writer.StartKeyedObject("disable_environment");
-        writer.AddKeyedString(disable_environment, "1");
-        writer.EndObject();
-    }
-    print_vector_of_strings(writer, "component_layers", component_layers);
-    print_vector_of_strings(writer, "blacklisted_layers", blacklisted_layers);
-    print_vector_of_strings(writer, "override_paths", override_paths);
-    print_vector_of_strings(writer, "app_keys", app_keys);
-    print_object_of_t(writer, "pre_instance_functions", pre_instance_functions);
-    if (!library_arch.empty()) {
-        writer.AddKeyedString("library_arch", library_arch);
-    }
-}
-
-VkLayerProperties ManifestLayer::LayerDescription::get_layer_properties() const {
-    VkLayerProperties properties{};
-    copy_string_to_char_array(name, properties.layerName, VK_MAX_EXTENSION_NAME_SIZE);
-    copy_string_to_char_array(description, properties.description, VK_MAX_EXTENSION_NAME_SIZE);
-    properties.implementationVersion = implementation_version;
-    properties.specVersion = api_version;
-    return properties;
-}
-
-std::string ManifestLayer::get_manifest_str() const {
-    JsonWriter writer;
-    writer.StartObject();
-    writer.AddKeyedString("file_format_version", file_format_version.get_version_str());
-    if (layers.size() == 1) {
-        writer.StartKeyedObject("layer");
-        layers.at(0).get_manifest_str(writer);
-        writer.EndObject();
-    } else {
-        writer.StartKeyedArray("layers");
-        for (size_t i = 0; i < layers.size(); i++) {
-            writer.StartObject();
-            layers.at(i).get_manifest_str(writer);
-            writer.EndObject();
-        }
-        writer.EndArray();
-    }
-    writer.EndObject();
-    return writer.output;
-}
-
-namespace fs {
-// internal implementation helper for per-platform creating & destroying folders
-int create_folder(std::filesystem::path const& path) {
-#if defined(WIN32)
-    return _wmkdir(path.c_str());
-#else
-    mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
-    return 0;
-#endif
-}
-
-int delete_folder_contents(std::filesystem::path const& folder) {
-#if defined(WIN32)
-    if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(folder.c_str()) && GetLastError() == ERROR_FILE_NOT_FOUND) {
-        // nothing to delete
-        return 0;
-    }
-    std::filesystem::path search_path = folder / "*.*";
-    WIN32_FIND_DATAW fd;
-    HANDLE hFind = ::FindFirstFileW(search_path.c_str(), &fd);
-    if (hFind != INVALID_HANDLE_VALUE) {
-        do {
-            std::filesystem::path file_name = fd.cFileName;
-            if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
-                if (file_name != "." && file_name != "..") {
-                    delete_folder(fd.cFileName);
-                }
-            } else {
-                DeleteFileW((folder / fd.cFileName).native().c_str());
-            }
-        } while (::FindNextFileW(hFind, &fd));
-        ::FindClose(hFind);
-    }
-    return 0;
-#else
-    DIR* dir = opendir(folder.c_str());
-    if (!dir) {
-        return 0;
-    }
-    int ret = 0;
-    dirent* file;
-    while (!ret && (file = readdir(dir))) {
-        int ret2 = -1;
-
-        /* Skip the names "." and ".." as we don't want to recurse on them. */
-        if (string_eq(file->d_name, ".") || string_eq(file->d_name, "..")) continue;
-
-        std::filesystem::path file_path = folder / file->d_name;
-        struct stat statbuf;
-        if (!stat(file_path.c_str(), &statbuf)) {
-            if (S_ISDIR(statbuf.st_mode))
-                ret2 = delete_folder(file_path);
-            else
-                ret2 = unlink(file_path.c_str());
-        }
-
-        ret = ret2;
-    }
-    closedir(dir);
-    return ret;
-#endif
-}
-
-int delete_folder(std::filesystem::path const& folder) {
-    int ret = delete_folder_contents(folder);
-    if (ret != 0) return ret;
-#if defined(WIN32)
-    _wrmdir(folder.native().c_str());
-    return 0;
-#else
-    return rmdir(folder.c_str());
-#endif
-}
-
-FolderManager::FolderManager(std::filesystem::path root_path, std::string name) noexcept : folder(root_path / name) {
-    delete_folder_contents(folder);
-    create_folder(folder);
-}
-FolderManager::~FolderManager() noexcept {
-    if (folder.empty()) return;
-    auto list_of_files_to_delete = files;
-    // remove(file) modifies the files variable, copy the list before deleting it
-    // Note: the allocation tests currently leak the loaded driver handles because in an OOM scenario the loader doesn't bother
-    // removing those. Since this is in an OOM situation, it is a low priority to fix. It does have the effect that Windows will
-    // be unable to delete the binaries that were leaked.
-    for (auto& file : list_of_files_to_delete) {
-        remove(file);
-    }
-    delete_folder(folder);
-}
-FolderManager::FolderManager(FolderManager&& other) noexcept : folder(other.folder), files(other.files) { other.folder.clear(); }
-FolderManager& FolderManager::operator=(FolderManager&& other) noexcept {
-    folder = other.folder;
-    files = other.files;
-    other.folder.clear();
-    return *this;
-}
-
-std::filesystem::path FolderManager::write_manifest(std::filesystem::path const& name, std::string const& contents) {
-    std::filesystem::path out_path = folder / name;
-    auto found = std::find(files.begin(), files.end(), name);
-    if (found != files.end()) {
-        std::cout << "Overwriting manifest " << name << ". Was this intended?\n";
-    } else {
-        files.emplace_back(name);
-    }
-    auto file = std::ofstream(out_path, std::ios_base::trunc | std::ios_base::out);
-    if (!file) {
-        std::cerr << "Failed to create manifest " << name << " at " << out_path << "\n";
-        return out_path;
-    }
-    file << contents << std::endl;
-    return out_path;
-}
-void FolderManager::add_existing_file(std::filesystem::path const& file_name) { files.emplace_back(file_name); }
-
-// close file handle, delete file, remove `name` from managed file list.
-void FolderManager::remove(std::filesystem::path const& name) {
-    std::filesystem::path out_path = folder / name;
-    auto found = std::find(files.begin(), files.end(), name);
-    if (found != files.end()) {
-#if defined(WIN32)
-        int rc = _wremove(out_path.c_str());
-#else
-        int rc = std::remove(out_path.c_str());
-#endif
-        if (rc != 0) {
-            std::cerr << "Failed to remove file " << name << " at " << out_path << "\n";
-        }
-
-        files.erase(found);
-
-    } else {
-        std::cout << "Couldn't remove file " << name << " at " << out_path << ".\n";
-    }
-}
-
-// copy file into this folder
-std::filesystem::path FolderManager::copy_file(std::filesystem::path const& file, std::filesystem::path const& new_name) {
-    auto new_filepath = folder / new_name;
-    auto found = std::find(files.begin(), files.end(), new_name);
-    if (found != files.end()) {
-        std::cout << "File location already contains" << new_name << ". Is this a bug?\n";
-    } else if (file == new_filepath) {
-        std::cout << "Trying to copy " << new_name << " into itself. Is this a bug?\n";
-    } else {
-        files.emplace_back(new_name);
-    }
-    std::ifstream src(file, std::ios::binary);
-    if (!src) {
-        std::cerr << "Failed to create file " << file << " for copying from\n";
-        return new_filepath;
-    }
-    std::ofstream dst(new_filepath, std::ios::binary);
-    if (!dst) {
-        std::cerr << "Failed to create file " << new_filepath << " for copying to\n";
-        return new_filepath;
-    }
-    dst << src.rdbuf();
-    return new_filepath;
-}
-}  // namespace fs
-
-const char* get_platform_wsi_extension([[maybe_unused]] const char* api_selection) {
-#if defined(VK_USE_PLATFORM_ANDROID_KHR)
-    return "VK_KHR_android_surface";
-#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
-    return "VK_EXT_directfb_surface";
-#elif defined(VK_USE_PLATFORM_FUCHSIA)
-    return "VK_FUCHSIA_imagepipe_surface";
-#elif defined(VK_USE_PLATFORM_GGP)
-    return "VK_GGP_stream_descriptor_surface";
-#elif defined(VK_USE_PLATFORM_IOS_MVK)
-    return "VK_MVK_ios_surface";
-#elif defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)
-#if defined(VK_USE_PLATFORM_MACOS_MVK)
-    if (string_eq(api_selection, "VK_USE_PLATFORM_MACOS_MVK")) return "VK_MVK_macos_surface";
-#endif
-#if defined(VK_USE_PLATFORM_METAL_EXT)
-    if (string_eq(api_selection, "VK_USE_PLATFORM_METAL_EXT")) return "VK_EXT_metal_surface";
-    return "VK_EXT_metal_surface";
-#endif
-#elif defined(VK_USE_PLATFORM_SCREEN_QNX)
-    return "VK_QNX_screen_surface";
-#elif defined(VK_USE_PLATFORM_VI_NN)
-    return "VK_NN_vi_surface";
-#elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
-#if defined(VK_USE_PLATFORM_XCB_KHR)
-    if (string_eq(api_selection, "VK_USE_PLATFORM_XCB_KHR")) return "VK_KHR_xcb_surface";
-#endif
-#if defined(VK_USE_PLATFORM_XLIB_KHR)
-    if (string_eq(api_selection, "VK_USE_PLATFORM_XLIB_KHR")) return "VK_KHR_xlib_surface";
-#endif
-#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
-    if (string_eq(api_selection, "VK_USE_PLATFORM_WAYLAND_KHR")) return "VK_KHR_wayland_surface";
-#endif
-#if defined(VK_USE_PLATFORM_XCB_KHR)
-    return "VK_KHR_xcb_surface";
-#endif
-#elif defined(VK_USE_PLATFORM_WIN32_KHR)
-    return "VK_KHR_win32_surface";
-#else
-    return "VK_KHR_display";
-#endif
-}
-
-bool string_eq(const char* a, const char* b) noexcept { return a && b && strcmp(a, b) == 0; }
-bool string_eq(const char* a, const char* b, size_t len) noexcept { return a && b && strncmp(a, b, len) == 0; }
-
-InstanceCreateInfo::InstanceCreateInfo() {
-    instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
-    application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
-}
-
-VkInstanceCreateInfo* InstanceCreateInfo::get() noexcept {
-    if (fill_in_application_info) {
-        application_info.pApplicationName = app_name.c_str();
-        application_info.pEngineName = engine_name.c_str();
-        application_info.applicationVersion = app_version;
-        application_info.engineVersion = engine_version;
-        application_info.apiVersion = api_version;
-        instance_info.pApplicationInfo = &application_info;
-    }
-    instance_info.flags = flags;
-    instance_info.enabledLayerCount = static_cast<uint32_t>(enabled_layers.size());
-    instance_info.ppEnabledLayerNames = enabled_layers.data();
-    instance_info.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size());
-    instance_info.ppEnabledExtensionNames = enabled_extensions.data();
-    return &instance_info;
-}
-InstanceCreateInfo& InstanceCreateInfo::set_api_version(uint32_t major, uint32_t minor, uint32_t patch) {
-    this->api_version = VK_MAKE_API_VERSION(0, major, minor, patch);
-    return *this;
-}
-InstanceCreateInfo& InstanceCreateInfo::setup_WSI(const char* api_selection) {
-    add_extensions({"VK_KHR_surface", get_platform_wsi_extension(api_selection)});
-    return *this;
-}
-
-DeviceQueueCreateInfo::DeviceQueueCreateInfo() { queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; }
-DeviceQueueCreateInfo::DeviceQueueCreateInfo(const VkDeviceQueueCreateInfo* create_info) {
-    queue_create_info = *create_info;
-    for (uint32_t i = 0; i < create_info->queueCount; i++) {
-        priorities.push_back(create_info->pQueuePriorities[i]);
-    }
-}
-
-VkDeviceQueueCreateInfo DeviceQueueCreateInfo::get() noexcept {
-    queue_create_info.pQueuePriorities = priorities.data();
-    queue_create_info.queueCount = 1;
-    queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
-    return queue_create_info;
-}
-
-DeviceCreateInfo::DeviceCreateInfo(const VkDeviceCreateInfo* create_info) {
-    dev = *create_info;
-    for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
-        enabled_extensions.push_back(create_info->ppEnabledExtensionNames[i]);
-    }
-    for (uint32_t i = 0; i < create_info->enabledLayerCount; i++) {
-        enabled_layers.push_back(create_info->ppEnabledLayerNames[i]);
-    }
-    for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++) {
-        device_queue_infos.push_back(create_info->pQueueCreateInfos[i]);
-    }
-}
-
-VkDeviceCreateInfo* DeviceCreateInfo::get() noexcept {
-    dev.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
-    dev.enabledLayerCount = static_cast<uint32_t>(enabled_layers.size());
-    dev.ppEnabledLayerNames = enabled_layers.data();
-    dev.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size());
-    dev.ppEnabledExtensionNames = enabled_extensions.data();
-    uint32_t index = 0;
-    for (auto& queue : queue_info_details) {
-        queue.queue_create_info.queueFamilyIndex = index++;
-        queue.queue_create_info.queueCount = 1;
-        device_queue_infos.push_back(queue.get());
-    }
-
-    dev.queueCreateInfoCount = static_cast<uint32_t>(device_queue_infos.size());
-    dev.pQueueCreateInfos = device_queue_infos.data();
-    return &dev;
-}
-
-#if defined(WIN32)
-std::string narrow(const std::wstring& utf16) {
-    if (utf16.empty()) {
-        return {};
-    }
-    int size = WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()), nullptr, 0, nullptr, nullptr);
-    if (size <= 0) {
-        return {};
-    }
-    std::string utf8(size, '\0');
-    if (WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()), &utf8[0], size, nullptr, nullptr) != size) {
-        return {};
-    }
-    return utf8;
-}
-
-std::wstring widen(const std::string& utf8) {
-    if (utf8.empty()) {
-        return {};
-    }
-    int size = MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), nullptr, 0);
-    if (size <= 0) {
-        return {};
-    }
-    std::wstring utf16(size, L'\0');
-    if (MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), &utf16[0], size) != size) {
-        return {};
-    }
-    return utf16;
-}
-#else
-std::string narrow(const std::string& utf16) { return utf16; }
-std::string widen(const std::string& utf8) { return utf8; }
-#endif
diff --git a/tests/framework/test_util.h b/tests/framework/test_util.h
deleted file mode 100644
index cf8a435..0000000
--- a/tests/framework/test_util.h
+++ /dev/null
@@ -1,1007 +0,0 @@
-/*
- * Copyright (c) 2021-2023 The Khronos Group Inc.
- * Copyright (c) 2021-2023 Valve Corporation
- * Copyright (c) 2021-2023 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and/or associated documentation files (the "Materials"), to
- * deal in the Materials without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Materials, and to permit persons to whom the Materials are
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice(s) and this permission notice shall be included in
- * all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- *
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
- * USE OR OTHER DEALINGS IN THE MATERIALS.
- *
- * Author: Charles Giessen <charles@lunarg.com>
- */
-
-/*
- * Contains all the utilities needed to make the framework and tests work.
- * Contains:
- * All the standard library includes and main platform specific includes
- * Dll export macro
- * Manifest ICD & Layer structs
- * FolderManager - manages the contents of a folder, cleaning up when needed
- * per-platform library loading - mirrors the vk_loader_platform
- * LibraryWrapper - RAII wrapper for a library
- * DispatchableHandle - RAII wrapper for vulkan dispatchable handle objects
- * ostream overload for VkResult - prettifies googletest output
- * Instance & Device create info helpers
- * operator == overloads for many vulkan structs - more concise tests
- */
-#pragma once
-
-#include <algorithm>
-#include <array>
-#include <iostream>
-#include <ostream>
-#include <string>
-#include <vector>
-#include <unordered_map>
-#include <filesystem>
-
-#include <cassert>
-#include <cstring>
-#include <ctime>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdint.h>
-
-// Set of platforms with a common set of functionality which is queried throughout the program
-#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNX__) || defined(__FreeBSD__) || \
-    defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__)
-#define COMMON_UNIX_PLATFORMS 1
-#else
-#define COMMON_UNIX_PLATFORMS 0
-#endif
-
-#if defined(WIN32)
-#include <direct.h>
-#include <windows.h>
-#include <strsafe.h>
-#elif COMMON_UNIX_PLATFORMS
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <dlfcn.h>
-
-// Prevent macro collisions from <sys/types.h>
-#undef major
-#undef minor
-
-#endif
-
-#include <vulkan/vulkan.h>
-#include <vulkan/vk_icd.h>
-#include <vulkan/vk_layer.h>
-
-#include FRAMEWORK_CONFIG_HEADER
-
-#if defined(__GNUC__) && __GNUC__ >= 4
-#define FRAMEWORK_EXPORT __attribute__((visibility("default")))
-#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
-#define FRAMEWORK_EXPORT __attribute__((visibility("default")))
-#elif defined(WIN32)
-#define FRAMEWORK_EXPORT __declspec(dllexport)
-#else
-#define FRAMEWORK_EXPORT
-#endif
-
-// Define it here so that json_writer.h has access to these functions
-#if defined(WIN32)
-// Convert an UTF-16 wstring to an UTF-8 string
-std::string narrow(const std::wstring& utf16);
-// Convert an UTF-8 string to an UTF-16 wstring
-std::wstring widen(const std::string& utf8);
-#else
-// Do nothing passthrough for the sake of Windows & UTF-16
-std::string narrow(const std::string& utf16);
-// Do nothing passthrough for the sake of Windows & UTF-16
-std::string widen(const std::string& utf8);
-#endif
-
-#include "json_writer.h"
-
-// get_env_var() - returns a std::string of `name`. if report_failure is true, then it will log to stderr that it didn't find the
-//     env-var
-// NOTE: This is only intended for test framework code, all test code MUST use EnvVarWrapper
-std::string get_env_var(std::string const& name, bool report_failure = true);
-
-/*
- * Wrapper around Environment Variables with common operations
- * Since Environment Variables leak between tests, there needs to be RAII code to remove them during test cleanup
-
- */
-
-// Wrapper to set & remove env-vars automatically
-struct EnvVarWrapper {
-    // Constructor which unsets the env-var
-    EnvVarWrapper(std::string const& name) noexcept : name(name) {
-        initial_value = get_env_var(name, false);
-        remove_env_var();
-    }
-    // Constructor which set the env-var to the specified value
-    EnvVarWrapper(std::string const& name, std::string const& value) noexcept : name(name), cur_value(value) {
-        initial_value = get_env_var(name, false);
-        set_env_var();
-    }
-    ~EnvVarWrapper() noexcept {
-        remove_env_var();
-        if (!initial_value.empty()) {
-            set_new_value(initial_value);
-        }
-    }
-
-    // delete copy operators
-    EnvVarWrapper(const EnvVarWrapper&) = delete;
-    EnvVarWrapper& operator=(const EnvVarWrapper&) = delete;
-
-    void set_new_value(std::string const& value) {
-        cur_value = value;
-        set_env_var();
-    }
-    void add_to_list(std::string const& list_item) {
-        if (!cur_value.empty()) {
-            cur_value += OS_ENV_VAR_LIST_SEPARATOR;
-        }
-        cur_value += list_item;
-        set_env_var();
-    }
-#if defined(WIN32)
-    void add_to_list(std::wstring const& list_item) {
-        if (!cur_value.empty()) {
-            cur_value += OS_ENV_VAR_LIST_SEPARATOR;
-        }
-        cur_value += narrow(list_item);
-        set_env_var();
-    }
-#endif
-    void remove_value() const { remove_env_var(); }
-    const char* get() const { return name.c_str(); }
-    const char* value() const { return cur_value.c_str(); }
-
-   private:
-    std::string name;
-    std::string cur_value;
-    std::string initial_value;
-
-    void set_env_var();
-    void remove_env_var() const;
-#if defined(WIN32)
-    // Environment variable list separator - not for filesystem paths
-    const char OS_ENV_VAR_LIST_SEPARATOR = ';';
-#elif COMMON_UNIX_PLATFORMS
-    // Environment variable list separator - not for filesystem paths
-    const char OS_ENV_VAR_LIST_SEPARATOR = ':';
-#endif
-};
-
-// Windows specific error handling logic
-#if defined(WIN32)
-const long ERROR_SETENV_FAILED = 10543;           // chosen at random, attempts to not conflict
-const long ERROR_REMOVEDIRECTORY_FAILED = 10544;  // chosen at random, attempts to not conflict
-const char* win_api_error_str(LSTATUS status);
-void print_error_message(LSTATUS status, const char* function_name, std::string optional_message = "");
-#endif
-
-struct ManifestICD;    // forward declaration for FolderManager::write
-struct ManifestLayer;  // forward declaration for FolderManager::write
-
-namespace fs {
-
-int create_folder(std::filesystem::path const& path);
-int delete_folder(std::filesystem::path const& folder);
-
-class FolderManager {
-   public:
-    explicit FolderManager(std::filesystem::path root_path, std::string name) noexcept;
-    ~FolderManager() noexcept;
-    FolderManager(FolderManager const&) = delete;
-    FolderManager& operator=(FolderManager const&) = delete;
-    FolderManager(FolderManager&& other) noexcept;
-    FolderManager& operator=(FolderManager&& other) noexcept;
-
-    // Add a manifest to the folder
-    std::filesystem::path write_manifest(std::filesystem::path const& name, std::string const& contents);
-
-    // Add an already existing file to the manager, so it will be cleaned up automatically
-    void add_existing_file(std::filesystem::path const& file_name);
-
-    // close file handle, delete file, remove `name` from managed file list.
-    void remove(std::filesystem::path const& name);
-
-    // copy file into this folder with name `new_name`. Returns the full path of the file that was copied
-    std::filesystem::path copy_file(std::filesystem::path const& file, std::filesystem::path const& new_name);
-
-    // location of the managed folder
-    std::filesystem::path location() const { return folder; }
-
-    std::vector<std::filesystem::path> get_files() const { return files; }
-
-   private:
-    std::filesystem::path folder;
-    std::vector<std::filesystem::path> files;
-};
-}  // namespace fs
-
-// copy the contents of a std::string into a char array and add a null terminator at the end
-// src - std::string to read from
-// dst - char array to write to
-// size_dst - number of characters in the dst array
-inline void copy_string_to_char_array(std::string const& src, char* dst, size_t size_dst) { dst[src.copy(dst, size_dst - 1)] = 0; }
-
-#if defined(WIN32)
-typedef HMODULE loader_platform_dl_handle;
-inline loader_platform_dl_handle loader_platform_open_library(const wchar_t* lib_path) {
-    // Try loading the library the original way first.
-    loader_platform_dl_handle lib_handle = LoadLibraryW(lib_path);
-    if (lib_handle == nullptr && GetLastError() == ERROR_MOD_NOT_FOUND) {
-        // If that failed, then try loading it with broader search folders.
-        lib_handle = LoadLibraryExW(lib_path, nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
-    }
-    return lib_handle;
-}
-inline void loader_platform_open_library_print_error(std::filesystem::path const& libPath) {
-    std::wcerr << L"Unable to open library: " << libPath << L" due to: " << std::to_wstring(GetLastError()) << L"\n";
-}
-inline void loader_platform_close_library(loader_platform_dl_handle library) { FreeLibrary(library); }
-inline void* loader_platform_get_proc_address(loader_platform_dl_handle library, const char* name) {
-    assert(library);
-    assert(name);
-    return reinterpret_cast<void*>(GetProcAddress(library, name));
-}
-inline char* loader_platform_get_proc_address_error(const char* name) {
-    static char errorMsg[120];
-    snprintf(errorMsg, 119, "Failed to find function \"%s\" in dynamic library", name);
-    return errorMsg;
-}
-
-#elif COMMON_UNIX_PLATFORMS
-
-typedef void* loader_platform_dl_handle;
-inline loader_platform_dl_handle loader_platform_open_library(const char* libPath) {
-    return dlopen(libPath, RTLD_LAZY | RTLD_LOCAL);
-}
-inline void loader_platform_open_library_print_error(std::filesystem::path const& libPath) {
-    std::wcerr << "Unable to open library: " << libPath << " due to: " << dlerror() << "\n";
-}
-inline void loader_platform_close_library(loader_platform_dl_handle library) {
-    char* loader_disable_dynamic_library_unloading_env_var = getenv("VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING");
-    if (NULL == loader_disable_dynamic_library_unloading_env_var ||
-        0 != strncmp(loader_disable_dynamic_library_unloading_env_var, "1", 2)) {
-        dlclose(library);
-    }
-}
-inline void* loader_platform_get_proc_address(loader_platform_dl_handle library, const char* name) {
-    assert(library);
-    assert(name);
-    return dlsym(library, name);
-}
-inline const char* loader_platform_get_proc_address_error([[maybe_unused]] const char* name) { return dlerror(); }
-#endif
-
-class FromVoidStarFunc {
-   private:
-    void* function;
-
-   public:
-    FromVoidStarFunc(void* function) : function(function) {}
-    FromVoidStarFunc(PFN_vkVoidFunction function) : function(reinterpret_cast<void*>(function)) {}
-
-    template <typename T>
-    operator T() {
-        return reinterpret_cast<T>(function);
-    }
-};
-
-struct LibraryWrapper {
-    explicit LibraryWrapper() noexcept {}
-    explicit LibraryWrapper(std::filesystem::path const& lib_path) noexcept : lib_path(lib_path) {
-        lib_handle = loader_platform_open_library(lib_path.native().c_str());
-        if (lib_handle == nullptr) {
-            loader_platform_open_library_print_error(lib_path);
-            assert(lib_handle != nullptr && "Must be able to open library");
-        }
-    }
-    ~LibraryWrapper() noexcept {
-        if (lib_handle != nullptr) {
-            loader_platform_close_library(lib_handle);
-            lib_handle = nullptr;
-        }
-    }
-    LibraryWrapper(LibraryWrapper const& wrapper) = delete;
-    LibraryWrapper& operator=(LibraryWrapper const& wrapper) = delete;
-    LibraryWrapper(LibraryWrapper&& wrapper) noexcept : lib_handle(wrapper.lib_handle), lib_path(wrapper.lib_path) {
-        wrapper.lib_handle = nullptr;
-    }
-    LibraryWrapper& operator=(LibraryWrapper&& wrapper) noexcept {
-        if (this != &wrapper) {
-            if (lib_handle != nullptr) {
-                loader_platform_close_library(lib_handle);
-            }
-            lib_handle = wrapper.lib_handle;
-            lib_path = wrapper.lib_path;
-            wrapper.lib_handle = nullptr;
-        }
-        return *this;
-    }
-    FromVoidStarFunc get_symbol(const char* symbol_name) const {
-        assert(lib_handle != nullptr && "Cannot get symbol with null library handle");
-        void* symbol = loader_platform_get_proc_address(lib_handle, symbol_name);
-        if (symbol == nullptr) {
-            fprintf(stderr, "Unable to open symbol %s: %s\n", symbol_name, loader_platform_get_proc_address_error(symbol_name));
-            assert(symbol != nullptr && "Must be able to get symbol");
-        }
-        return FromVoidStarFunc(symbol);
-    }
-
-    explicit operator bool() const noexcept { return lib_handle != nullptr; }
-
-    loader_platform_dl_handle lib_handle = nullptr;
-    std::filesystem::path lib_path;
-};
-
-template <typename T>
-PFN_vkVoidFunction to_vkVoidFunction(T func) {
-    return reinterpret_cast<PFN_vkVoidFunction>(func);
-}
-template <typename T>
-struct FRAMEWORK_EXPORT DispatchableHandle {
-    DispatchableHandle() {
-        auto ptr_handle = new VK_LOADER_DATA;
-        set_loader_magic_value(ptr_handle);
-        handle = reinterpret_cast<T>(ptr_handle);
-    }
-    ~DispatchableHandle() {
-        if (handle) {
-            delete reinterpret_cast<VK_LOADER_DATA*>(handle);
-        }
-        handle = nullptr;
-    }
-    DispatchableHandle(DispatchableHandle const&) = delete;
-    DispatchableHandle& operator=(DispatchableHandle const&) = delete;
-    DispatchableHandle(DispatchableHandle&& other) noexcept : handle(other.handle) { other.handle = nullptr; }
-    DispatchableHandle& operator=(DispatchableHandle&& other) noexcept {
-        if (handle) {
-            delete reinterpret_cast<VK_LOADER_DATA*>(handle);
-        }
-        handle = other.handle;
-        other.handle = nullptr;
-        return *this;
-    }
-    bool operator==(T base_handle) { return base_handle == handle; }
-    bool operator!=(T base_handle) { return base_handle != handle; }
-
-    T handle = nullptr;
-};
-
-// Stream operator for VkResult so GTEST will print out error codes as strings (automatically)
-inline std::ostream& operator<<(std::ostream& os, const VkResult& result) {
-    switch (result) {
-        case (VK_SUCCESS):
-            return os << "VK_SUCCESS";
-        case (VK_NOT_READY):
-            return os << "VK_NOT_READY";
-        case (VK_TIMEOUT):
-            return os << "VK_TIMEOUT";
-        case (VK_EVENT_SET):
-            return os << "VK_EVENT_SET";
-        case (VK_EVENT_RESET):
-            return os << "VK_EVENT_RESET";
-        case (VK_INCOMPLETE):
-            return os << "VK_INCOMPLETE";
-        case (VK_ERROR_OUT_OF_HOST_MEMORY):
-            return os << "VK_ERROR_OUT_OF_HOST_MEMORY";
-        case (VK_ERROR_OUT_OF_DEVICE_MEMORY):
-            return os << "VK_ERROR_OUT_OF_DEVICE_MEMORY";
-        case (VK_ERROR_INITIALIZATION_FAILED):
-            return os << "VK_ERROR_INITIALIZATION_FAILED";
-        case (VK_ERROR_DEVICE_LOST):
-            return os << "VK_ERROR_DEVICE_LOST";
-        case (VK_ERROR_MEMORY_MAP_FAILED):
-            return os << "VK_ERROR_MEMORY_MAP_FAILED";
-        case (VK_ERROR_LAYER_NOT_PRESENT):
-            return os << "VK_ERROR_LAYER_NOT_PRESENT";
-        case (VK_ERROR_EXTENSION_NOT_PRESENT):
-            return os << "VK_ERROR_EXTENSION_NOT_PRESENT";
-        case (VK_ERROR_FEATURE_NOT_PRESENT):
-            return os << "VK_ERROR_FEATURE_NOT_PRESENT";
-        case (VK_ERROR_INCOMPATIBLE_DRIVER):
-            return os << "VK_ERROR_INCOMPATIBLE_DRIVER";
-        case (VK_ERROR_TOO_MANY_OBJECTS):
-            return os << "VK_ERROR_TOO_MANY_OBJECTS";
-        case (VK_ERROR_FORMAT_NOT_SUPPORTED):
-            return os << "VK_ERROR_FORMAT_NOT_SUPPORTED";
-        case (VK_ERROR_FRAGMENTED_POOL):
-            return os << "VK_ERROR_FRAGMENTED_POOL";
-        case (VK_ERROR_UNKNOWN):
-            return os << "VK_ERROR_UNKNOWN";
-        case (VK_ERROR_OUT_OF_POOL_MEMORY):
-            return os << "VK_ERROR_OUT_OF_POOL_MEMORY";
-        case (VK_ERROR_INVALID_EXTERNAL_HANDLE):
-            return os << "VK_ERROR_INVALID_EXTERNAL_HANDLE";
-        case (VK_ERROR_FRAGMENTATION):
-            return os << "VK_ERROR_FRAGMENTATION";
-        case (VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS):
-            return os << "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS";
-        case (VK_ERROR_SURFACE_LOST_KHR):
-            return os << "VK_ERROR_SURFACE_LOST_KHR";
-        case (VK_ERROR_NATIVE_WINDOW_IN_USE_KHR):
-            return os << "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
-        case (VK_SUBOPTIMAL_KHR):
-            return os << "VK_SUBOPTIMAL_KHR";
-        case (VK_ERROR_OUT_OF_DATE_KHR):
-            return os << "VK_ERROR_OUT_OF_DATE_KHR";
-        case (VK_ERROR_INCOMPATIBLE_DISPLAY_KHR):
-            return os << "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
-        case (VK_ERROR_VALIDATION_FAILED_EXT):
-            return os << "VK_ERROR_VALIDATION_FAILED_EXT";
-        case (VK_ERROR_INVALID_SHADER_NV):
-            return os << "VK_ERROR_INVALID_SHADER_NV";
-        case (VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT):
-            return os << "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
-        case (VK_ERROR_NOT_PERMITTED_EXT):
-            return os << "VK_ERROR_NOT_PERMITTED_EXT";
-        case (VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT):
-            return os << "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
-        case (VK_THREAD_IDLE_KHR):
-            return os << "VK_THREAD_IDLE_KHR";
-        case (VK_THREAD_DONE_KHR):
-            return os << "VK_THREAD_DONE_KHR";
-        case (VK_OPERATION_DEFERRED_KHR):
-            return os << "VK_OPERATION_DEFERRED_KHR";
-        case (VK_OPERATION_NOT_DEFERRED_KHR):
-            return os << "VK_OPERATION_NOT_DEFERRED_KHR";
-        case (VK_PIPELINE_COMPILE_REQUIRED_EXT):
-            return os << "VK_PIPELINE_COMPILE_REQUIRED_EXT";
-        case (VK_RESULT_MAX_ENUM):
-            return os << "VK_RESULT_MAX_ENUM";
-        case (VK_ERROR_COMPRESSION_EXHAUSTED_EXT):
-            return os << "VK_ERROR_COMPRESSION_EXHAUSTED_EXT";
-        case (VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR):
-            return os << "VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR";
-        case (VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR):
-            return os << "VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR";
-        case (VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR):
-            return os << "VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR";
-        case (VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR):
-            return os << "VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR";
-        case (VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR):
-            return os << "VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR";
-        case (VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR):
-            return os << "VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR";
-        case (VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR):
-            return os << "VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR";
-        case (VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT):
-            return os << "VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT";
-        case (VK_PIPELINE_BINARY_MISSING_KHR):
-            return os << "VK_PIPELINE_BINARY_MISSING_KHR";
-        case (VK_ERROR_NOT_ENOUGH_SPACE_KHR):
-            return os << "VK_ERROR_NOT_ENOUGH_SPACE_KHR";
-    }
-    return os << static_cast<int32_t>(result);
-}
-
-const char* get_platform_wsi_extension([[maybe_unused]] const char* api_selection);
-
-bool string_eq(const char* a, const char* b) noexcept;
-bool string_eq(const char* a, const char* b, size_t len) noexcept;
-
-inline std::string version_to_string(uint32_t version) {
-    std::string out = std::to_string(VK_API_VERSION_MAJOR(version)) + "." + std::to_string(VK_API_VERSION_MINOR(version)) + "." +
-                      std::to_string(VK_API_VERSION_PATCH(version));
-    if (VK_API_VERSION_VARIANT(version) != 0) out += std::to_string(VK_API_VERSION_VARIANT(version)) + "." + out;
-    return out;
-}
-
-// Macro to ease the definition of variables with builder member functions
-// class_name = class the member variable is apart of
-// type = type of the variable
-// name = name of the variable
-// default_value = value to default initialize, use {} if nothing else makes sense
-#define BUILDER_VALUE(class_name, type, name, default_value) \
-    type name = default_value;                               \
-    class_name& set_##name(type const& name) {               \
-        this->name = name;                                   \
-        return *this;                                        \
-    }
-
-// Macro to ease the definition of vectors with builder member functions
-// class_name = class the member variable is apart of
-// type = type of the variable
-// name = name of the variable
-// singular_name = used for the `add_singular_name` member function
-#define BUILDER_VECTOR(class_name, type, name, singular_name)                    \
-    std::vector<type> name;                                                      \
-    class_name& add_##singular_name(type const& singular_name) {                 \
-        this->name.push_back(singular_name);                                     \
-        return *this;                                                            \
-    }                                                                            \
-    class_name& add_##singular_name##s(std::vector<type> const& singular_name) { \
-        for (auto& elem : singular_name) this->name.push_back(elem);             \
-        return *this;                                                            \
-    }
-// Like BUILDER_VECTOR but for move only types - where passing in means giving up ownership
-#define BUILDER_VECTOR_MOVE_ONLY(class_name, type, name, singular_name) \
-    std::vector<type> name;                                             \
-    class_name& add_##singular_name(type&& singular_name) {             \
-        this->name.push_back(std::move(singular_name));                 \
-        return *this;                                                   \
-    }
-
-struct ManifestVersion {
-    BUILDER_VALUE(ManifestVersion, uint32_t, major, 1)
-    BUILDER_VALUE(ManifestVersion, uint32_t, minor, 0)
-    BUILDER_VALUE(ManifestVersion, uint32_t, patch, 0)
-
-    std::string get_version_str() const noexcept {
-        return std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(patch);
-    }
-};
-
-// ManifestICD builder
-struct ManifestICD {
-    BUILDER_VALUE(ManifestICD, ManifestVersion, file_format_version, {})
-    BUILDER_VALUE(ManifestICD, uint32_t, api_version, 0)
-    BUILDER_VALUE(ManifestICD, std::filesystem::path, lib_path, {})
-    BUILDER_VALUE(ManifestICD, bool, is_portability_driver, false)
-    BUILDER_VALUE(ManifestICD, std::string, library_arch, "")
-    std::string get_manifest_str() const;
-};
-
-// ManifestLayer builder
-struct ManifestLayer {
-    struct LayerDescription {
-        enum class Type { INSTANCE, GLOBAL, DEVICE };
-        std::string get_type_str(Type layer_type) const {
-            if (layer_type == Type::GLOBAL)
-                return "GLOBAL";
-            else if (layer_type == Type::DEVICE)
-                return "DEVICE";
-            else  // default
-                return "INSTANCE";
-        }
-        struct FunctionOverride {
-            BUILDER_VALUE(FunctionOverride, std::string, vk_func, {})
-            BUILDER_VALUE(FunctionOverride, std::string, override_name, {})
-
-            void get_manifest_str(JsonWriter& writer) const { writer.AddKeyedString(vk_func, override_name); }
-        };
-        struct Extension {
-            Extension() noexcept {}
-            Extension(std::string name, uint32_t spec_version = 0, std::vector<std::string> entrypoints = {}) noexcept
-                : name(name), spec_version(spec_version), entrypoints(entrypoints) {}
-            std::string name;
-            uint32_t spec_version = 0;
-            std::vector<std::string> entrypoints;
-            void get_manifest_str(JsonWriter& writer) const;
-        };
-        BUILDER_VALUE(LayerDescription, std::string, name, {})
-        BUILDER_VALUE(LayerDescription, Type, type, Type::INSTANCE)
-        BUILDER_VALUE(LayerDescription, std::filesystem::path, lib_path, {})
-        BUILDER_VALUE(LayerDescription, uint32_t, api_version, VK_API_VERSION_1_0)
-        BUILDER_VALUE(LayerDescription, uint32_t, implementation_version, 0)
-        BUILDER_VALUE(LayerDescription, std::string, description, {})
-        BUILDER_VECTOR(LayerDescription, FunctionOverride, functions, function)
-        BUILDER_VECTOR(LayerDescription, Extension, instance_extensions, instance_extension)
-        BUILDER_VECTOR(LayerDescription, Extension, device_extensions, device_extension)
-        BUILDER_VALUE(LayerDescription, std::string, enable_environment, {})
-        BUILDER_VALUE(LayerDescription, std::string, disable_environment, {})
-        BUILDER_VECTOR(LayerDescription, std::string, component_layers, component_layer)
-        BUILDER_VECTOR(LayerDescription, std::string, blacklisted_layers, blacklisted_layer)
-        BUILDER_VECTOR(LayerDescription, std::filesystem::path, override_paths, override_path)
-        BUILDER_VECTOR(LayerDescription, FunctionOverride, pre_instance_functions, pre_instance_function)
-        BUILDER_VECTOR(LayerDescription, std::string, app_keys, app_key)
-        BUILDER_VALUE(LayerDescription, std::string, library_arch, "")
-
-        void get_manifest_str(JsonWriter& writer) const;
-        VkLayerProperties get_layer_properties() const;
-    };
-    BUILDER_VALUE(ManifestLayer, ManifestVersion, file_format_version, {})
-    BUILDER_VECTOR(ManifestLayer, LayerDescription, layers, layer)
-
-    std::string get_manifest_str() const;
-};
-
-struct Extension {
-    BUILDER_VALUE(Extension, std::string, extensionName, {})
-    BUILDER_VALUE(Extension, uint32_t, specVersion, VK_API_VERSION_1_0)
-
-    Extension(const char* name, uint32_t specVersion = VK_API_VERSION_1_0) noexcept
-        : extensionName(name), specVersion(specVersion) {}
-    Extension(std::string extensionName, uint32_t specVersion = VK_API_VERSION_1_0) noexcept
-        : extensionName(extensionName), specVersion(specVersion) {}
-
-    VkExtensionProperties get() const noexcept {
-        VkExtensionProperties props{};
-        copy_string_to_char_array(extensionName, &props.extensionName[0], VK_MAX_EXTENSION_NAME_SIZE);
-        props.specVersion = specVersion;
-        return props;
-    }
-};
-
-struct MockQueueFamilyProperties {
-    BUILDER_VALUE(MockQueueFamilyProperties, VkQueueFamilyProperties, properties, {})
-    BUILDER_VALUE(MockQueueFamilyProperties, bool, support_present, false)
-
-    VkQueueFamilyProperties get() const noexcept { return properties; }
-};
-
-struct InstanceCreateInfo {
-    BUILDER_VALUE(InstanceCreateInfo, VkInstanceCreateInfo, instance_info, {})
-    BUILDER_VALUE(InstanceCreateInfo, VkApplicationInfo, application_info, {})
-    BUILDER_VALUE(InstanceCreateInfo, std::string, app_name, {})
-    BUILDER_VALUE(InstanceCreateInfo, std::string, engine_name, {})
-    BUILDER_VALUE(InstanceCreateInfo, uint32_t, flags, 0)
-    BUILDER_VALUE(InstanceCreateInfo, uint32_t, app_version, 0)
-    BUILDER_VALUE(InstanceCreateInfo, uint32_t, engine_version, 0)
-    BUILDER_VALUE(InstanceCreateInfo, uint32_t, api_version, VK_API_VERSION_1_0)
-    BUILDER_VECTOR(InstanceCreateInfo, const char*, enabled_layers, layer)
-    BUILDER_VECTOR(InstanceCreateInfo, const char*, enabled_extensions, extension)
-    // tell the get() function to not provide `application_info`
-    BUILDER_VALUE(InstanceCreateInfo, bool, fill_in_application_info, true)
-
-    InstanceCreateInfo();
-
-    VkInstanceCreateInfo* get() noexcept;
-
-    InstanceCreateInfo& set_api_version(uint32_t major, uint32_t minor, uint32_t patch);
-
-    InstanceCreateInfo& setup_WSI(const char* api_selection = nullptr);
-};
-
-struct DeviceQueueCreateInfo {
-    DeviceQueueCreateInfo();
-    DeviceQueueCreateInfo(const VkDeviceQueueCreateInfo* create_info);
-
-    BUILDER_VALUE(DeviceQueueCreateInfo, VkDeviceQueueCreateInfo, queue_create_info, {})
-    BUILDER_VECTOR(DeviceQueueCreateInfo, float, priorities, priority)
-
-    VkDeviceQueueCreateInfo get() noexcept;
-};
-
-struct DeviceCreateInfo {
-    DeviceCreateInfo() = default;
-    DeviceCreateInfo(const VkDeviceCreateInfo* create_info);
-
-    BUILDER_VALUE(DeviceCreateInfo, VkDeviceCreateInfo, dev, {})
-    BUILDER_VECTOR(DeviceCreateInfo, const char*, enabled_extensions, extension)
-    BUILDER_VECTOR(DeviceCreateInfo, const char*, enabled_layers, layer)
-    BUILDER_VECTOR(DeviceCreateInfo, DeviceQueueCreateInfo, queue_info_details, device_queue)
-
-    VkDeviceCreateInfo* get() noexcept;
-
-   private:
-    std::vector<VkDeviceQueueCreateInfo> device_queue_infos;
-};
-
-inline bool operator==(const VkExtent3D& a, const VkExtent3D& b) {
-    return a.width == b.width && a.height == b.height && a.depth == b.depth;
-}
-inline bool operator!=(const VkExtent3D& a, const VkExtent3D& b) { return !(a == b); }
-
-inline bool operator==(const VkQueueFamilyProperties& a, const VkQueueFamilyProperties& b) {
-    return a.minImageTransferGranularity == b.minImageTransferGranularity && a.queueCount == b.queueCount &&
-           a.queueFlags == b.queueFlags && a.timestampValidBits == b.timestampValidBits;
-}
-inline bool operator!=(const VkQueueFamilyProperties& a, const VkQueueFamilyProperties& b) { return !(a == b); }
-
-inline bool operator==(const VkQueueFamilyProperties& a, const VkQueueFamilyProperties2& b) { return a == b.queueFamilyProperties; }
-inline bool operator!=(const VkQueueFamilyProperties& a, const VkQueueFamilyProperties2& b) { return a != b.queueFamilyProperties; }
-
-inline bool operator==(const VkLayerProperties& a, const VkLayerProperties& b) {
-    return string_eq(a.layerName, b.layerName, 256) && string_eq(a.description, b.description, 256) &&
-           a.implementationVersion == b.implementationVersion && a.specVersion == b.specVersion;
-}
-inline bool operator!=(const VkLayerProperties& a, const VkLayerProperties& b) { return !(a == b); }
-
-inline bool operator==(const VkExtensionProperties& a, const VkExtensionProperties& b) {
-    return string_eq(a.extensionName, b.extensionName, 256) && a.specVersion == b.specVersion;
-}
-inline bool operator!=(const VkExtensionProperties& a, const VkExtensionProperties& b) { return !(a == b); }
-
-inline bool operator==(const VkPhysicalDeviceFeatures& feats1, const VkPhysicalDeviceFeatures2& feats2) {
-    return feats1.robustBufferAccess == feats2.features.robustBufferAccess &&
-           feats1.fullDrawIndexUint32 == feats2.features.fullDrawIndexUint32 &&
-           feats1.imageCubeArray == feats2.features.imageCubeArray && feats1.independentBlend == feats2.features.independentBlend &&
-           feats1.geometryShader == feats2.features.geometryShader &&
-           feats1.tessellationShader == feats2.features.tessellationShader &&
-           feats1.sampleRateShading == feats2.features.sampleRateShading && feats1.dualSrcBlend == feats2.features.dualSrcBlend &&
-           feats1.logicOp == feats2.features.logicOp && feats1.multiDrawIndirect == feats2.features.multiDrawIndirect &&
-           feats1.drawIndirectFirstInstance == feats2.features.drawIndirectFirstInstance &&
-           feats1.depthClamp == feats2.features.depthClamp && feats1.depthBiasClamp == feats2.features.depthBiasClamp &&
-           feats1.fillModeNonSolid == feats2.features.fillModeNonSolid && feats1.depthBounds == feats2.features.depthBounds &&
-           feats1.wideLines == feats2.features.wideLines && feats1.largePoints == feats2.features.largePoints &&
-           feats1.alphaToOne == feats2.features.alphaToOne && feats1.multiViewport == feats2.features.multiViewport &&
-           feats1.samplerAnisotropy == feats2.features.samplerAnisotropy &&
-           feats1.textureCompressionETC2 == feats2.features.textureCompressionETC2 &&
-           feats1.textureCompressionASTC_LDR == feats2.features.textureCompressionASTC_LDR &&
-           feats1.textureCompressionBC == feats2.features.textureCompressionBC &&
-           feats1.occlusionQueryPrecise == feats2.features.occlusionQueryPrecise &&
-           feats1.pipelineStatisticsQuery == feats2.features.pipelineStatisticsQuery &&
-           feats1.vertexPipelineStoresAndAtomics == feats2.features.vertexPipelineStoresAndAtomics &&
-           feats1.fragmentStoresAndAtomics == feats2.features.fragmentStoresAndAtomics &&
-           feats1.shaderTessellationAndGeometryPointSize == feats2.features.shaderTessellationAndGeometryPointSize &&
-           feats1.shaderImageGatherExtended == feats2.features.shaderImageGatherExtended &&
-           feats1.shaderStorageImageExtendedFormats == feats2.features.shaderStorageImageExtendedFormats &&
-           feats1.shaderStorageImageMultisample == feats2.features.shaderStorageImageMultisample &&
-           feats1.shaderStorageImageReadWithoutFormat == feats2.features.shaderStorageImageReadWithoutFormat &&
-           feats1.shaderStorageImageWriteWithoutFormat == feats2.features.shaderStorageImageWriteWithoutFormat &&
-           feats1.shaderUniformBufferArrayDynamicIndexing == feats2.features.shaderUniformBufferArrayDynamicIndexing &&
-           feats1.shaderSampledImageArrayDynamicIndexing == feats2.features.shaderSampledImageArrayDynamicIndexing &&
-           feats1.shaderStorageBufferArrayDynamicIndexing == feats2.features.shaderStorageBufferArrayDynamicIndexing &&
-           feats1.shaderStorageImageArrayDynamicIndexing == feats2.features.shaderStorageImageArrayDynamicIndexing &&
-           feats1.shaderClipDistance == feats2.features.shaderClipDistance &&
-           feats1.shaderCullDistance == feats2.features.shaderCullDistance &&
-           feats1.shaderFloat64 == feats2.features.shaderFloat64 && feats1.shaderInt64 == feats2.features.shaderInt64 &&
-           feats1.shaderInt16 == feats2.features.shaderInt16 &&
-           feats1.shaderResourceResidency == feats2.features.shaderResourceResidency &&
-           feats1.shaderResourceMinLod == feats2.features.shaderResourceMinLod &&
-           feats1.sparseBinding == feats2.features.sparseBinding &&
-           feats1.sparseResidencyBuffer == feats2.features.sparseResidencyBuffer &&
-           feats1.sparseResidencyImage2D == feats2.features.sparseResidencyImage2D &&
-           feats1.sparseResidencyImage3D == feats2.features.sparseResidencyImage3D &&
-           feats1.sparseResidency2Samples == feats2.features.sparseResidency2Samples &&
-           feats1.sparseResidency4Samples == feats2.features.sparseResidency4Samples &&
-           feats1.sparseResidency8Samples == feats2.features.sparseResidency8Samples &&
-           feats1.sparseResidency16Samples == feats2.features.sparseResidency16Samples &&
-           feats1.sparseResidencyAliased == feats2.features.sparseResidencyAliased &&
-           feats1.variableMultisampleRate == feats2.features.variableMultisampleRate &&
-           feats1.inheritedQueries == feats2.features.inheritedQueries;
-}
-
-inline bool operator==(const VkPhysicalDeviceMemoryProperties& props1, const VkPhysicalDeviceMemoryProperties2& props2) {
-    bool equal = true;
-    equal = equal && props1.memoryTypeCount == props2.memoryProperties.memoryTypeCount;
-    equal = equal && props1.memoryHeapCount == props2.memoryProperties.memoryHeapCount;
-    for (uint32_t i = 0; i < props1.memoryHeapCount; ++i) {
-        equal = equal && props1.memoryHeaps[i].size == props2.memoryProperties.memoryHeaps[i].size;
-        equal = equal && props1.memoryHeaps[i].flags == props2.memoryProperties.memoryHeaps[i].flags;
-    }
-    for (uint32_t i = 0; i < props1.memoryTypeCount; ++i) {
-        equal = equal && props1.memoryTypes[i].propertyFlags == props2.memoryProperties.memoryTypes[i].propertyFlags;
-        equal = equal && props1.memoryTypes[i].heapIndex == props2.memoryProperties.memoryTypes[i].heapIndex;
-    }
-    return equal;
-}
-inline bool operator==(const VkSparseImageFormatProperties& props1, const VkSparseImageFormatProperties& props2) {
-    return props1.aspectMask == props2.aspectMask && props1.imageGranularity.width == props2.imageGranularity.width &&
-           props1.imageGranularity.height == props2.imageGranularity.height &&
-           props1.imageGranularity.depth == props2.imageGranularity.depth && props1.flags == props2.flags;
-}
-inline bool operator==(const VkSparseImageFormatProperties& props1, const VkSparseImageFormatProperties2& props2) {
-    return props1 == props2.properties;
-}
-inline bool operator==(const VkExternalMemoryProperties& props1, const VkExternalMemoryProperties& props2) {
-    return props1.externalMemoryFeatures == props2.externalMemoryFeatures &&
-           props1.exportFromImportedHandleTypes == props2.exportFromImportedHandleTypes &&
-           props1.compatibleHandleTypes == props2.compatibleHandleTypes;
-}
-inline bool operator==(const VkExternalSemaphoreProperties& props1, const VkExternalSemaphoreProperties& props2) {
-    return props1.externalSemaphoreFeatures == props2.externalSemaphoreFeatures &&
-           props1.exportFromImportedHandleTypes == props2.exportFromImportedHandleTypes &&
-           props1.compatibleHandleTypes == props2.compatibleHandleTypes;
-}
-inline bool operator==(const VkExternalFenceProperties& props1, const VkExternalFenceProperties& props2) {
-    return props1.externalFenceFeatures == props2.externalFenceFeatures &&
-           props1.exportFromImportedHandleTypes == props2.exportFromImportedHandleTypes &&
-           props1.compatibleHandleTypes == props2.compatibleHandleTypes;
-}
-inline bool operator==(const VkSurfaceCapabilitiesKHR& props1, const VkSurfaceCapabilitiesKHR& props2) {
-    return props1.minImageCount == props2.minImageCount && props1.maxImageCount == props2.maxImageCount &&
-           props1.currentExtent.width == props2.currentExtent.width && props1.currentExtent.height == props2.currentExtent.height &&
-           props1.minImageExtent.width == props2.minImageExtent.width &&
-           props1.minImageExtent.height == props2.minImageExtent.height &&
-           props1.maxImageExtent.width == props2.maxImageExtent.width &&
-           props1.maxImageExtent.height == props2.maxImageExtent.height &&
-           props1.maxImageArrayLayers == props2.maxImageArrayLayers && props1.supportedTransforms == props2.supportedTransforms &&
-           props1.currentTransform == props2.currentTransform && props1.supportedCompositeAlpha == props2.supportedCompositeAlpha &&
-           props1.supportedUsageFlags == props2.supportedUsageFlags;
-}
-inline bool operator==(const VkSurfacePresentScalingCapabilitiesEXT& caps1, const VkSurfacePresentScalingCapabilitiesEXT& caps2) {
-    return caps1.supportedPresentScaling == caps2.supportedPresentScaling &&
-           caps1.supportedPresentGravityX == caps2.supportedPresentGravityX &&
-           caps1.supportedPresentGravityY == caps2.supportedPresentGravityY &&
-           caps1.minScaledImageExtent.width == caps2.minScaledImageExtent.width &&
-           caps1.minScaledImageExtent.height == caps2.minScaledImageExtent.height &&
-           caps1.maxScaledImageExtent.width == caps2.maxScaledImageExtent.width &&
-           caps1.maxScaledImageExtent.height == caps2.maxScaledImageExtent.height;
-}
-inline bool operator==(const VkSurfaceFormatKHR& format1, const VkSurfaceFormatKHR& format2) {
-    return format1.format == format2.format && format1.colorSpace == format2.colorSpace;
-}
-inline bool operator==(const VkSurfaceFormatKHR& format1, const VkSurfaceFormat2KHR& format2) {
-    return format1 == format2.surfaceFormat;
-}
-inline bool operator==(const VkDisplayPropertiesKHR& props1, const VkDisplayPropertiesKHR& props2) {
-    return props1.display == props2.display && props1.physicalDimensions.width == props2.physicalDimensions.width &&
-           props1.physicalDimensions.height == props2.physicalDimensions.height &&
-           props1.physicalResolution.width == props2.physicalResolution.width &&
-           props1.physicalResolution.height == props2.physicalResolution.height &&
-           props1.supportedTransforms == props2.supportedTransforms && props1.planeReorderPossible == props2.planeReorderPossible &&
-           props1.persistentContent == props2.persistentContent;
-}
-inline bool operator==(const VkDisplayPropertiesKHR& props1, const VkDisplayProperties2KHR& props2) {
-    return props1 == props2.displayProperties;
-}
-inline bool operator==(const VkDisplayModePropertiesKHR& disp1, const VkDisplayModePropertiesKHR& disp2) {
-    return disp1.displayMode == disp2.displayMode && disp1.parameters.visibleRegion.width == disp2.parameters.visibleRegion.width &&
-           disp1.parameters.visibleRegion.height == disp2.parameters.visibleRegion.height &&
-           disp1.parameters.refreshRate == disp2.parameters.refreshRate;
-}
-
-inline bool operator==(const VkDisplayModePropertiesKHR& disp1, const VkDisplayModeProperties2KHR& disp2) {
-    return disp1 == disp2.displayModeProperties;
-}
-inline bool operator==(const VkDisplayPlaneCapabilitiesKHR& caps1, const VkDisplayPlaneCapabilitiesKHR& caps2) {
-    return caps1.supportedAlpha == caps2.supportedAlpha && caps1.minSrcPosition.x == caps2.minSrcPosition.x &&
-           caps1.minSrcPosition.y == caps2.minSrcPosition.y && caps1.maxSrcPosition.x == caps2.maxSrcPosition.x &&
-           caps1.maxSrcPosition.y == caps2.maxSrcPosition.y && caps1.minSrcExtent.width == caps2.minSrcExtent.width &&
-           caps1.minSrcExtent.height == caps2.minSrcExtent.height && caps1.maxSrcExtent.width == caps2.maxSrcExtent.width &&
-           caps1.maxSrcExtent.height == caps2.maxSrcExtent.height && caps1.minDstPosition.x == caps2.minDstPosition.x &&
-           caps1.minDstPosition.y == caps2.minDstPosition.y && caps1.maxDstPosition.x == caps2.maxDstPosition.x &&
-           caps1.maxDstPosition.y == caps2.maxDstPosition.y && caps1.minDstExtent.width == caps2.minDstExtent.width &&
-           caps1.minDstExtent.height == caps2.minDstExtent.height && caps1.maxDstExtent.width == caps2.maxDstExtent.width &&
-           caps1.maxDstExtent.height == caps2.maxDstExtent.height;
-}
-
-inline bool operator==(const VkDisplayPlaneCapabilitiesKHR& caps1, const VkDisplayPlaneCapabilities2KHR& caps2) {
-    return caps1 == caps2.capabilities;
-}
-inline bool operator==(const VkDisplayPlanePropertiesKHR& props1, const VkDisplayPlanePropertiesKHR& props2) {
-    return props1.currentDisplay == props2.currentDisplay && props1.currentStackIndex == props2.currentStackIndex;
-}
-inline bool operator==(const VkDisplayPlanePropertiesKHR& props1, const VkDisplayPlaneProperties2KHR& props2) {
-    return props1 == props2.displayPlaneProperties;
-}
-inline bool operator==(const VkExtent2D& ext1, const VkExtent2D& ext2) {
-    return ext1.height == ext2.height && ext1.width == ext2.width;
-}
-// Allow comparison of vectors of different types as long as their elements are comparable (just has to make sure to only apply when
-// T != U)
-template <typename T, typename U, typename = std::enable_if_t<!std::is_same_v<T, U>>>
-bool operator==(const std::vector<T>& a, const std::vector<U>& b) {
-    return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](const auto& left, const auto& right) { return left == right; });
-}
-
-struct VulkanFunction {
-    std::string name;
-    PFN_vkVoidFunction function = nullptr;
-};
-
-template <typename T, size_t U>
-bool check_permutation(std::initializer_list<const char*> expected, std::array<T, U> const& returned) {
-    if (expected.size() != returned.size()) return false;
-    for (uint32_t i = 0; i < expected.size(); i++) {
-        auto found = std::find_if(std::begin(returned), std::end(returned),
-                                  [&](T elem) { return string_eq(*(expected.begin() + i), elem.layerName); });
-        if (found == std::end(returned)) return false;
-    }
-    return true;
-}
-template <typename T>
-bool check_permutation(std::initializer_list<const char*> expected, std::vector<T> const& returned) {
-    if (expected.size() != returned.size()) return false;
-    for (uint32_t i = 0; i < expected.size(); i++) {
-        auto found = std::find_if(std::begin(returned), std::end(returned),
-                                  [&](T elem) { return string_eq(*(expected.begin() + i), elem.layerName); });
-        if (found == std::end(returned)) return false;
-    }
-    return true;
-}
-
-inline bool contains(std::vector<VkExtensionProperties> const& vec, const char* name) {
-    return std::any_of(std::begin(vec), std::end(vec),
-                       [name](VkExtensionProperties const& elem) { return string_eq(name, elem.extensionName); });
-}
-inline bool contains(std::vector<VkLayerProperties> const& vec, const char* name) {
-    return std::any_of(std::begin(vec), std::end(vec),
-                       [name](VkLayerProperties const& elem) { return string_eq(name, elem.layerName); });
-}
-
-#if defined(__linux__) || defined(__GNU__)
-
-// find application path + name. Path cannot be longer than 1024, returns NULL if it is greater than that.
-inline std::string test_platform_executable_path() {
-    std::string buffer;
-    buffer.resize(1024);
-    ssize_t count = readlink("/proc/self/exe", &buffer[0], buffer.size());
-    if (count == -1) return NULL;
-    if (count == 0) return NULL;
-    buffer[count] = '\0';
-    buffer.resize(count);
-    return buffer;
-}
-#elif defined(__APPLE__)
-#include <libproc.h>
-inline std::string test_platform_executable_path() {
-    std::string buffer;
-    buffer.resize(1024);
-    pid_t pid = getpid();
-    int ret = proc_pidpath(pid, &buffer[0], static_cast<uint32_t>(buffer.size()));
-    if (ret <= 0) return NULL;
-    buffer[ret] = '\0';
-    buffer.resize(ret);
-    return buffer;
-}
-#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
-#include <sys/sysctl.h>
-inline std::string test_platform_executable_path() {
-    int mib[] = {
-        CTL_KERN,
-#if defined(__NetBSD__)
-        KERN_PROC_ARGS,
-        -1,
-        KERN_PROC_PATHNAME,
-#else
-        KERN_PROC,
-        KERN_PROC_PATHNAME,
-        -1,
-#endif
-    };
-    std::string buffer;
-    buffer.resize(1024);
-    size_t size = buffer.size();
-    if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &buffer[0], &size, NULL, 0) < 0) {
-        return NULL;
-    }
-    buffer.resize(size);
-
-    return buffer;
-}
-#elif defined(__Fuchsia__) || defined(__OpenBSD__)
-inline std::string test_platform_executable_path() { return {}; }
-#elif defined(__QNX__)
-
-#ifndef SYSCONFDIR
-#define SYSCONFDIR "/etc"
-#endif
-
-#include <fcntl.h>
-#include <sys/stat.h>
-
-inline std::string test_platform_executable_path() {
-    std::string buffer;
-    buffer.resize(1024);
-    int fd = open("/proc/self/exefile", O_RDONLY);
-    ssize_t rdsize;
-
-    if (fd == -1) {
-        return NULL;
-    }
-
-    rdsize = read(fd, &buffer[0], buffer.size());
-    if (rdsize < 0) {
-        return NULL;
-    }
-    buffer[rdsize] = 0x00;
-    close(fd);
-    buffer.resize(rdsize);
-
-    return buffer;
-}
-#endif  // defined (__QNX__)
-#if defined(WIN32)
-inline std::string test_platform_executable_path() {
-    std::string buffer;
-    buffer.resize(1024);
-    DWORD ret = GetModuleFileName(NULL, static_cast<LPSTR>(&buffer[0]), (DWORD)buffer.size());
-    if (ret == 0) return NULL;
-    if (ret > buffer.size()) return NULL;
-    buffer.resize(ret);
-    buffer[ret] = '\0';
-    return narrow(std::filesystem::path(buffer).native());
-}
-
-#endif
diff --git a/tests/framework/util/CMakeLists.txt b/tests/framework/util/CMakeLists.txt
new file mode 100644
index 0000000..ec263fa
--- /dev/null
+++ b/tests/framework/util/CMakeLists.txt
@@ -0,0 +1,90 @@
+# ~~~
+# Copyright (c) 2021 Valve Corporation
+# Copyright (c) 2021 LunarG, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ~~~
+
+add_library(testing_framework_util STATIC
+    builder_defines.h
+    dispatch_table.cpp
+    dispatch_table.h
+    dispatchable_handle.h
+    dynamic_library_wrapper.cpp
+    dynamic_library_wrapper.h
+    env_var_wrapper.cpp
+    env_var_wrapper.h
+    equality_helpers.cpp
+    equality_helpers.h
+    folder_manager.cpp
+    folder_manager.h
+    functions.h
+    get_executable_path.cpp
+    get_executable_path.h
+    json_writer.cpp
+    json_writer.h
+    manifest_builders.cpp
+    manifest_builders.h
+    platform_wsi.cpp
+    platform_wsi.h
+    test_defines.h
+    vulkan_object_wrappers.cpp
+    vulkan_object_wrappers.h
+    wide_char_handling.cpp
+    wide_char_handling.h
+    )
+target_link_libraries(testing_framework_util PUBLIC loader_common_options Vulkan::Headers gtest)
+
+if(UNIX OR APPLE)
+    target_link_libraries(testing_framework_util PUBLIC ${CMAKE_DL_LIBS})
+endif()
+
+if(UNIX)
+    target_compile_options(testing_framework_util PUBLIC -fPIC)
+endif()
+# Gives access to all headers in this folder, the framework folder, the framework binary folder, and the loader/generated folder
+target_include_directories(testing_framework_util
+    PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/.." "${CMAKE_CURRENT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}")
+
+if (UNIX)
+    if (LOADER_ENABLE_ADDRESS_SANITIZER)
+        target_compile_options(testing_framework_util PUBLIC -fsanitize=address,undefined)
+        target_link_options(testing_framework_util PUBLIC -fsanitize=address,undefined)
+        # workaround regression in macOS SDK 15 when address sanitizer is enabled in debug mode
+        # https://developer.apple.com/forums/thread/774632
+        if (APPLE)
+            target_compile_options(testing_framework_util PRIVATE -mllvm -asan-globals=0)
+        endif()
+    endif()
+    if (LOADER_ENABLE_THREAD_SANITIZER)
+        target_compile_options(testing_framework_util PUBLIC -fsanitize=thread)
+        target_link_options(testing_framework_util PUBLIC -fsanitize=thread)
+        target_compile_options(gtest PUBLIC -fsanitize=thread)
+        target_link_options(gtest PUBLIC -fsanitize=thread)
+    endif()
+endif()
+
+if (MSVC)
+    # silence hidden class member warnings in test framework
+    target_compile_options(testing_framework_util PUBLIC /wd4458)
+    # Make sure exception handling is enabled for the test framework
+    target_compile_options(testing_framework_util PUBLIC /EHsc)
+endif()
+
+# Add a compiler definition for the path to framework_config.h with the correct config
+target_compile_definitions(testing_framework_util PUBLIC FRAMEWORK_CONFIG_HEADER="${FRAMEWORK_CONFIG_HEADER_PATH}")
+
+if (APPLE_STATIC_LOADER)
+    target_compile_definitions(testing_framework_util PUBLIC "APPLE_STATIC_LOADER=1")
+    target_link_libraries(testing_framework_util PRIVATE vulkan)
+endif()
diff --git a/tests/framework/util/builder_defines.h b/tests/framework/util/builder_defines.h
new file mode 100644
index 0000000..c727c81
--- /dev/null
+++ b/tests/framework/util/builder_defines.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#include <vector>
+
+// Macro to ease the definition of variables with builder member functions
+// type = type of the variable
+// name = name of the variable
+// default_value = value to default initialize, use {} if nothing else makes sense
+#define BUILDER_VALUE_WITH_DEFAULT(type, name, default_value) \
+    type name = default_value;                                \
+    auto set_##name(type const& name)->decltype(*this) {      \
+        this->name = name;                                    \
+        return *this;                                         \
+    }
+
+#define BUILDER_VALUE(type, name) BUILDER_VALUE_WITH_DEFAULT(type, name, {})
+
+// Macro to ease the definition of vectors with builder member functions
+// type = type of the variable
+// name = name of the variable
+// singular_name = used for the `add_singular_name` member function
+#define BUILDER_VECTOR(type, name, singular_name)                                          \
+    std::vector<type> name;                                                                \
+    auto add_##singular_name(type const& singular_name)->decltype(*this) {                 \
+        this->name.push_back(singular_name);                                               \
+        return *this;                                                                      \
+    }                                                                                      \
+    auto add_##singular_name##s(std::vector<type> const& singular_name)->decltype(*this) { \
+        for (auto& elem : singular_name) this->name.push_back(elem);                       \
+        return *this;                                                                      \
+    }
+// Like BUILDER_VECTOR but for move only types - where passing in means giving up ownership
+#define BUILDER_VECTOR_MOVE_ONLY(type, name, singular_name)           \
+    std::vector<type> name;                                           \
+    auto add_##singular_name(type&& singular_name)->decltype(*this) { \
+        this->name.push_back(std::move(singular_name));               \
+        return *this;                                                 \
+    }
diff --git a/tests/framework/util/dispatch_table.cpp b/tests/framework/util/dispatch_table.cpp
new file mode 100644
index 0000000..34b9f0d
--- /dev/null
+++ b/tests/framework/util/dispatch_table.cpp
@@ -0,0 +1,175 @@
+// VulkanFunctions - loads vulkan functions for tests to use
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#include "dispatch_table.h"
+
+#include "env_var_wrapper.h"
+
+std::filesystem::path get_loader_path() {
+    auto loader_path = std::filesystem::path(FRAMEWORK_VULKAN_LIBRARY_PATH);
+    auto env_var_res = get_env_var("VK_LOADER_TEST_LOADER_PATH", false);
+    if (!env_var_res.empty()) {
+        loader_path = std::filesystem::path(env_var_res);
+    }
+    return loader_path;
+}
+
+void init_vulkan_functions(VulkanFunctions& funcs) {
+#if defined(APPLE_STATIC_LOADER)
+#define GPA(name) name
+#else
+#define GPA(name) funcs.loader.get_symbol(#name)
+#endif
+
+    // clang-format off
+    funcs.vkGetInstanceProcAddr = GPA(vkGetInstanceProcAddr);
+    funcs.vkEnumerateInstanceExtensionProperties = GPA(vkEnumerateInstanceExtensionProperties);
+    funcs.vkEnumerateInstanceLayerProperties = GPA(vkEnumerateInstanceLayerProperties);
+    funcs.vkEnumerateInstanceVersion = GPA(vkEnumerateInstanceVersion);
+    funcs.vkCreateInstance = GPA(vkCreateInstance);
+    funcs.vkDestroyInstance = GPA(vkDestroyInstance);
+    funcs.vkEnumeratePhysicalDevices = GPA(vkEnumeratePhysicalDevices);
+    funcs.vkEnumeratePhysicalDeviceGroups = GPA(vkEnumeratePhysicalDeviceGroups);
+    funcs.vkGetPhysicalDeviceFeatures = GPA(vkGetPhysicalDeviceFeatures);
+    funcs.vkGetPhysicalDeviceFeatures2 = GPA(vkGetPhysicalDeviceFeatures2);
+    funcs.vkGetPhysicalDeviceFormatProperties = GPA(vkGetPhysicalDeviceFormatProperties);
+    funcs.vkGetPhysicalDeviceFormatProperties2 = GPA(vkGetPhysicalDeviceFormatProperties2);
+    funcs.vkGetPhysicalDeviceImageFormatProperties = GPA(vkGetPhysicalDeviceImageFormatProperties);
+    funcs.vkGetPhysicalDeviceImageFormatProperties2 = GPA(vkGetPhysicalDeviceImageFormatProperties2);
+    funcs.vkGetPhysicalDeviceSparseImageFormatProperties = GPA(vkGetPhysicalDeviceSparseImageFormatProperties);
+    funcs.vkGetPhysicalDeviceSparseImageFormatProperties2 = GPA(vkGetPhysicalDeviceSparseImageFormatProperties2);
+    funcs.vkGetPhysicalDeviceProperties = GPA(vkGetPhysicalDeviceProperties);
+    funcs.vkGetPhysicalDeviceProperties2 = GPA(vkGetPhysicalDeviceProperties2);
+    funcs.vkGetPhysicalDeviceQueueFamilyProperties = GPA(vkGetPhysicalDeviceQueueFamilyProperties);
+    funcs.vkGetPhysicalDeviceQueueFamilyProperties2 = GPA(vkGetPhysicalDeviceQueueFamilyProperties2);
+    funcs.vkGetPhysicalDeviceMemoryProperties = GPA(vkGetPhysicalDeviceMemoryProperties);
+    funcs.vkGetPhysicalDeviceMemoryProperties2 = GPA(vkGetPhysicalDeviceMemoryProperties2);
+    funcs.vkGetPhysicalDeviceSurfaceSupportKHR = GPA(vkGetPhysicalDeviceSurfaceSupportKHR);
+    funcs.vkGetPhysicalDeviceSurfaceFormatsKHR = GPA(vkGetPhysicalDeviceSurfaceFormatsKHR);
+    funcs.vkGetPhysicalDeviceSurfacePresentModesKHR = GPA(vkGetPhysicalDeviceSurfacePresentModesKHR);
+    funcs.vkGetPhysicalDeviceSurfaceCapabilitiesKHR = GPA(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
+    funcs.vkEnumerateDeviceExtensionProperties = GPA(vkEnumerateDeviceExtensionProperties);
+    funcs.vkEnumerateDeviceLayerProperties = GPA(vkEnumerateDeviceLayerProperties);
+    funcs.vkGetPhysicalDeviceExternalBufferProperties = GPA(vkGetPhysicalDeviceExternalBufferProperties);
+    funcs.vkGetPhysicalDeviceExternalFenceProperties = GPA(vkGetPhysicalDeviceExternalFenceProperties);
+    funcs.vkGetPhysicalDeviceExternalSemaphoreProperties = GPA(vkGetPhysicalDeviceExternalSemaphoreProperties);
+
+    funcs.vkDestroySurfaceKHR = GPA(vkDestroySurfaceKHR);
+    funcs.vkGetDeviceProcAddr = GPA(vkGetDeviceProcAddr);
+    funcs.vkCreateDevice = GPA(vkCreateDevice);
+
+    funcs.vkCreateHeadlessSurfaceEXT = GPA(vkCreateHeadlessSurfaceEXT);
+    funcs.vkCreateDisplayPlaneSurfaceKHR = GPA(vkCreateDisplayPlaneSurfaceKHR);
+    funcs.vkGetPhysicalDeviceDisplayPropertiesKHR = GPA(vkGetPhysicalDeviceDisplayPropertiesKHR);
+    funcs.vkGetPhysicalDeviceDisplayPlanePropertiesKHR = GPA(vkGetPhysicalDeviceDisplayPlanePropertiesKHR);
+    funcs.vkGetDisplayPlaneSupportedDisplaysKHR = GPA(vkGetDisplayPlaneSupportedDisplaysKHR);
+    funcs.vkGetDisplayModePropertiesKHR = GPA(vkGetDisplayModePropertiesKHR);
+    funcs.vkCreateDisplayModeKHR = GPA(vkCreateDisplayModeKHR);
+    funcs.vkGetDisplayPlaneCapabilitiesKHR = GPA(vkGetDisplayPlaneCapabilitiesKHR);
+    funcs.vkGetPhysicalDevicePresentRectanglesKHR = GPA(vkGetPhysicalDevicePresentRectanglesKHR);
+    funcs.vkGetPhysicalDeviceDisplayProperties2KHR = GPA(vkGetPhysicalDeviceDisplayProperties2KHR);
+    funcs.vkGetPhysicalDeviceDisplayPlaneProperties2KHR = GPA(vkGetPhysicalDeviceDisplayPlaneProperties2KHR);
+    funcs.vkGetDisplayModeProperties2KHR = GPA(vkGetDisplayModeProperties2KHR);
+    funcs.vkGetDisplayPlaneCapabilities2KHR = GPA(vkGetDisplayPlaneCapabilities2KHR);
+    funcs.vkGetPhysicalDeviceSurfaceCapabilities2KHR = GPA(vkGetPhysicalDeviceSurfaceCapabilities2KHR);
+    funcs.vkGetPhysicalDeviceSurfaceFormats2KHR = GPA(vkGetPhysicalDeviceSurfaceFormats2KHR);
+
+#if defined(VK_USE_PLATFORM_ANDROID_KHR)
+    funcs.vkCreateAndroidSurfaceKHR = GPA(vkCreateAndroidSurfaceKHR);
+#endif  // VK_USE_PLATFORM_ANDROID_KHR
+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    funcs.vkCreateDirectFBSurfaceEXT = GPA(vkCreateDirectFBSurfaceEXT);
+    funcs.vkGetPhysicalDeviceDirectFBPresentationSupportEXT = GPA(vkGetPhysicalDeviceDirectFBPresentationSupportEXT);
+#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    funcs.vkCreateImagePipeSurfaceFUCHSIA = GPA(vkCreateImagePipeSurfaceFUCHSIA);
+#endif  // VK_USE_PLATFORM_FUCHSIA
+#if defined(VK_USE_PLATFORM_GGP)
+    funcs.vkCreateStreamDescriptorSurfaceGGP = GPA(vkCreateStreamDescriptorSurfaceGGP);
+#endif  // VK_USE_PLATFORM_GGP
+#if defined(VK_USE_PLATFORM_IOS_MVK)
+    funcs.vkCreateIOSSurfaceMVK = GPA(vkCreateIOSSurfaceMVK);
+#endif  // VK_USE_PLATFORM_IOS_MVK
+#if defined(VK_USE_PLATFORM_MACOS_MVK)
+    funcs.vkCreateMacOSSurfaceMVK = GPA(vkCreateMacOSSurfaceMVK);
+#endif  // VK_USE_PLATFORM_MACOS_MVK
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    funcs.vkCreateMetalSurfaceEXT = GPA(vkCreateMetalSurfaceEXT);
+#endif  // VK_USE_PLATFORM_METAL_EXT
+#if defined(VK_USE_PLATFORM_SCREEN_QNX)
+    funcs.vkCreateScreenSurfaceQNX = GPA(vkCreateScreenSurfaceQNX);
+    funcs.vkGetPhysicalDeviceScreenPresentationSupportQNX = GPA(vkGetPhysicalDeviceScreenPresentationSupportQNX);
+#endif  // VK_USE_PLATFORM_SCREEN_QNX
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    funcs.vkCreateWaylandSurfaceKHR = GPA(vkCreateWaylandSurfaceKHR);
+    funcs.vkGetPhysicalDeviceWaylandPresentationSupportKHR = GPA(vkGetPhysicalDeviceWaylandPresentationSupportKHR);
+#endif  // VK_USE_PLATFORM_WAYLAND_KHR
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+    funcs.vkCreateXcbSurfaceKHR = GPA(vkCreateXcbSurfaceKHR);
+    funcs.vkGetPhysicalDeviceXcbPresentationSupportKHR = GPA(vkGetPhysicalDeviceXcbPresentationSupportKHR);
+#endif  // VK_USE_PLATFORM_XCB_KHR
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+    funcs.vkCreateXlibSurfaceKHR = GPA(vkCreateXlibSurfaceKHR);
+    funcs.vkGetPhysicalDeviceXlibPresentationSupportKHR = GPA(vkGetPhysicalDeviceXlibPresentationSupportKHR);
+#endif  // VK_USE_PLATFORM_XLIB_KHR
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    funcs.vkCreateWin32SurfaceKHR = GPA(vkCreateWin32SurfaceKHR);
+    funcs.vkGetPhysicalDeviceWin32PresentationSupportKHR = GPA(vkGetPhysicalDeviceWin32PresentationSupportKHR);
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+    funcs.vkDestroyDevice = GPA(vkDestroyDevice);
+    funcs.vkGetDeviceQueue = GPA(vkGetDeviceQueue);
+#undef GPA
+    // clang-format on
+}
+
+#if defined(APPLE_STATIC_LOADER)
+VulkanFunctions::VulkanFunctions() {
+#else
+VulkanFunctions::VulkanFunctions() : loader(get_loader_path()) {
+#endif
+    init_vulkan_functions(*this);
+}
+
+InstanceFunctions::InstanceFunctions(PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr, VkInstance instance) {
+    this->vkGetInstanceProcAddr = vkGetInstanceProcAddr;
+    vkCreateDebugReportCallbackEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"));
+    vkDestroyDebugReportCallbackEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"));
+    vkCreateDebugUtilsMessengerEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"));
+    vkDestroyDebugUtilsMessengerEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT"));
+}
+
+DeviceFunctions::DeviceFunctions(const VulkanFunctions& vulkan_functions, VkDevice device) {
+    vkGetDeviceProcAddr = vulkan_functions.vkGetDeviceProcAddr;
+    vkDestroyDevice = load(device, "vkDestroyDevice");
+    vkGetDeviceQueue = load(device, "vkGetDeviceQueue");
+    vkCreateCommandPool = load(device, "vkCreateCommandPool");
+    vkAllocateCommandBuffers = load(device, "vkAllocateCommandBuffers");
+    vkDestroyCommandPool = load(device, "vkDestroyCommandPool");
+    vkCreateSwapchainKHR = load(device, "vkCreateSwapchainKHR");
+    vkGetSwapchainImagesKHR = load(device, "vkGetSwapchainImagesKHR");
+    vkDestroySwapchainKHR = load(device, "vkDestroySwapchainKHR");
+}
diff --git a/tests/framework/util/dispatch_table.h b/tests/framework/util/dispatch_table.h
new file mode 100644
index 0000000..d614bbd
--- /dev/null
+++ b/tests/framework/util/dispatch_table.h
@@ -0,0 +1,186 @@
+// VulkanFunctions - loads vulkan functions for tests to use
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#include <vulkan/vulkan.h>
+
+#include "functions.h"
+#include "dynamic_library_wrapper.h"
+
+struct VulkanFunctions {
+#if !defined(APPLE_STATIC_LOADER)
+    LibraryWrapper loader;
+#endif
+    // Pre-Instance
+    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = nullptr;
+    PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties = nullptr;
+    PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties = nullptr;
+    PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion = nullptr;
+    PFN_vkCreateInstance vkCreateInstance = nullptr;
+
+    // Instance
+    PFN_vkDestroyInstance vkDestroyInstance = nullptr;
+    PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices = nullptr;
+    PFN_vkEnumeratePhysicalDeviceGroups vkEnumeratePhysicalDeviceGroups = nullptr;
+    PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures = nullptr;
+    PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2 = nullptr;
+    PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties = nullptr;
+    PFN_vkGetPhysicalDeviceFormatProperties2 vkGetPhysicalDeviceFormatProperties2 = nullptr;
+    PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties = nullptr;
+    PFN_vkGetPhysicalDeviceImageFormatProperties2 vkGetPhysicalDeviceImageFormatProperties2 = nullptr;
+    PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties = nullptr;
+    PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 vkGetPhysicalDeviceSparseImageFormatProperties2 = nullptr;
+    PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties = nullptr;
+    PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2 = nullptr;
+    PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties = nullptr;
+    PFN_vkGetPhysicalDeviceQueueFamilyProperties2 vkGetPhysicalDeviceQueueFamilyProperties2 = nullptr;
+    PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties = nullptr;
+    PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2 = nullptr;
+    PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR = nullptr;
+    PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR = nullptr;
+    PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR = nullptr;
+    PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr;
+    PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties = nullptr;
+    PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties = nullptr;
+    PFN_vkGetPhysicalDeviceExternalBufferProperties vkGetPhysicalDeviceExternalBufferProperties = nullptr;
+    PFN_vkGetPhysicalDeviceExternalFenceProperties vkGetPhysicalDeviceExternalFenceProperties = nullptr;
+    PFN_vkGetPhysicalDeviceExternalSemaphoreProperties vkGetPhysicalDeviceExternalSemaphoreProperties = nullptr;
+
+    PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr = nullptr;
+    PFN_vkCreateDevice vkCreateDevice = nullptr;
+
+    // WSI
+    PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT = nullptr;
+    PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR = nullptr;
+    PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR = nullptr;
+    PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR = nullptr;
+    PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR = nullptr;
+    PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR = nullptr;
+    PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR = nullptr;
+    PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR = nullptr;
+    PFN_vkGetPhysicalDevicePresentRectanglesKHR vkGetPhysicalDevicePresentRectanglesKHR = nullptr;
+    PFN_vkGetPhysicalDeviceDisplayProperties2KHR vkGetPhysicalDeviceDisplayProperties2KHR = nullptr;
+    PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR vkGetPhysicalDeviceDisplayPlaneProperties2KHR = nullptr;
+    PFN_vkGetDisplayModeProperties2KHR vkGetDisplayModeProperties2KHR = nullptr;
+    PFN_vkGetDisplayPlaneCapabilities2KHR vkGetDisplayPlaneCapabilities2KHR = nullptr;
+    PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR = nullptr;
+    PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR = nullptr;
+
+#if defined(VK_USE_PLATFORM_ANDROID_KHR)
+    PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR = nullptr;
+#endif  // VK_USE_PLATFORM_ANDROID_KHR
+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    PFN_vkCreateDirectFBSurfaceEXT vkCreateDirectFBSurfaceEXT = nullptr;
+    PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT vkGetPhysicalDeviceDirectFBPresentationSupportEXT = nullptr;
+#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+    PFN_vkCreateImagePipeSurfaceFUCHSIA vkCreateImagePipeSurfaceFUCHSIA = nullptr;
+#endif  // VK_USE_PLATFORM_FUCHSIA
+#if defined(VK_USE_PLATFORM_GGP)
+    PFN_vkCreateStreamDescriptorSurfaceGGP vkCreateStreamDescriptorSurfaceGGP = nullptr;
+#endif  // VK_USE_PLATFORM_GGP
+#if defined(VK_USE_PLATFORM_IOS_MVK)
+    PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK = nullptr;
+#endif  // VK_USE_PLATFORM_IOS_MVK
+#if defined(VK_USE_PLATFORM_MACOS_MVK)
+    PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK = nullptr;
+#endif  // VK_USE_PLATFORM_MACOS_MVK
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT = nullptr;
+#endif  // VK_USE_PLATFORM_METAL_EXT
+#if defined(VK_USE_PLATFORM_SCREEN_QNX)
+    PFN_vkCreateScreenSurfaceQNX vkCreateScreenSurfaceQNX = nullptr;
+    PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX vkGetPhysicalDeviceScreenPresentationSupportQNX = nullptr;
+#endif  // VK_USE_PLATFORM_SCREEN_QNX
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR = nullptr;
+    PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR = nullptr;
+#endif  // VK_USE_PLATFORM_WAYLAND_KHR
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+    PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR = nullptr;
+    PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR = nullptr;
+#endif  // VK_USE_PLATFORM_XCB_KHR
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+    PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR = nullptr;
+    PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR = nullptr;
+#endif  // VK_USE_PLATFORM_XLIB_KHR
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR = nullptr;
+    PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR = nullptr;
+#endif  // VK_USE_PLATFORM_WIN32_KHR
+    PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR = nullptr;
+
+    // device functions
+    PFN_vkDestroyDevice vkDestroyDevice = nullptr;
+    PFN_vkGetDeviceQueue vkGetDeviceQueue = nullptr;
+
+    VulkanFunctions();
+
+    FromVoidStarFunc load(VkInstance inst, const char* func_name) const {
+        return FromVoidStarFunc(vkGetInstanceProcAddr(inst, func_name));
+    }
+
+    FromVoidStarFunc load(VkDevice device, const char* func_name) const {
+        return FromVoidStarFunc(vkGetDeviceProcAddr(device, func_name));
+    }
+};
+
+struct InstanceFunctions {
+    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+
+    PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
+    PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
+    PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT;
+    PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT;
+
+    InstanceFunctions() = default;
+    InstanceFunctions(PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr, VkInstance instance);
+
+    FromVoidStarFunc load(VkInstance instance, const char* func_name) const {
+        return FromVoidStarFunc(vkGetInstanceProcAddr(instance, func_name));
+    }
+};
+
+struct DeviceFunctions {
+    PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr = nullptr;
+    PFN_vkDestroyDevice vkDestroyDevice = nullptr;
+    PFN_vkGetDeviceQueue vkGetDeviceQueue = nullptr;
+    PFN_vkCreateCommandPool vkCreateCommandPool = nullptr;
+    PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers = nullptr;
+    PFN_vkDestroyCommandPool vkDestroyCommandPool = nullptr;
+    PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR = nullptr;
+    PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR = nullptr;
+    PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR = nullptr;
+
+    DeviceFunctions() = default;
+    DeviceFunctions(const VulkanFunctions& vulkan_functions, VkDevice device);
+
+    FromVoidStarFunc load(VkDevice device, const char* func_name) const {
+        return FromVoidStarFunc(vkGetDeviceProcAddr(device, func_name));
+    }
+};
diff --git a/tests/framework/util/dispatchable_handle.h b/tests/framework/util/dispatchable_handle.h
new file mode 100644
index 0000000..98085bb
--- /dev/null
+++ b/tests/framework/util/dispatchable_handle.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#include <vulkan/vk_icd.h>
+
+#include "test_defines.h"
+
+template <typename T>
+struct FRAMEWORK_EXPORT DispatchableHandle {
+    DispatchableHandle() {
+        auto ptr_handle = new VK_LOADER_DATA;
+        set_loader_magic_value(ptr_handle);
+        handle = reinterpret_cast<T>(ptr_handle);
+    }
+    ~DispatchableHandle() {
+        if (handle) {
+            delete reinterpret_cast<VK_LOADER_DATA*>(handle);
+        }
+        handle = nullptr;
+    }
+    DispatchableHandle(DispatchableHandle const&) = delete;
+    DispatchableHandle& operator=(DispatchableHandle const&) = delete;
+    DispatchableHandle(DispatchableHandle&& other) noexcept : handle(other.handle) { other.handle = nullptr; }
+    DispatchableHandle& operator=(DispatchableHandle&& other) noexcept {
+        if (handle) {
+            delete reinterpret_cast<VK_LOADER_DATA*>(handle);
+        }
+        handle = other.handle;
+        other.handle = nullptr;
+        return *this;
+    }
+    bool operator==(T base_handle) { return base_handle == handle; }
+    bool operator!=(T base_handle) { return base_handle != handle; }
+
+    T handle = nullptr;
+};
diff --git a/tests/framework/util/dynamic_library_wrapper.cpp b/tests/framework/util/dynamic_library_wrapper.cpp
new file mode 100644
index 0000000..e868d16
--- /dev/null
+++ b/tests/framework/util/dynamic_library_wrapper.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#include "dynamic_library_wrapper.h"
+
+#include "test_defines.h"
+#include "env_var_wrapper.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <iostream>
+
+namespace detail {
+
+#if defined(_WIN32)
+typedef HMODULE test_platform_dl_handle;
+
+std::string error_code_to_string(DWORD error_code) {
+    LPSTR lpMsgBuf{};
+    size_t MsgBufSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+                                      nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lpMsgBuf, 0, nullptr);
+    std::string code_str(lpMsgBuf, MsgBufSize);
+    LocalFree(lpMsgBuf);
+    return code_str;
+}
+std::wstring wide_error_code_to_string(DWORD error_code) {
+    LPWSTR lpwMsgBuf{};
+    size_t MsgBufSize = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+                                       nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lpwMsgBuf, 0, nullptr);
+    std::wstring code_str(lpwMsgBuf, MsgBufSize);
+    LocalFree(lpwMsgBuf);
+    return code_str;
+}
+#elif TESTING_COMMON_UNIX_PLATFORMS
+#include <dlfcn.h>
+
+typedef void* test_platform_dl_handle;
+#endif
+}  // namespace detail
+
+LibraryWrapper::LibraryWrapper() noexcept {}
+LibraryWrapper::LibraryWrapper(std::filesystem::path const& lib_path) noexcept : lib_path(lib_path.lexically_normal()) {
+#if defined(_WIN32)
+    auto wide_path = lib_path.native();  // Get a std::wstring first
+    // Try loading the library the original way first.
+    lib_handle = LoadLibraryW(wide_path.c_str());
+    DWORD last_error = GetLastError();
+    // If that failed because of path limitations, prepend a special sequence to opt into longer path support
+    if (lib_handle == nullptr && last_error == ERROR_FILENAME_EXCED_RANGE) {
+        // "\\?\" is a special prefix for filenames that tells winapi to ignore path limits, so we can workaround path limitations
+        // without relying on system level changes.
+        wide_path = L"\\\\?\\" + wide_path;
+        last_error = 0;
+        lib_handle = LoadLibraryW(wide_path.c_str());
+        last_error = GetLastError();
+    }
+    // If that failed, then try loading it with broader search folders.
+    if (lib_handle == nullptr && last_error == ERROR_MOD_NOT_FOUND) {
+        last_error = 0;
+        lib_handle =
+            LoadLibraryExW(wide_path.c_str(), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
+        last_error = GetLastError();
+    }
+    // If neither of the above worked, print an error message and abort
+    if (lib_handle == nullptr) {
+        auto error_msg = detail::wide_error_code_to_string(last_error);
+        std::wcerr << L"Unable to open library: " << wide_path << L" due to: " << error_msg << L"\n";
+        abort();
+    }
+#elif TESTING_COMMON_UNIX_PLATFORMS
+    lib_handle = dlopen(lib_path.string().c_str(), RTLD_LAZY | RTLD_LOCAL);
+    if (lib_handle == nullptr) {
+        std::wcerr << "Unable to open library: " << lib_path << " due to: " << dlerror() << "\n";
+        abort();
+    }
+#else
+#error "Unhandled platform in dynamic_library_wrapper.cpp!"
+#endif
+}
+
+LibraryWrapper::~LibraryWrapper() noexcept { close_library(); }
+
+LibraryWrapper::LibraryWrapper(LibraryWrapper&& wrapper) noexcept : lib_handle(wrapper.lib_handle), lib_path(wrapper.lib_path) {
+    wrapper.lib_handle = nullptr;
+}
+LibraryWrapper& LibraryWrapper::operator=(LibraryWrapper&& wrapper) noexcept {
+    if (this != &wrapper) {
+        lib_handle = wrapper.lib_handle;
+        lib_path = wrapper.lib_path;
+        wrapper.lib_handle = nullptr;
+    }
+    return *this;
+}
+
+void LibraryWrapper::close_library() noexcept {
+    auto loader_disable_dynamic_library_unloading_env_var = get_env_var("VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING", false);
+    if (loader_disable_dynamic_library_unloading_env_var.empty() || loader_disable_dynamic_library_unloading_env_var != "1") {
+        if (lib_handle != nullptr) {
+#if defined(_WIN32)
+            FreeLibrary(lib_handle);
+#elif TESTING_COMMON_UNIX_PLATFORMS
+            dlclose(lib_handle);
+#else
+#error "Unhandled platform in dynamic_library_wrapper.cpp!"
+#endif
+            lib_handle = nullptr;
+        }
+    }
+}
+
+FromVoidStarFunc LibraryWrapper::get_symbol(const char* symbol_name) const {
+    if (symbol_name == nullptr) {
+        std::cerr << "LibraryWrapper::get_symbol called with a null symbol_name!\n";
+        abort();
+    }
+    if (lib_handle == nullptr) {
+        std::cerr << "LibraryWrapper::get_symbol called when lib_handle is nullptr!\n";
+        abort();
+    }
+
+#if defined(_WIN32)
+    void* symbol = reinterpret_cast<void*>(GetProcAddress(lib_handle, symbol_name));
+    if (symbol == nullptr) {
+        auto last_error = detail::error_code_to_string(GetLastError());
+        std::cerr << "Unable to get symbol " << symbol_name << " in library " << lib_path.string() << " with to error code "
+                  << last_error << "\n";
+        abort();
+    }
+#elif TESTING_COMMON_UNIX_PLATFORMS
+    void* symbol = dlsym(lib_handle, symbol_name);
+    if (symbol == nullptr) {
+        std::cerr << "Unable to get symbol " << symbol_name << " in library " << lib_path.string() << " due to " << dlerror()
+                  << "\n";
+        abort();
+    }
+#else
+#error "Unhandled platform in dynamic_library_wrapper.cpp!"
+#endif
+    return FromVoidStarFunc(symbol);
+}
diff --git a/tests/framework/util/dynamic_library_wrapper.h b/tests/framework/util/dynamic_library_wrapper.h
new file mode 100644
index 0000000..35b72ad
--- /dev/null
+++ b/tests/framework/util/dynamic_library_wrapper.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#include <filesystem>
+
+#include "test_defines.h"
+
+#include "functions.h"
+
+#if defined(_WIN32)
+#include <direct.h>
+#include <windows.h>
+#include <strsafe.h>
+#elif TESTING_COMMON_UNIX_PLATFORMS
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#endif
+
+struct LibraryWrapper {
+    explicit LibraryWrapper() noexcept;
+    explicit LibraryWrapper(std::filesystem::path const& lib_path) noexcept;
+    ~LibraryWrapper() noexcept;
+    LibraryWrapper(LibraryWrapper const& wrapper) = delete;
+    LibraryWrapper& operator=(LibraryWrapper const& wrapper) = delete;
+    LibraryWrapper(LibraryWrapper&& wrapper) noexcept;
+    LibraryWrapper& operator=(LibraryWrapper&& wrapper) noexcept;
+    FromVoidStarFunc get_symbol(const char* symbol_name) const;
+
+    std::filesystem::path const& get_path() const { return lib_path; }
+    explicit operator bool() const noexcept { return lib_handle != nullptr; }
+
+   private:
+    void close_library() noexcept;
+
+#if defined(_WIN32)
+    HMODULE lib_handle = nullptr;
+#elif TESTING_COMMON_UNIX_PLATFORMS
+    void* lib_handle = nullptr;
+#else
+#error "Unhandled platform in dynamic_library_wrapper.h!"
+#endif
+    std::filesystem::path lib_path;
+};
diff --git a/tests/framework/util/env_var_wrapper.cpp b/tests/framework/util/env_var_wrapper.cpp
new file mode 100644
index 0000000..f9df389
--- /dev/null
+++ b/tests/framework/util/env_var_wrapper.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#include "env_var_wrapper.h"
+
+#include <stdlib.h>
+
+#include <iostream>
+
+#include "wide_char_handling.h"
+
+// NOTE: get_env_var() are only intended for test framework code, all test code MUST use
+// EnvVarWrapper
+
+#if defined(_WIN32)
+#include <Windows.h>
+#include <wchar.h>
+#include <strsafe.h>
+
+// Windows specific error handling logic
+const long ERROR_SETENV_FAILED = 10543;           // chosen at random, attempts to not conflict
+const long ERROR_REMOVEDIRECTORY_FAILED = 10544;  // chosen at random, attempts to not conflict
+const char* win_api_error_str(LSTATUS status) {
+    if (status == ERROR_INVALID_FUNCTION) return "ERROR_INVALID_FUNCTION";
+    if (status == ERROR_FILE_NOT_FOUND) return "ERROR_FILE_NOT_FOUND";
+    if (status == ERROR_PATH_NOT_FOUND) return "ERROR_PATH_NOT_FOUND";
+    if (status == ERROR_TOO_MANY_OPEN_FILES) return "ERROR_TOO_MANY_OPEN_FILES";
+    if (status == ERROR_ACCESS_DENIED) return "ERROR_ACCESS_DENIED";
+    if (status == ERROR_INVALID_HANDLE) return "ERROR_INVALID_HANDLE";
+    if (status == ERROR_ENVVAR_NOT_FOUND) return "ERROR_ENVVAR_NOT_FOUND";
+    if (status == ERROR_SETENV_FAILED) return "ERROR_SETENV_FAILED";
+    return "UNKNOWN ERROR";
+}
+std::string error_code_to_string(DWORD error_code) {
+    LPSTR lpMsgBuf{};
+    size_t MsgBufSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+                                      nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lpMsgBuf, 0, nullptr);
+    std::string code_str(lpMsgBuf, MsgBufSize);
+    LocalFree(lpMsgBuf);
+    return code_str;
+}
+
+void print_error_message(LSTATUS status, const char* function_name, std::string optional_message = "") {
+    DWORD dw = GetLastError();
+
+    std::cerr << function_name << " failed with " << win_api_error_str(status) << ": " << error_code_to_string(dw);
+    if (optional_message != "") {
+        std::cerr << " | " << optional_message;
+    }
+    std::cerr << "\n";
+}
+
+// get_env_var() - returns a std::string of `name`. if report_failure is true, then it will log to stderr that it didn't find the
+//     env-var
+std::string get_env_var(std::string const& name, bool report_failure) {
+    std::wstring name_utf16 = widen(name);
+    DWORD value_size = GetEnvironmentVariableW(name_utf16.c_str(), nullptr, 0);
+    if (0 == value_size) {
+        if (report_failure) print_error_message(ERROR_ENVVAR_NOT_FOUND, "GetEnvironmentVariableW");
+        return {};
+    }
+    std::wstring value(value_size, L'\0');
+    if (GetEnvironmentVariableW(name_utf16.c_str(), &value[0], value_size) != value_size - 1) {
+        return {};
+    }
+    return narrow(value);
+}
+#elif TESTING_COMMON_UNIX_PLATFORMS
+
+// get_env_var() - returns a std::string of `name`. if report_failure is true, then it will log to stderr that it didn't find the
+//     env-var
+std::string get_env_var(std::string const& name, bool report_failure) {
+    char* ret = getenv(name.c_str());
+    if (ret == nullptr) {
+        if (report_failure) std::cerr << "Failed to get environment variable:" << name << "\n";
+        return std::string();
+    }
+    return ret;
+}
+#endif
+
+std::vector<std::string> split_env_var_as_list(std::string const& env_var_contents) {
+    std::vector<std::string> items;
+    size_t start = 0;
+    size_t len = 0;
+    for (size_t i = 0; i < env_var_contents.size(); i++) {
+        if (env_var_contents[i] == OS_ENV_VAR_LIST_SEPARATOR) {
+            if (len != 0) {
+                // only push back non empty strings
+                items.push_back(env_var_contents.substr(start, len));
+            }
+            start = i + 1;
+            len = 0;
+        } else {
+            len++;
+        }
+    }
+    items.push_back(env_var_contents.substr(start, len));
+    return items;
+}
+
+/*
+ * Wrapper around Environment Variables with common operations
+ * Since Environment Variables leak between tests, there needs to be RAII code to remove them during test cleanup
+
+ */
+
+EnvVarWrapper::EnvVarWrapper(std::string const& name) noexcept : name(name) {
+    initial_value = get_env_var(name, false);
+    remove_env_var();
+}
+EnvVarWrapper::EnvVarWrapper(std::string const& name, std::string const& value) noexcept : name(name), cur_value(value) {
+    initial_value = get_env_var(name, false);
+    set_env_var();
+}
+EnvVarWrapper::~EnvVarWrapper() noexcept {
+    remove_env_var();
+    if (!initial_value.empty()) {
+        set_new_value(initial_value);
+    }
+}
+
+void EnvVarWrapper::set_new_value(std::string const& value) {
+    cur_value = value;
+    set_env_var();
+}
+void EnvVarWrapper::add_to_list(std::string const& list_item) {
+    if (!cur_value.empty()) {
+        cur_value += OS_ENV_VAR_LIST_SEPARATOR;
+    }
+    cur_value += list_item;
+    set_env_var();
+}
+#if defined(_WIN32)
+void EnvVarWrapper::add_to_list(std::wstring const& list_item) {
+    if (!cur_value.empty()) {
+        cur_value += OS_ENV_VAR_LIST_SEPARATOR;
+    }
+    cur_value += narrow(list_item);
+    set_env_var();
+}
+#endif
+void EnvVarWrapper::remove_value() const { remove_env_var(); }
+const char* EnvVarWrapper::get() const { return name.c_str(); }
+const char* EnvVarWrapper::value() const { return cur_value.c_str(); }
+
+#if defined(_WIN32)
+
+void EnvVarWrapper::set_env_var() const {
+    BOOL ret = SetEnvironmentVariableW(widen(name).c_str(), widen(cur_value).c_str());
+    if (ret == 0) {
+        print_error_message(ERROR_SETENV_FAILED, "SetEnvironmentVariableW");
+    }
+}
+void EnvVarWrapper::remove_env_var() const { SetEnvironmentVariableW(widen(name).c_str(), nullptr); }
+
+#elif TESTING_COMMON_UNIX_PLATFORMS
+
+void EnvVarWrapper::set_env_var() const { setenv(name.c_str(), cur_value.c_str(), 1); }
+void EnvVarWrapper::remove_env_var() const { unsetenv(name.c_str()); }
+#endif
diff --git a/tests/framework/util/env_var_wrapper.h b/tests/framework/util/env_var_wrapper.h
new file mode 100644
index 0000000..2a0ecca
--- /dev/null
+++ b/tests/framework/util/env_var_wrapper.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "test_defines.h"
+
+// Environment variable list separator - not for filesystem paths
+#if defined(_WIN32)
+static const char OS_ENV_VAR_LIST_SEPARATOR = ';';
+#elif TESTING_COMMON_UNIX_PLATFORMS
+static const char OS_ENV_VAR_LIST_SEPARATOR = ':';
+#else
+#error "Unhandled platform in env_var_wrapper.h!"
+#endif
+
+// get_env_var() - returns the contents of env-var `name` as a std::string
+// If report_failure is true, then it will log to stderr that it didn't find the env-var
+std::string get_env_var(std::string const& name, bool report_failure = true);
+
+// split_env_var_as_list() - split env_var_contents into separate elements using the platform
+// specific env-var list separator.
+std::vector<std::string> split_env_var_as_list(std::string const& env_var_contents);
+
+/*
+ * Wrapper around Environment Variables with common operations
+ * Since Environment Variables leak between tests, there needs to be RAII code to remove them during test cleanup
+
+ */
+
+// Wrapper to set & remove env-vars automatically
+struct EnvVarWrapper {
+    // Constructor which unsets the env-var
+    EnvVarWrapper(std::string const& name) noexcept;
+    // Constructor which set the env-var to the specified value
+    EnvVarWrapper(std::string const& name, std::string const& value) noexcept;
+    ~EnvVarWrapper() noexcept;
+
+    // delete copy operators
+    EnvVarWrapper(const EnvVarWrapper&) = delete;
+    EnvVarWrapper& operator=(const EnvVarWrapper&) = delete;
+
+    void set_new_value(std::string const& value);
+    void add_to_list(std::string const& list_item);
+#if defined(_WIN32)
+    void add_to_list(std::wstring const& list_item);
+#endif
+    void remove_value() const;
+    const char* get() const;
+    const char* value() const;
+
+   private:
+    std::string name;
+    std::string cur_value;
+    std::string initial_value;
+
+    void set_env_var() const;
+    void remove_env_var() const;
+};
diff --git a/tests/framework/util/equality_helpers.cpp b/tests/framework/util/equality_helpers.cpp
new file mode 100644
index 0000000..4a98599
--- /dev/null
+++ b/tests/framework/util/equality_helpers.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#include "equality_helpers.h"
+
+bool operator==(const VkExtent3D& a, const VkExtent3D& b) {
+    return a.width == b.width && a.height == b.height && a.depth == b.depth;
+}
+bool operator!=(const VkExtent3D& a, const VkExtent3D& b) { return !(a == b); }
+
+bool operator==(const VkQueueFamilyProperties& a, const VkQueueFamilyProperties& b) {
+    return a.minImageTransferGranularity == b.minImageTransferGranularity && a.queueCount == b.queueCount &&
+           a.queueFlags == b.queueFlags && a.timestampValidBits == b.timestampValidBits;
+}
+bool operator!=(const VkQueueFamilyProperties& a, const VkQueueFamilyProperties& b) { return !(a == b); }
+
+bool operator==(const VkQueueFamilyProperties& a, const VkQueueFamilyProperties2& b) { return a == b.queueFamilyProperties; }
+bool operator!=(const VkQueueFamilyProperties& a, const VkQueueFamilyProperties2& b) { return a != b.queueFamilyProperties; }
+
+bool operator==(const VkLayerProperties& a, const VkLayerProperties& b) {
+    return string_eq(a.layerName, b.layerName, 256) && string_eq(a.description, b.description, 256) &&
+           a.implementationVersion == b.implementationVersion && a.specVersion == b.specVersion;
+}
+bool operator!=(const VkLayerProperties& a, const VkLayerProperties& b) { return !(a == b); }
+
+bool operator==(const VkExtensionProperties& a, const VkExtensionProperties& b) {
+    return string_eq(a.extensionName, b.extensionName, 256) && a.specVersion == b.specVersion;
+}
+bool operator!=(const VkExtensionProperties& a, const VkExtensionProperties& b) { return !(a == b); }
+
+bool operator==(const VkPhysicalDeviceFeatures& feats1, const VkPhysicalDeviceFeatures2& feats2) {
+    return feats1.robustBufferAccess == feats2.features.robustBufferAccess &&
+           feats1.fullDrawIndexUint32 == feats2.features.fullDrawIndexUint32 &&
+           feats1.imageCubeArray == feats2.features.imageCubeArray && feats1.independentBlend == feats2.features.independentBlend &&
+           feats1.geometryShader == feats2.features.geometryShader &&
+           feats1.tessellationShader == feats2.features.tessellationShader &&
+           feats1.sampleRateShading == feats2.features.sampleRateShading && feats1.dualSrcBlend == feats2.features.dualSrcBlend &&
+           feats1.logicOp == feats2.features.logicOp && feats1.multiDrawIndirect == feats2.features.multiDrawIndirect &&
+           feats1.drawIndirectFirstInstance == feats2.features.drawIndirectFirstInstance &&
+           feats1.depthClamp == feats2.features.depthClamp && feats1.depthBiasClamp == feats2.features.depthBiasClamp &&
+           feats1.fillModeNonSolid == feats2.features.fillModeNonSolid && feats1.depthBounds == feats2.features.depthBounds &&
+           feats1.wideLines == feats2.features.wideLines && feats1.largePoints == feats2.features.largePoints &&
+           feats1.alphaToOne == feats2.features.alphaToOne && feats1.multiViewport == feats2.features.multiViewport &&
+           feats1.samplerAnisotropy == feats2.features.samplerAnisotropy &&
+           feats1.textureCompressionETC2 == feats2.features.textureCompressionETC2 &&
+           feats1.textureCompressionASTC_LDR == feats2.features.textureCompressionASTC_LDR &&
+           feats1.textureCompressionBC == feats2.features.textureCompressionBC &&
+           feats1.occlusionQueryPrecise == feats2.features.occlusionQueryPrecise &&
+           feats1.pipelineStatisticsQuery == feats2.features.pipelineStatisticsQuery &&
+           feats1.vertexPipelineStoresAndAtomics == feats2.features.vertexPipelineStoresAndAtomics &&
+           feats1.fragmentStoresAndAtomics == feats2.features.fragmentStoresAndAtomics &&
+           feats1.shaderTessellationAndGeometryPointSize == feats2.features.shaderTessellationAndGeometryPointSize &&
+           feats1.shaderImageGatherExtended == feats2.features.shaderImageGatherExtended &&
+           feats1.shaderStorageImageExtendedFormats == feats2.features.shaderStorageImageExtendedFormats &&
+           feats1.shaderStorageImageMultisample == feats2.features.shaderStorageImageMultisample &&
+           feats1.shaderStorageImageReadWithoutFormat == feats2.features.shaderStorageImageReadWithoutFormat &&
+           feats1.shaderStorageImageWriteWithoutFormat == feats2.features.shaderStorageImageWriteWithoutFormat &&
+           feats1.shaderUniformBufferArrayDynamicIndexing == feats2.features.shaderUniformBufferArrayDynamicIndexing &&
+           feats1.shaderSampledImageArrayDynamicIndexing == feats2.features.shaderSampledImageArrayDynamicIndexing &&
+           feats1.shaderStorageBufferArrayDynamicIndexing == feats2.features.shaderStorageBufferArrayDynamicIndexing &&
+           feats1.shaderStorageImageArrayDynamicIndexing == feats2.features.shaderStorageImageArrayDynamicIndexing &&
+           feats1.shaderClipDistance == feats2.features.shaderClipDistance &&
+           feats1.shaderCullDistance == feats2.features.shaderCullDistance &&
+           feats1.shaderFloat64 == feats2.features.shaderFloat64 && feats1.shaderInt64 == feats2.features.shaderInt64 &&
+           feats1.shaderInt16 == feats2.features.shaderInt16 &&
+           feats1.shaderResourceResidency == feats2.features.shaderResourceResidency &&
+           feats1.shaderResourceMinLod == feats2.features.shaderResourceMinLod &&
+           feats1.sparseBinding == feats2.features.sparseBinding &&
+           feats1.sparseResidencyBuffer == feats2.features.sparseResidencyBuffer &&
+           feats1.sparseResidencyImage2D == feats2.features.sparseResidencyImage2D &&
+           feats1.sparseResidencyImage3D == feats2.features.sparseResidencyImage3D &&
+           feats1.sparseResidency2Samples == feats2.features.sparseResidency2Samples &&
+           feats1.sparseResidency4Samples == feats2.features.sparseResidency4Samples &&
+           feats1.sparseResidency8Samples == feats2.features.sparseResidency8Samples &&
+           feats1.sparseResidency16Samples == feats2.features.sparseResidency16Samples &&
+           feats1.sparseResidencyAliased == feats2.features.sparseResidencyAliased &&
+           feats1.variableMultisampleRate == feats2.features.variableMultisampleRate &&
+           feats1.inheritedQueries == feats2.features.inheritedQueries;
+}
+
+bool operator==(const VkPhysicalDeviceMemoryProperties& props1, const VkPhysicalDeviceMemoryProperties2& props2) {
+    bool equal = true;
+    equal = equal && props1.memoryTypeCount == props2.memoryProperties.memoryTypeCount;
+    equal = equal && props1.memoryHeapCount == props2.memoryProperties.memoryHeapCount;
+    for (uint32_t i = 0; i < props1.memoryHeapCount; ++i) {
+        equal = equal && props1.memoryHeaps[i].size == props2.memoryProperties.memoryHeaps[i].size;
+        equal = equal && props1.memoryHeaps[i].flags == props2.memoryProperties.memoryHeaps[i].flags;
+    }
+    for (uint32_t i = 0; i < props1.memoryTypeCount; ++i) {
+        equal = equal && props1.memoryTypes[i].propertyFlags == props2.memoryProperties.memoryTypes[i].propertyFlags;
+        equal = equal && props1.memoryTypes[i].heapIndex == props2.memoryProperties.memoryTypes[i].heapIndex;
+    }
+    return equal;
+}
+bool operator==(const VkSparseImageFormatProperties& props1, const VkSparseImageFormatProperties& props2) {
+    return props1.aspectMask == props2.aspectMask && props1.imageGranularity.width == props2.imageGranularity.width &&
+           props1.imageGranularity.height == props2.imageGranularity.height &&
+           props1.imageGranularity.depth == props2.imageGranularity.depth && props1.flags == props2.flags;
+}
+bool operator==(const VkSparseImageFormatProperties& props1, const VkSparseImageFormatProperties2& props2) {
+    return props1 == props2.properties;
+}
+bool operator==(const VkExternalMemoryProperties& props1, const VkExternalMemoryProperties& props2) {
+    return props1.externalMemoryFeatures == props2.externalMemoryFeatures &&
+           props1.exportFromImportedHandleTypes == props2.exportFromImportedHandleTypes &&
+           props1.compatibleHandleTypes == props2.compatibleHandleTypes;
+}
+bool operator==(const VkExternalSemaphoreProperties& props1, const VkExternalSemaphoreProperties& props2) {
+    return props1.externalSemaphoreFeatures == props2.externalSemaphoreFeatures &&
+           props1.exportFromImportedHandleTypes == props2.exportFromImportedHandleTypes &&
+           props1.compatibleHandleTypes == props2.compatibleHandleTypes;
+}
+bool operator==(const VkExternalFenceProperties& props1, const VkExternalFenceProperties& props2) {
+    return props1.externalFenceFeatures == props2.externalFenceFeatures &&
+           props1.exportFromImportedHandleTypes == props2.exportFromImportedHandleTypes &&
+           props1.compatibleHandleTypes == props2.compatibleHandleTypes;
+}
+bool operator==(const VkSurfaceCapabilitiesKHR& props1, const VkSurfaceCapabilitiesKHR& props2) {
+    return props1.minImageCount == props2.minImageCount && props1.maxImageCount == props2.maxImageCount &&
+           props1.currentExtent.width == props2.currentExtent.width && props1.currentExtent.height == props2.currentExtent.height &&
+           props1.minImageExtent.width == props2.minImageExtent.width &&
+           props1.minImageExtent.height == props2.minImageExtent.height &&
+           props1.maxImageExtent.width == props2.maxImageExtent.width &&
+           props1.maxImageExtent.height == props2.maxImageExtent.height &&
+           props1.maxImageArrayLayers == props2.maxImageArrayLayers && props1.supportedTransforms == props2.supportedTransforms &&
+           props1.currentTransform == props2.currentTransform && props1.supportedCompositeAlpha == props2.supportedCompositeAlpha &&
+           props1.supportedUsageFlags == props2.supportedUsageFlags;
+}
+bool operator==(const VkSurfacePresentScalingCapabilitiesEXT& caps1, const VkSurfacePresentScalingCapabilitiesEXT& caps2) {
+    return caps1.supportedPresentScaling == caps2.supportedPresentScaling &&
+           caps1.supportedPresentGravityX == caps2.supportedPresentGravityX &&
+           caps1.supportedPresentGravityY == caps2.supportedPresentGravityY &&
+           caps1.minScaledImageExtent.width == caps2.minScaledImageExtent.width &&
+           caps1.minScaledImageExtent.height == caps2.minScaledImageExtent.height &&
+           caps1.maxScaledImageExtent.width == caps2.maxScaledImageExtent.width &&
+           caps1.maxScaledImageExtent.height == caps2.maxScaledImageExtent.height;
+}
+bool operator==(const VkSurfaceFormatKHR& format1, const VkSurfaceFormatKHR& format2) {
+    return format1.format == format2.format && format1.colorSpace == format2.colorSpace;
+}
+bool operator==(const VkSurfaceFormatKHR& format1, const VkSurfaceFormat2KHR& format2) { return format1 == format2.surfaceFormat; }
+bool operator==(const VkDisplayPropertiesKHR& props1, const VkDisplayPropertiesKHR& props2) {
+    return props1.display == props2.display && props1.physicalDimensions.width == props2.physicalDimensions.width &&
+           props1.physicalDimensions.height == props2.physicalDimensions.height &&
+           props1.physicalResolution.width == props2.physicalResolution.width &&
+           props1.physicalResolution.height == props2.physicalResolution.height &&
+           props1.supportedTransforms == props2.supportedTransforms && props1.planeReorderPossible == props2.planeReorderPossible &&
+           props1.persistentContent == props2.persistentContent;
+}
+bool operator==(const VkDisplayPropertiesKHR& props1, const VkDisplayProperties2KHR& props2) {
+    return props1 == props2.displayProperties;
+}
+bool operator==(const VkDisplayModePropertiesKHR& disp1, const VkDisplayModePropertiesKHR& disp2) {
+    return disp1.displayMode == disp2.displayMode && disp1.parameters.visibleRegion.width == disp2.parameters.visibleRegion.width &&
+           disp1.parameters.visibleRegion.height == disp2.parameters.visibleRegion.height &&
+           disp1.parameters.refreshRate == disp2.parameters.refreshRate;
+}
+
+bool operator==(const VkDisplayModePropertiesKHR& disp1, const VkDisplayModeProperties2KHR& disp2) {
+    return disp1 == disp2.displayModeProperties;
+}
+bool operator==(const VkDisplayPlaneCapabilitiesKHR& caps1, const VkDisplayPlaneCapabilitiesKHR& caps2) {
+    return caps1.supportedAlpha == caps2.supportedAlpha && caps1.minSrcPosition.x == caps2.minSrcPosition.x &&
+           caps1.minSrcPosition.y == caps2.minSrcPosition.y && caps1.maxSrcPosition.x == caps2.maxSrcPosition.x &&
+           caps1.maxSrcPosition.y == caps2.maxSrcPosition.y && caps1.minSrcExtent.width == caps2.minSrcExtent.width &&
+           caps1.minSrcExtent.height == caps2.minSrcExtent.height && caps1.maxSrcExtent.width == caps2.maxSrcExtent.width &&
+           caps1.maxSrcExtent.height == caps2.maxSrcExtent.height && caps1.minDstPosition.x == caps2.minDstPosition.x &&
+           caps1.minDstPosition.y == caps2.minDstPosition.y && caps1.maxDstPosition.x == caps2.maxDstPosition.x &&
+           caps1.maxDstPosition.y == caps2.maxDstPosition.y && caps1.minDstExtent.width == caps2.minDstExtent.width &&
+           caps1.minDstExtent.height == caps2.minDstExtent.height && caps1.maxDstExtent.width == caps2.maxDstExtent.width &&
+           caps1.maxDstExtent.height == caps2.maxDstExtent.height;
+}
+
+bool operator==(const VkDisplayPlaneCapabilitiesKHR& caps1, const VkDisplayPlaneCapabilities2KHR& caps2) {
+    return caps1 == caps2.capabilities;
+}
+bool operator==(const VkDisplayPlanePropertiesKHR& props1, const VkDisplayPlanePropertiesKHR& props2) {
+    return props1.currentDisplay == props2.currentDisplay && props1.currentStackIndex == props2.currentStackIndex;
+}
+bool operator==(const VkDisplayPlanePropertiesKHR& props1, const VkDisplayPlaneProperties2KHR& props2) {
+    return props1 == props2.displayPlaneProperties;
+}
+bool operator==(const VkExtent2D& ext1, const VkExtent2D& ext2) { return ext1.height == ext2.height && ext1.width == ext2.width; }
diff --git a/tests/framework/util/equality_helpers.h b/tests/framework/util/equality_helpers.h
new file mode 100644
index 0000000..5c38f50
--- /dev/null
+++ b/tests/framework/util/equality_helpers.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#include <string.h>
+
+#include <algorithm>
+#include <vector>
+
+#include <vulkan/vulkan.h>
+
+inline bool string_eq(const char* a, const char* b) noexcept { return a && b && strcmp(a, b) == 0; }
+inline bool string_eq(const char* a, const char* b, size_t len) noexcept { return a && b && strncmp(a, b, len) == 0; }
+
+bool operator==(const VkExtent3D& a, const VkExtent3D& b);
+bool operator!=(const VkExtent3D& a, const VkExtent3D& b);
+
+bool operator==(const VkQueueFamilyProperties& a, const VkQueueFamilyProperties& b);
+bool operator!=(const VkQueueFamilyProperties& a, const VkQueueFamilyProperties& b);
+
+bool operator==(const VkQueueFamilyProperties& a, const VkQueueFamilyProperties2& b);
+bool operator!=(const VkQueueFamilyProperties& a, const VkQueueFamilyProperties2& b);
+
+bool operator==(const VkLayerProperties& a, const VkLayerProperties& b);
+bool operator!=(const VkLayerProperties& a, const VkLayerProperties& b);
+
+bool operator==(const VkExtensionProperties& a, const VkExtensionProperties& b);
+bool operator!=(const VkExtensionProperties& a, const VkExtensionProperties& b);
+
+bool operator==(const VkPhysicalDeviceFeatures& feats1, const VkPhysicalDeviceFeatures2& feats2);
+
+bool operator==(const VkPhysicalDeviceMemoryProperties& props1, const VkPhysicalDeviceMemoryProperties2& props2);
+bool operator==(const VkSparseImageFormatProperties& props1, const VkSparseImageFormatProperties& props2);
+bool operator==(const VkSparseImageFormatProperties& props1, const VkSparseImageFormatProperties2& props2);
+bool operator==(const VkExternalMemoryProperties& props1, const VkExternalMemoryProperties& props2);
+bool operator==(const VkExternalSemaphoreProperties& props1, const VkExternalSemaphoreProperties& props2);
+bool operator==(const VkExternalFenceProperties& props1, const VkExternalFenceProperties& props2);
+bool operator==(const VkSurfaceCapabilitiesKHR& props1, const VkSurfaceCapabilitiesKHR& props2);
+bool operator==(const VkSurfacePresentScalingCapabilitiesEXT& caps1, const VkSurfacePresentScalingCapabilitiesEXT& caps2);
+bool operator==(const VkSurfaceFormatKHR& format1, const VkSurfaceFormatKHR& format2);
+bool operator==(const VkSurfaceFormatKHR& format1, const VkSurfaceFormat2KHR& format2);
+bool operator==(const VkDisplayPropertiesKHR& props1, const VkDisplayPropertiesKHR& props2);
+bool operator==(const VkDisplayPropertiesKHR& props1, const VkDisplayProperties2KHR& props2);
+bool operator==(const VkDisplayModePropertiesKHR& disp1, const VkDisplayModePropertiesKHR& disp2);
+
+bool operator==(const VkDisplayModePropertiesKHR& disp1, const VkDisplayModeProperties2KHR& disp2);
+bool operator==(const VkDisplayPlaneCapabilitiesKHR& caps1, const VkDisplayPlaneCapabilitiesKHR& caps2);
+
+bool operator==(const VkDisplayPlaneCapabilitiesKHR& caps1, const VkDisplayPlaneCapabilities2KHR& caps2);
+bool operator==(const VkDisplayPlanePropertiesKHR& props1, const VkDisplayPlanePropertiesKHR& props2);
+bool operator==(const VkDisplayPlanePropertiesKHR& props1, const VkDisplayPlaneProperties2KHR& props2);
+bool operator==(const VkExtent2D& ext1, const VkExtent2D& ext2);
+
+// Allow comparison of vectors of different types as long as their elements are comparable (just has to make sure to only apply when
+// T != U)
+template <typename T, typename U, typename = std::enable_if_t<!std::is_same_v<T, U>>>
+bool operator==(const std::vector<T>& a, const std::vector<U>& b) {
+    return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](const auto& left, const auto& right) { return left == right; });
+}
diff --git a/tests/framework/util/folder_manager.cpp b/tests/framework/util/folder_manager.cpp
new file mode 100644
index 0000000..53bbba6
--- /dev/null
+++ b/tests/framework/util/folder_manager.cpp
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#include "folder_manager.h"
+
+#include <algorithm>
+#include <fstream>
+
+#include "gtest/gtest.h"
+
+#include "util/json_writer.h"
+#include "util/env_var_wrapper.h"
+
+namespace fs {
+Folder::Folder(std::filesystem::path root_path, std::string name) noexcept : folder((root_path / name).lexically_normal()) {
+    clear();
+    // Don't actually create the folder yet, as we will do it on demand
+}
+Folder::~Folder() noexcept { clear(); }
+Folder::Folder(Folder&& other) noexcept : actually_created(other.actually_created), folder(other.folder) { other.folder.clear(); }
+Folder& Folder::operator=(Folder&& other) noexcept {
+    folder = other.folder;
+    actually_created = other.actually_created;
+    other.folder.clear();
+    return *this;
+}
+
+void Folder::check_if_first_use() {
+    if (!actually_created) {
+        if (!::testing::internal::InDeathTestChild()) {
+            std::error_code err;
+            if (!std::filesystem::create_directories(folder, err)) {
+                std::cerr << "Failed to create folder " << folder << " because " << err.message() << "\n";
+            }
+        }
+        actually_created = true;
+    }
+}
+
+std::filesystem::path Folder::write_manifest(std::filesystem::path const& name, std::string const& contents) {
+    check_if_first_use();
+    std::filesystem::path out_path = (folder / name).lexically_normal();
+    if (!::testing::internal::InDeathTestChild()) {
+        auto file = std::ofstream(out_path, std::ios_base::trunc | std::ios_base::out);
+        if (!file) {
+            std::cerr << "Failed to create manifest " << name << " at " << out_path << "\n";
+            return out_path;
+        }
+        file << contents << std::endl;
+    }
+    insert_file_to_tracking(name);
+    return out_path;
+}
+
+// close file handle, delete file, remove `name` from managed file list.
+void Folder::remove(std::filesystem::path const& name) {
+    check_if_first_use();
+    std::filesystem::path out_path = folder / name;
+    if (!::testing::internal::InDeathTestChild()) {
+        std::error_code err;
+        if (!std::filesystem::remove(out_path, err)) {
+            std::cerr << "Failed to remove file " << name << " at " << out_path << " because " << err.message() << "\n";
+        }
+    }
+
+    auto found = std::find(added_files.begin(), added_files.end(), name);
+    if (found != added_files.end()) {
+        added_files.erase(found);
+    } else {
+        std::cout << "File " << name << " not in tracked files of folder " << folder << ".\n";
+    }
+}
+
+// copy file into this folder
+std::filesystem::path Folder::copy_file(std::filesystem::path const& file, std::filesystem::path const& new_name) {
+    check_if_first_use();
+    insert_file_to_tracking(new_name);
+
+    auto new_filepath = folder / new_name;
+    if (!::testing::internal::InDeathTestChild()) {
+        std::error_code err;
+        if (!std::filesystem::copy_file(file, new_filepath, err)) {
+            std::cerr << "Failed to copy file " << file << " to " << new_filepath << " because " << err.message() << "\n";
+        }
+    }
+    return new_filepath;
+}
+
+std::vector<std::filesystem::path> Folder::get_files() const { return added_files; }
+
+std::filesystem::path Folder::add_symlink(std::filesystem::path const& target, std::filesystem::path const& link_name) {
+    check_if_first_use();
+
+    if (!::testing::internal::InDeathTestChild()) {
+        std::error_code err;
+        std::filesystem::create_symlink(target, folder / link_name, err);
+        if (err.value() != 0) {
+            std::cerr << "Failed to create symlink with target" << target << " with name " << folder / link_name << " because "
+                      << err.message() << "\n";
+        }
+    }
+    insert_file_to_tracking(link_name);
+    return folder / link_name;
+}
+void Folder::insert_file_to_tracking(std::filesystem::path const& name) {
+    auto found = std::find(added_files.begin(), added_files.end(), name);
+    if (found != added_files.end()) {
+        std::cout << "Overwriting manifest " << name << ". Was this intended?\n";
+    } else {
+        added_files.emplace_back(name);
+    }
+}
+
+void Folder::clear() const noexcept {
+    if (!::testing::internal::InDeathTestChild()) {
+        std::error_code err;
+        std::filesystem::remove_all(folder, err);
+        if (err.value() != 0) {
+            std::cerr << "Failed to remove folder " << folder << " because " << err.message() << "\n";
+        }
+    }
+}
+
+std::filesystem::path category_path_name(ManifestCategory category) {
+    if (category == ManifestCategory::settings) return "settings.d";
+    if (category == ManifestCategory::implicit_layer) return "implicit_layer.d";
+    if (category == ManifestCategory::explicit_layer)
+        return "explicit_layer.d";
+    else
+        return "icd.d";
+}
+
+FileSystemManager::FileSystemManager()
+    : root_folder(std::filesystem::path(TEST_EXECUTION_DIRECTORY),
+                  std::string(::testing::UnitTest::GetInstance()->GetInstance()->current_test_suite()->name()) + "_" +
+                      ::testing::UnitTest::GetInstance()->current_test_info()->name()) {
+    // Clean out test folder in case a previous run's files are still around
+    root_folder.clear();
+
+    auto const& root = root_folder.location();
+    folders.try_emplace(ManifestLocation::null, root, std::string("null_dir"));
+    folders.try_emplace(ManifestLocation::driver, root, std::string("icd_manifests"));
+    folders.try_emplace(ManifestLocation::driver_env_var, root, std::string("icd_env_vars_manifests"));
+    folders.try_emplace(ManifestLocation::explicit_layer, root, std::string("explicit_layer_manifests"));
+    folders.try_emplace(ManifestLocation::explicit_layer_env_var, root, std::string("explicit_env_var_layer_folder"));
+    folders.try_emplace(ManifestLocation::explicit_layer_add_env_var, root, std::string("explicit_add_env_var_layer_folder"));
+    folders.try_emplace(ManifestLocation::implicit_layer, root, std::string("implicit_layer_manifests"));
+    folders.try_emplace(ManifestLocation::implicit_layer_env_var, root, std::string("implicit_env_var_layer_manifests"));
+    folders.try_emplace(ManifestLocation::implicit_layer_add_env_var, root, std::string("implicit_add_env_var_layer_manifests"));
+    folders.try_emplace(ManifestLocation::override_layer, root, std::string("override_layer_manifests"));
+#if defined(_WIN32)
+    folders.try_emplace(ManifestLocation::windows_app_package, root, std::string("app_package_manifests"));
+#endif
+#if defined(__APPLE__)
+    folders.try_emplace(ManifestLocation::macos_bundle, root, std::string("macos_bundle"));
+#endif
+    folders.try_emplace(ManifestLocation::settings_location, root, std::string("settings_location"));
+    folders.try_emplace(ManifestLocation::unsecured_driver, root, std::string("unsecured_driver"));
+    folders.try_emplace(ManifestLocation::unsecured_explicit_layer, root, std::string("unsecured_explicit_layer"));
+    folders.try_emplace(ManifestLocation::unsecured_implicit_layer, root, std::string("unsecured_implicit_layer"));
+    folders.try_emplace(ManifestLocation::unsecured_settings, root, std::string("unsecured_settings"));
+}
+
+fs::Folder& FileSystemManager::get_folder(ManifestLocation location) noexcept { return folders.at(location); }
+fs::Folder const& FileSystemManager::get_folder(ManifestLocation location) const noexcept { return folders.at(location); }
+
+Folder* FileSystemManager::get_folder_for_given_path(std::string_view given_path) noexcept {
+    for (auto const& [manifest_location, folder] : folders) {
+        if (folder.location() == given_path) {
+            return &folders.at(manifest_location);
+        }
+    }
+    for (auto const& [redirected_path, redirected_location] : redirected_paths) {
+        if (redirected_path == given_path) {
+            return &folders.at(redirected_location);
+        }
+        const auto mismatch_pair =
+            std::mismatch(given_path.begin(), given_path.end(), redirected_path.begin(), redirected_path.end());
+        if (mismatch_pair.second == redirected_path.end()) return &folders.at(redirected_location);
+    }
+    return nullptr;
+}
+
+bool FileSystemManager::is_folder_path(std::filesystem::path const& path) const noexcept {
+    for (auto const& [location, folder] : folders) {
+        if (path == folder.location()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void FileSystemManager::add_path_redirect(std::filesystem::path const& redirected_path, ManifestLocation location) {
+    redirected_paths[redirected_path.string()] = location;
+}
+
+std::filesystem::path FileSystemManager::get_real_path_of_redirected_path(std::filesystem::path const& path) const {
+    if (redirected_paths.count(path.string()) > 0) {
+        return folders.at(redirected_paths.at(path.lexically_normal().string())).location();
+    }
+    for (auto const& [redirected_path_str, redirected_location] : redirected_paths) {
+        std::filesystem::path redirected_path = redirected_path_str;
+        const auto mismatch_pair = std::mismatch(path.begin(), path.end(), redirected_path.begin(), redirected_path.end());
+        if (mismatch_pair.second == redirected_path.end()) return folders.at(redirected_location).location();
+    }
+    return std::filesystem::path{};
+}
+
+std::filesystem::path FileSystemManager::get_path_redirect_by_manifest_location(ManifestLocation location) const {
+    for (auto const& [path, redirected_location] : redirected_paths) {
+        if (redirected_location == location) {
+            return path;
+        }
+    }
+    return folders.at(ManifestLocation::null).location();
+}
+
+}  // namespace fs
diff --git a/tests/framework/util/folder_manager.h b/tests/framework/util/folder_manager.h
new file mode 100644
index 0000000..9d405cb
--- /dev/null
+++ b/tests/framework/util/folder_manager.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#include <filesystem>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <vector>
+
+#include "test_defines.h"
+
+namespace fs {
+
+class Folder {
+   public:
+    explicit Folder(std::filesystem::path root_path, std::string name) noexcept;
+    ~Folder() noexcept;
+    Folder(Folder const&) = delete;
+    Folder& operator=(Folder const&) = delete;
+    Folder(Folder&& other) noexcept;
+    Folder& operator=(Folder&& other) noexcept;
+
+    // Add a manifest to the folder
+    std::filesystem::path write_manifest(std::filesystem::path const& name, std::string const& contents);
+
+    // close file handle, delete file, remove `name` from managed file list.
+    void remove(std::filesystem::path const& name);
+
+    // Remove all contents in the path
+    void clear() const noexcept;
+
+    // copy file into this folder with name `new_name`. Returns the full path of the file that was copied
+    std::filesystem::path copy_file(std::filesystem::path const& file, std::filesystem::path const& new_name);
+
+    // location of the managed folder
+    std::filesystem::path const& location() const { return folder; }
+
+    std::vector<std::filesystem::path> get_files() const;
+
+    // Create a symlink in this folder to target with the filename set to link_name
+    std::filesystem::path add_symlink(std::filesystem::path const& target, std::filesystem::path const& link_name);
+
+   private:
+    bool actually_created = false;
+    std::filesystem::path folder;
+    std::vector<std::filesystem::path> added_files;
+
+    void insert_file_to_tracking(std::filesystem::path const& name);
+    void check_if_first_use();
+};
+
+class FileSystemManager {
+    fs::Folder root_folder;
+    std::unordered_map<ManifestLocation, Folder> folders;
+
+    // paths that this folder appears as to the loader (ex /usr/share/vulkan/explicit_layer.d is in the ManifestLocation::icd folder
+    std::unordered_map<std::string, ManifestLocation> redirected_paths;
+
+   public:
+    FileSystemManager();
+
+    Folder& get_folder(ManifestLocation location) noexcept;
+    Folder const& get_folder(ManifestLocation location) const noexcept;
+
+    // Gets a pointer to the folder that given_path points to. This includes redirected paths as well as the exact path of folders
+    Folder* get_folder_for_given_path(std::string_view given_path) noexcept;
+
+    bool is_folder_path(std::filesystem::path const& path) const noexcept;
+
+    void add_path_redirect(std::filesystem::path const& apparent_path, ManifestLocation location);
+
+    // Returns the first redirected path pointing at by a manifest location. Returns the NULL location if one isn't found
+    std::filesystem::path get_path_redirect_by_manifest_location(ManifestLocation location) const;
+
+    // Returns the real path that a redirected path points to. Returns an empty path if no redirect is found
+    std::filesystem::path get_real_path_of_redirected_path(std::filesystem::path const& redirected_path) const;
+};
+
+}  // namespace fs
diff --git a/tests/framework/util/functions.h b/tests/framework/util/functions.h
new file mode 100644
index 0000000..5debba9
--- /dev/null
+++ b/tests/framework/util/functions.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#include <string>
+
+#include <vulkan/vulkan_core.h>
+
+class FromVoidStarFunc {
+    void* function;
+
+   public:
+    FromVoidStarFunc(void* function) : function(function) {}
+    FromVoidStarFunc(PFN_vkVoidFunction function) : function(reinterpret_cast<void*>(function)) {}
+
+    template <typename T>
+    operator T() {
+        return reinterpret_cast<T>(function);
+    }
+};
+
+template <typename T>
+PFN_vkVoidFunction to_vkVoidFunction(T func) {
+    return reinterpret_cast<PFN_vkVoidFunction>(func);
+}
+
+struct VulkanFunction {
+    std::string name;
+    PFN_vkVoidFunction function = nullptr;
+};
diff --git a/tests/framework/util/get_executable_path.cpp b/tests/framework/util/get_executable_path.cpp
new file mode 100644
index 0000000..9edb5d3
--- /dev/null
+++ b/tests/framework/util/get_executable_path.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#include "get_executable_path.h"
+
+#if defined(__linux__) || defined(__GNU__)
+
+#include <unistd.h>
+
+// find application path + name. Path cannot be longer than 1024, returns NULL if it is greater than that.
+std::string test_platform_executable_path() {
+    std::string buffer;
+    buffer.resize(1024);
+    ssize_t count = readlink("/proc/self/exe", &buffer[0], buffer.size());
+    if (count == -1) return NULL;
+    if (count == 0) return NULL;
+    buffer[count] = '\0';
+    buffer.resize(count);
+    return buffer;
+}
+#elif defined(__APPLE__)
+
+#include <libproc.h>
+#include <unistd.h>
+
+std::string test_platform_executable_path() {
+    std::string buffer;
+    buffer.resize(1024);
+    pid_t pid = getpid();
+    int ret = proc_pidpath(pid, &buffer[0], static_cast<uint32_t>(buffer.size()));
+    if (ret <= 0) return NULL;
+    buffer[ret] = '\0';
+    buffer.resize(ret);
+    return buffer;
+}
+#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
+#include <sys/sysctl.h>
+std::string test_platform_executable_path() {
+    int mib[] = {
+        CTL_KERN,
+#if defined(__NetBSD__)
+        KERN_PROC_ARGS,
+        -1,
+        KERN_PROC_PATHNAME,
+#else
+        KERN_PROC,
+        KERN_PROC_PATHNAME,
+        -1,
+#endif
+    };
+    std::string buffer;
+    buffer.resize(1024);
+    size_t size = buffer.size();
+    if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &buffer[0], &size, NULL, 0) < 0) {
+        return NULL;
+    }
+    buffer.resize(size);
+
+    return buffer;
+}
+#elif defined(__Fuchsia__) || defined(__OpenBSD__)
+std::string test_platform_executable_path() { return {}; }
+#elif defined(__QNX__)
+
+#ifndef SYSCONFDIR
+#define SYSCONFDIR "/etc"
+#endif
+
+#include <fcntl.h>
+#include <sys/stat.h>
+
+std::string test_platform_executable_path() {
+    std::string buffer;
+    buffer.resize(1024);
+    int fd = open("/proc/self/exefile", O_RDONLY);
+    ssize_t rdsize;
+
+    if (fd == -1) {
+        return NULL;
+    }
+
+    rdsize = read(fd, &buffer[0], buffer.size());
+    if (rdsize < 0) {
+        return NULL;
+    }
+    buffer[rdsize] = 0x00;
+    close(fd);
+    buffer.resize(rdsize);
+
+    return buffer;
+}
+#endif  // defined (__QNX__)
+
+#if defined(_WIN32)
+
+#include <filesystem>
+
+#include <Windows.h>
+
+#include "wide_char_handling.h"
+
+std::string test_platform_executable_path() {
+    std::string buffer;
+    buffer.resize(1024);
+    DWORD ret = GetModuleFileName(NULL, static_cast<LPSTR>(&buffer[0]), (DWORD)buffer.size());
+    if (ret == 0) return NULL;
+    if (ret > buffer.size()) return NULL;
+    buffer.resize(ret);
+    buffer[ret] = '\0';
+    return narrow(std::filesystem::path(buffer).native());
+}
+
+#endif
diff --git a/tests/framework/util/get_executable_path.h b/tests/framework/util/get_executable_path.h
new file mode 100644
index 0000000..bb296e5
--- /dev/null
+++ b/tests/framework/util/get_executable_path.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#include <string>
+
+// find application path + name. Path cannot be longer than 1024, returns NULL if it is greater than that.
+std::string test_platform_executable_path();
diff --git a/tests/framework/util/json_writer.cpp b/tests/framework/util/json_writer.cpp
new file mode 100644
index 0000000..1a955c0
--- /dev/null
+++ b/tests/framework/util/json_writer.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2023 The Khronos Group Inc.
+ * Copyright (c) 2023 Valve Corporation
+ * Copyright (c) 2023 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ * Author: Charles Giessen <charles@lunarg.com>
+ */
+
+#include "json_writer.h"
+
+#include "wide_char_handling.h"
+
+void JsonWriter::StartObject() {
+    CommaAndNewLine();
+    Indent();
+    output += "{";
+    stack.push(false);
+}
+void JsonWriter::StartKeyedObject(std::string const& key) {
+    CommaAndNewLine();
+    Indent();
+    output += "\"" + key + "\": {";
+    stack.push(false);
+}
+void JsonWriter::EndObject() {
+    stack.pop();
+    output += "\n";
+    Indent();
+    output += "}";
+}
+void JsonWriter::StartKeyedArray(std::string const& key) {
+    CommaAndNewLine();
+    Indent();
+    output += "\"" + key + "\": [";
+    stack.push(false);
+}
+void JsonWriter::StartArray() {
+    CommaAndNewLine();
+    Indent();
+    output += "[";
+    stack.push(false);
+}
+void JsonWriter::EndArray() {
+    stack.pop();
+    output += "\n";
+    Indent();
+    output += "]";
+}
+
+void JsonWriter::AddKeyedString(std::string const& key, std::string const& value) {
+    CommaAndNewLine();
+    Indent();
+    output += "\"" + key + "\": \"" + escape(value) + "\"";
+}
+void JsonWriter::AddString(std::string const& value) {
+    CommaAndNewLine();
+    Indent();
+    output += "\"" + escape(value) + "\"";
+}
+#if defined(_WIN32)
+void JsonWriter::AddKeyedString(std::string const& key, std::wstring const& value) {
+    CommaAndNewLine();
+    Indent();
+    output += "\"" + key + "\": \"" + escape(narrow(value)) + "\"";
+}
+void JsonWriter::AddString(std::wstring const& value) {
+    CommaAndNewLine();
+    Indent();
+    output += "\"" + escape(narrow(value)) + "\"";
+}
+#endif
+
+void JsonWriter::AddKeyedBool(std::string const& key, bool value) {
+    CommaAndNewLine();
+    Indent();
+    output += "\"" + key + "\": " + (value ? "true" : "false");
+}
+void JsonWriter::AddBool(bool value) {
+    CommaAndNewLine();
+    Indent();
+    output += std::string(value ? "true" : "false");
+}
+
+void JsonWriter::AddKeyedNumber(std::string const& key, double number) {
+    CommaAndNewLine();
+    Indent();
+    output += "\"" + key + "\": " + std::to_string(number);
+}
+void JsonWriter::AddNumber(double number) {
+    CommaAndNewLine();
+    Indent();
+    output += std::to_string(number);
+}
+
+void JsonWriter::AddKeyedInteger(std::string const& key, int64_t number) {
+    CommaAndNewLine();
+    Indent();
+    output += "\"" + key + "\": " + std::to_string(number);
+}
+void JsonWriter::AddInteger(int64_t number) {
+    CommaAndNewLine();
+    Indent();
+    output += std::to_string(number);
+}
+
+// Json doesn't allow `\` in strings, it must be escaped. Thus we have to convert '\\' to '\\\\' in strings
+std::string JsonWriter::escape(std::string const& in_path) {
+    std::string out;
+    for (auto& c : in_path) {
+        if (c == '\\')
+            out += "\\\\";
+        else
+            out += c;
+    }
+    return out;
+}
+std::string JsonWriter::escape(std::filesystem::path const& in_path) { return escape(narrow(in_path.native())); }
+
+void JsonWriter::CommaAndNewLine() {
+    if (stack.size() > 0) {
+        if (stack.top() == false) {
+            stack.top() = true;
+        } else {
+            output += ",";
+        }
+        output += "\n";
+    }
+}
+void JsonWriter::Indent() {
+    for (uint32_t i = 0; i < stack.size(); i++) {
+        output += '\t';
+    }
+}
diff --git a/tests/framework/util/json_writer.h b/tests/framework/util/json_writer.h
new file mode 100644
index 0000000..a5c3154
--- /dev/null
+++ b/tests/framework/util/json_writer.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2023 The Khronos Group Inc.
+ * Copyright (c) 2023 Valve Corporation
+ * Copyright (c) 2023 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ * Author: Charles Giessen <charles@lunarg.com>
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <stack>
+#include <string>
+#include <filesystem>
+
+#include "wide_char_handling.h"
+
+// Utility class to simplify the writing of JSON manifest files
+
+struct JsonWriter {
+    std::string output;
+
+    // the bool represents whether an object has been written & a comma is needed
+    std::stack<bool> stack;
+
+    void StartObject();
+    void StartKeyedObject(std::string const& key);
+    void EndObject();
+    void StartKeyedArray(std::string const& key);
+    void StartArray();
+    void EndArray();
+
+    void AddKeyedString(std::string const& key, std::string const& value);
+    void AddString(std::string const& value);
+#if defined(_WIN32)
+    void AddKeyedString(std::string const& key, std::wstring const& value);
+    void AddString(std::wstring const& value);
+#endif
+
+    void AddKeyedBool(std::string const& key, bool value);
+    void AddBool(bool value);
+
+    void AddKeyedNumber(std::string const& key, double number);
+    void AddNumber(double number);
+
+    void AddKeyedInteger(std::string const& key, int64_t number);
+    void AddInteger(int64_t number);
+
+    // Json doesn't allow `\` in strings, it must be escaped. Thus we have to convert '\\' to '\\\\' in strings
+    static std::string escape(std::string const& in_path);
+    static std::string escape(std::filesystem::path const& in_path);
+
+   private:
+    void CommaAndNewLine();
+    void Indent();
+};
diff --git a/tests/framework/util/manifest_builders.cpp b/tests/framework/util/manifest_builders.cpp
new file mode 100644
index 0000000..6666a57
--- /dev/null
+++ b/tests/framework/util/manifest_builders.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#include "manifest_builders.h"
+
+#include "json_writer.h"
+
+template <typename T>
+void print_object_of_t(JsonWriter& writer, const char* object_name, std::vector<T> const& vec) {
+    if (vec.size() == 0) return;
+    writer.StartKeyedObject(object_name);
+    for (auto& element : vec) {
+        element.get_manifest_str(writer);
+    }
+    writer.EndObject();
+}
+
+template <typename T>
+void print_array_of_t(JsonWriter& writer, const char* object_name, std::vector<T> const& vec) {
+    if (vec.size() == 0) return;
+    writer.StartKeyedArray(object_name);
+    for (auto& element : vec) {
+        element.get_manifest_str(writer);
+    }
+    writer.EndArray();
+}
+void print_vector_of_strings(JsonWriter& writer, const char* object_name, std::vector<std::string> const& strings) {
+    if (strings.size() == 0) return;
+    writer.StartKeyedArray(object_name);
+    for (auto const& str : strings) {
+        writer.AddString(std::filesystem::path(str).native());
+    }
+    writer.EndArray();
+}
+void print_vector_of_strings(JsonWriter& writer, const char* object_name, std::vector<std::filesystem::path> const& paths) {
+    if (paths.size() == 0) return;
+    writer.StartKeyedArray(object_name);
+    for (auto const& path : paths) {
+        writer.AddString(path.native());
+    }
+    writer.EndArray();
+}
+
+std::string version_to_string(uint32_t version) {
+    std::string out = std::to_string(VK_API_VERSION_MAJOR(version)) + "." + std::to_string(VK_API_VERSION_MINOR(version)) + "." +
+                      std::to_string(VK_API_VERSION_PATCH(version));
+    if (VK_API_VERSION_VARIANT(version) != 0) out += std::to_string(VK_API_VERSION_VARIANT(version)) + "." + out;
+    return out;
+}
+
+std::string to_text(bool b) { return b ? std::string("true") : std::string("false"); }
+
+std::string ManifestICD::get_manifest_str() const {
+    JsonWriter writer;
+    writer.StartObject();
+    writer.AddKeyedString("file_format_version", file_format_version.get_version_str());
+    writer.StartKeyedObject("ICD");
+    writer.AddKeyedString("library_path", lib_path.native());
+    writer.AddKeyedString("api_version", version_to_string(api_version));
+    writer.AddKeyedBool("is_portability_driver", is_portability_driver);
+    if (!library_arch.empty()) writer.AddKeyedString("library_arch", library_arch);
+    writer.EndObject();
+    writer.EndObject();
+    return writer.output;
+}
+
+void ManifestLayer::LayerDescription::FunctionOverride::get_manifest_str(JsonWriter& writer) const {
+    writer.AddKeyedString(vk_func, override_name);
+}
+
+void ManifestLayer::LayerDescription::Extension::get_manifest_str(JsonWriter& writer) const {
+    writer.StartObject();
+    writer.AddKeyedString("name", name);
+    writer.AddKeyedString("spec_version", std::to_string(spec_version));
+    writer.AddKeyedString("spec_version", std::to_string(spec_version));
+    print_vector_of_strings(writer, "entrypoints", entrypoints);
+    writer.EndObject();
+}
+
+void ManifestLayer::LayerDescription::get_manifest_str(JsonWriter& writer) const {
+    writer.AddKeyedString("name", name);
+    writer.AddKeyedString("type", get_type_str(type));
+    if (!lib_path.empty()) {
+        writer.AddKeyedString("library_path", lib_path.native());
+    }
+    writer.AddKeyedString("api_version", version_to_string(api_version));
+    writer.AddKeyedString("implementation_version", std::to_string(implementation_version));
+    writer.AddKeyedString("description", description);
+    print_object_of_t(writer, "functions", functions);
+    print_array_of_t(writer, "instance_extensions", instance_extensions);
+    print_array_of_t(writer, "device_extensions", device_extensions);
+    if (!enable_environment.empty()) {
+        writer.StartKeyedObject("enable_environment");
+        writer.AddKeyedString(enable_environment, "1");
+        writer.EndObject();
+    }
+    if (!disable_environment.empty()) {
+        writer.StartKeyedObject("disable_environment");
+        writer.AddKeyedString(disable_environment, "1");
+        writer.EndObject();
+    }
+    print_vector_of_strings(writer, "component_layers", component_layers);
+    print_vector_of_strings(writer, "blacklisted_layers", blacklisted_layers);
+    print_vector_of_strings(writer, "override_paths", override_paths);
+    print_vector_of_strings(writer, "app_keys", app_keys);
+    print_object_of_t(writer, "pre_instance_functions", pre_instance_functions);
+    if (!library_arch.empty()) {
+        writer.AddKeyedString("library_arch", library_arch);
+    }
+}
+
+VkLayerProperties ManifestLayer::LayerDescription::get_layer_properties() const {
+    VkLayerProperties properties{};
+    name.copy(properties.layerName, VK_MAX_EXTENSION_NAME_SIZE);
+    description.copy(properties.description, VK_MAX_EXTENSION_NAME_SIZE);
+    properties.implementationVersion = implementation_version;
+    properties.specVersion = api_version;
+    return properties;
+}
+
+std::string ManifestLayer::get_manifest_str() const {
+    JsonWriter writer;
+    writer.StartObject();
+    writer.AddKeyedString("file_format_version", file_format_version.get_version_str());
+    if (layers.size() == 1) {
+        writer.StartKeyedObject("layer");
+        layers.at(0).get_manifest_str(writer);
+        writer.EndObject();
+    } else {
+        writer.StartKeyedArray("layers");
+        for (size_t i = 0; i < layers.size(); i++) {
+            writer.StartObject();
+            layers.at(i).get_manifest_str(writer);
+            writer.EndObject();
+        }
+        writer.EndArray();
+    }
+    writer.EndObject();
+    return writer.output;
+}
diff --git a/tests/framework/util/manifest_builders.h b/tests/framework/util/manifest_builders.h
new file mode 100644
index 0000000..8ebb816
--- /dev/null
+++ b/tests/framework/util/manifest_builders.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#include <vector>
+#include <string>
+#include <filesystem>
+
+#include <vulkan/vulkan_core.h>
+
+#include "builder_defines.h"
+
+// Forward declaration since we take it by reference only
+class JsonWriter;
+
+struct ManifestVersion {
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, major, 1)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, minor, 0)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, patch, 0)
+
+    std::string get_version_str() const noexcept {
+        return std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(patch);
+    }
+};
+
+// ManifestICD builder
+struct ManifestICD {
+    BUILDER_VALUE(ManifestVersion, file_format_version)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, api_version, VK_API_VERSION_1_0)
+    BUILDER_VALUE(std::filesystem::path, lib_path)
+    BUILDER_VALUE(bool, is_portability_driver)
+    BUILDER_VALUE(std::string, library_arch)
+    std::string get_manifest_str() const;
+};
+
+// ManifestLayer builder
+struct ManifestLayer {
+    struct LayerDescription {
+        enum class Type { INSTANCE, GLOBAL, DEVICE };
+        std::string get_type_str(Type layer_type) const {
+            if (layer_type == Type::GLOBAL)
+                return "GLOBAL";
+            else if (layer_type == Type::DEVICE)
+                return "DEVICE";
+            else  // default
+                return "INSTANCE";
+        }
+        struct FunctionOverride {
+            BUILDER_VALUE(std::string, vk_func)
+            BUILDER_VALUE(std::string, override_name)
+
+            void get_manifest_str(JsonWriter& writer) const;
+        };
+        struct Extension {
+            Extension() noexcept {}
+            Extension(std::string name, uint32_t spec_version = 0, std::vector<std::string> entrypoints = {}) noexcept
+                : name(name), spec_version(spec_version), entrypoints(entrypoints) {}
+            std::string name;
+            uint32_t spec_version = 0;
+            std::vector<std::string> entrypoints;
+            void get_manifest_str(JsonWriter& writer) const;
+        };
+        BUILDER_VALUE(std::string, name)
+        BUILDER_VALUE_WITH_DEFAULT(Type, type, Type::INSTANCE)
+        BUILDER_VALUE(std::filesystem::path, lib_path)
+        BUILDER_VALUE_WITH_DEFAULT(uint32_t, api_version, VK_API_VERSION_1_0)
+        BUILDER_VALUE(uint32_t, implementation_version)
+        BUILDER_VALUE(std::string, description)
+        BUILDER_VECTOR(FunctionOverride, functions, function)
+        BUILDER_VECTOR(Extension, instance_extensions, instance_extension)
+        BUILDER_VECTOR(Extension, device_extensions, device_extension)
+        BUILDER_VALUE(std::string, enable_environment)
+        BUILDER_VALUE(std::string, disable_environment)
+        BUILDER_VECTOR(std::string, component_layers, component_layer)
+        BUILDER_VECTOR(std::string, blacklisted_layers, blacklisted_layer)
+        BUILDER_VECTOR(std::filesystem::path, override_paths, override_path)
+        BUILDER_VECTOR(FunctionOverride, pre_instance_functions, pre_instance_function)
+        BUILDER_VECTOR(std::string, app_keys, app_key)
+        BUILDER_VALUE(std::string, library_arch)
+
+        void get_manifest_str(JsonWriter& writer) const;
+        VkLayerProperties get_layer_properties() const;
+    };
+    BUILDER_VALUE(ManifestVersion, file_format_version)
+    BUILDER_VECTOR(LayerDescription, layers, layer)
+
+    std::string get_manifest_str() const;
+};
diff --git a/tests/framework/util/platform_wsi.cpp b/tests/framework/util/platform_wsi.cpp
new file mode 100644
index 0000000..748abdc
--- /dev/null
+++ b/tests/framework/util/platform_wsi.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#include "platform_wsi.h"
+
+#include "equality_helpers.h"
+
+const char* get_platform_wsi_extension([[maybe_unused]] const char* api_selection) {
+#if defined(VK_USE_PLATFORM_ANDROID_KHR)
+    return "VK_KHR_android_surface";
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    return "VK_EXT_directfb_surface";
+#elif defined(VK_USE_PLATFORM_FUCHSIA)
+    return "VK_FUCHSIA_imagepipe_surface";
+#elif defined(VK_USE_PLATFORM_GGP)
+    return "VK_GGP_stream_descriptor_surface";
+#elif defined(VK_USE_PLATFORM_IOS_MVK)
+    return "VK_MVK_ios_surface";
+#elif defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)
+#if defined(VK_USE_PLATFORM_MACOS_MVK)
+    if (string_eq(api_selection, "VK_USE_PLATFORM_MACOS_MVK")) return "VK_MVK_macos_surface";
+#endif
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+    if (string_eq(api_selection, "VK_USE_PLATFORM_METAL_EXT")) return "VK_EXT_metal_surface";
+    return "VK_EXT_metal_surface";
+#endif
+#elif defined(VK_USE_PLATFORM_SCREEN_QNX)
+    return "VK_QNX_screen_surface";
+#elif defined(VK_USE_PLATFORM_VI_NN)
+    return "VK_NN_vi_surface";
+#elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+    if (string_eq(api_selection, "VK_USE_PLATFORM_XCB_KHR")) return "VK_KHR_xcb_surface";
+#endif
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+    if (string_eq(api_selection, "VK_USE_PLATFORM_XLIB_KHR")) return "VK_KHR_xlib_surface";
+#endif
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    if (string_eq(api_selection, "VK_USE_PLATFORM_WAYLAND_KHR")) return "VK_KHR_wayland_surface";
+#endif
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+    return "VK_KHR_xcb_surface";
+#endif
+#elif defined(VK_USE_PLATFORM_WIN32_KHR)
+    return "VK_KHR_win32_surface";
+#else
+    return "VK_KHR_display";
+#endif
+}
diff --git a/tests/framework/util/platform_wsi.h b/tests/framework/util/platform_wsi.h
new file mode 100644
index 0000000..66b7b50
--- /dev/null
+++ b/tests/framework/util/platform_wsi.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+const char* get_platform_wsi_extension([[maybe_unused]] const char* api_selection);
diff --git a/tests/framework/util/test_defines.h b/tests/framework/util/test_defines.h
new file mode 100644
index 0000000..9c261bb
--- /dev/null
+++ b/tests/framework/util/test_defines.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define FRAMEWORK_EXPORT __attribute__((visibility("default")))
+#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
+#define FRAMEWORK_EXPORT __attribute__((visibility("default")))
+#elif defined(_WIN32)
+#define FRAMEWORK_EXPORT __declspec(dllexport)
+#else
+#define FRAMEWORK_EXPORT
+#endif
+
+// Set of platforms with a common set of functionality which is queried throughout the program
+#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNX__) || defined(__FreeBSD__) || \
+    defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__)
+#define TESTING_COMMON_UNIX_PLATFORMS 1
+#else
+#define TESTING_COMMON_UNIX_PLATFORMS 0
+#endif
+
+#define TESTING_VULKAN_DIR "vulkan/"
+
+#include FRAMEWORK_CONFIG_HEADER
+
+enum class ManifestCategory { implicit_layer, explicit_layer, icd, settings };
+
+// Controls whether to create a manifest and where to put it
+enum class ManifestDiscoveryType {
+    generic,            // put the manifest in the regular locations
+    unsecured_generic,  // put the manifest in a user folder rather than system
+    none,               // Do not write the manifest anywhere (for Direct Driver Loading)
+    null_dir,           // put the manifest in the 'null_dir' which the loader does not search in (D3DKMT for instance)
+    env_var,            // use the corresponding env-var for it
+    add_env_var,        // use the corresponding add-env-var for it
+    override_folder,    // add to a special folder for the override layer to use
+#if defined(_WIN32)
+    windows_app_package,  // let the app package search find it
+#endif
+#if defined(__APPLE__)
+    macos_bundle,  // place it in a location only accessible to macos bundles
+#endif
+};
+
+enum class LibraryPathType {
+    absolute,              // default for testing - the exact path of the binary
+    relative,              // Relative to the manifest file
+    default_search_paths,  // Dont add any path information to the library_path - force the use of the default search paths
+};
+
+// Locations that files can go in the test framework
+enum class ManifestLocation {
+    null,
+    driver,
+    driver_env_var,
+    explicit_layer,
+    explicit_layer_env_var,
+    explicit_layer_add_env_var,
+    implicit_layer,
+    implicit_layer_env_var,
+    implicit_layer_add_env_var,
+    override_layer,
+#if defined(_WIN32)
+    windows_app_package,
+#endif
+#if defined(__APPLE__)
+    macos_bundle,
+#endif
+    settings_location,
+    unsecured_driver,
+    unsecured_explicit_layer,
+    unsecured_implicit_layer,
+    unsecured_settings,
+};
diff --git a/tests/framework/util/vulkan_object_wrappers.cpp b/tests/framework/util/vulkan_object_wrappers.cpp
new file mode 100644
index 0000000..0223ff6
--- /dev/null
+++ b/tests/framework/util/vulkan_object_wrappers.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#include "vulkan_object_wrappers.h"
+
+#include "platform_wsi.h"
+
+VkExtensionProperties Extension::get() const noexcept {
+    VkExtensionProperties props{};
+    extensionName.copy(props.extensionName, VK_MAX_EXTENSION_NAME_SIZE);
+    props.specVersion = specVersion;
+    return props;
+}
+
+InstanceCreateInfo::InstanceCreateInfo() {
+    instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+    application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+}
+
+VkInstanceCreateInfo* InstanceCreateInfo::get() noexcept {
+    if (fill_in_application_info) {
+        application_info.pApplicationName = app_name.c_str();
+        application_info.pEngineName = engine_name.c_str();
+        application_info.applicationVersion = app_version;
+        application_info.engineVersion = engine_version;
+        application_info.apiVersion = api_version;
+        instance_info.pApplicationInfo = &application_info;
+    }
+    instance_info.flags = flags;
+    instance_info.enabledLayerCount = static_cast<uint32_t>(enabled_layers.size());
+    instance_info.ppEnabledLayerNames = enabled_layers.data();
+    instance_info.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size());
+    instance_info.ppEnabledExtensionNames = enabled_extensions.data();
+    return &instance_info;
+}
+InstanceCreateInfo& InstanceCreateInfo::set_api_version(uint32_t major, uint32_t minor, uint32_t patch) {
+    this->api_version = VK_MAKE_API_VERSION(0, major, minor, patch);
+    return *this;
+}
+InstanceCreateInfo& InstanceCreateInfo::setup_WSI(const char* api_selection) {
+    add_extensions({"VK_KHR_surface", get_platform_wsi_extension(api_selection)});
+    return *this;
+}
+
+DeviceQueueCreateInfo::DeviceQueueCreateInfo() { queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; }
+DeviceQueueCreateInfo::DeviceQueueCreateInfo(const VkDeviceQueueCreateInfo* create_info) {
+    queue_create_info = *create_info;
+    for (uint32_t i = 0; i < create_info->queueCount; i++) {
+        priorities.push_back(create_info->pQueuePriorities[i]);
+    }
+}
+
+VkDeviceQueueCreateInfo DeviceQueueCreateInfo::get() noexcept {
+    queue_create_info.pQueuePriorities = priorities.data();
+    queue_create_info.queueCount = 1;
+    queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+    return queue_create_info;
+}
+
+DeviceCreateInfo::DeviceCreateInfo(const VkDeviceCreateInfo* create_info) {
+    dev = *create_info;
+    for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
+        enabled_extensions.push_back(create_info->ppEnabledExtensionNames[i]);
+    }
+    for (uint32_t i = 0; i < create_info->enabledLayerCount; i++) {
+        enabled_layers.push_back(create_info->ppEnabledLayerNames[i]);
+    }
+    for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++) {
+        device_queue_infos.push_back(create_info->pQueueCreateInfos[i]);
+    }
+}
+
+VkDeviceCreateInfo* DeviceCreateInfo::get() noexcept {
+    dev.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+    dev.enabledLayerCount = static_cast<uint32_t>(enabled_layers.size());
+    dev.ppEnabledLayerNames = enabled_layers.data();
+    dev.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size());
+    dev.ppEnabledExtensionNames = enabled_extensions.data();
+    uint32_t index = 0;
+    for (auto& queue : queue_info_details) {
+        queue.queue_create_info.queueFamilyIndex = index++;
+        queue.queue_create_info.queueCount = 1;
+        device_queue_infos.push_back(queue.get());
+    }
+
+    dev.queueCreateInfoCount = static_cast<uint32_t>(device_queue_infos.size());
+    dev.pQueueCreateInfos = device_queue_infos.data();
+    return &dev;
+}
diff --git a/tests/framework/util/vulkan_object_wrappers.h b/tests/framework/util/vulkan_object_wrappers.h
new file mode 100644
index 0000000..7cc9235
--- /dev/null
+++ b/tests/framework/util/vulkan_object_wrappers.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <vulkan/vulkan_core.h>
+
+#include "builder_defines.h"
+
+struct Extension {
+    BUILDER_VALUE(std::string, extensionName)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, specVersion, VK_API_VERSION_1_0)
+
+    Extension(const char* name, uint32_t specVersion = VK_API_VERSION_1_0) noexcept
+        : extensionName(name), specVersion(specVersion) {}
+    Extension(std::string extensionName, uint32_t specVersion = VK_API_VERSION_1_0) noexcept
+        : extensionName(extensionName), specVersion(specVersion) {}
+
+    VkExtensionProperties get() const noexcept;
+};
+
+struct MockQueueFamilyProperties {
+    BUILDER_VALUE(VkQueueFamilyProperties, properties)
+    BUILDER_VALUE(bool, support_present)
+
+    VkQueueFamilyProperties get() const noexcept { return properties; }
+};
+
+struct InstanceCreateInfo {
+    BUILDER_VALUE(VkInstanceCreateInfo, instance_info)
+    BUILDER_VALUE(VkApplicationInfo, application_info)
+    BUILDER_VALUE(std::string, app_name)
+    BUILDER_VALUE(std::string, engine_name)
+    BUILDER_VALUE(uint32_t, flags)
+    BUILDER_VALUE(uint32_t, app_version)
+    BUILDER_VALUE(uint32_t, engine_version)
+    BUILDER_VALUE_WITH_DEFAULT(uint32_t, api_version, VK_API_VERSION_1_0)
+    BUILDER_VECTOR(const char*, enabled_layers, layer)
+    BUILDER_VECTOR(const char*, enabled_extensions, extension)
+    // tell the get() function to not provide `application_info`
+    BUILDER_VALUE_WITH_DEFAULT(bool, fill_in_application_info, true)
+
+    InstanceCreateInfo();
+
+    VkInstanceCreateInfo* get() noexcept;
+
+    InstanceCreateInfo& set_api_version(uint32_t major, uint32_t minor, uint32_t patch);
+
+    InstanceCreateInfo& setup_WSI(const char* api_selection = nullptr);
+};
+
+struct DeviceQueueCreateInfo {
+    DeviceQueueCreateInfo();
+    DeviceQueueCreateInfo(const VkDeviceQueueCreateInfo* create_info);
+
+    BUILDER_VALUE(VkDeviceQueueCreateInfo, queue_create_info)
+    BUILDER_VECTOR(float, priorities, priority)
+
+    VkDeviceQueueCreateInfo get() noexcept;
+};
+
+struct DeviceCreateInfo {
+    DeviceCreateInfo() = default;
+    DeviceCreateInfo(const VkDeviceCreateInfo* create_info);
+
+    BUILDER_VALUE(VkDeviceCreateInfo, dev)
+    BUILDER_VECTOR(const char*, enabled_extensions, extension)
+    BUILDER_VECTOR(const char*, enabled_layers, layer)
+    BUILDER_VECTOR(DeviceQueueCreateInfo, queue_info_details, device_queue)
+
+    VkDeviceCreateInfo* get() noexcept;
+
+   private:
+    std::vector<VkDeviceQueueCreateInfo> device_queue_infos;
+};
diff --git a/tests/framework/util/wide_char_handling.cpp b/tests/framework/util/wide_char_handling.cpp
new file mode 100644
index 0000000..ac4fb0b
--- /dev/null
+++ b/tests/framework/util/wide_char_handling.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#include "wide_char_handling.h"
+
+#if defined(_WIN32)
+
+#include "Windows.h"
+
+std::string narrow(const std::wstring& utf16) {
+    if (utf16.empty()) {
+        return {};
+    }
+    int size = WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()), nullptr, 0, nullptr, nullptr);
+    if (size <= 0) {
+        return {};
+    }
+    std::string utf8(size, '\0');
+    if (WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()), &utf8[0], size, nullptr, nullptr) != size) {
+        return {};
+    }
+    return utf8;
+}
+
+std::wstring widen(const std::string& utf8) {
+    if (utf8.empty()) {
+        return {};
+    }
+    int size = MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), nullptr, 0);
+    if (size <= 0) {
+        return {};
+    }
+    std::wstring utf16(size, L'\0');
+    if (MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), &utf16[0], size) != size) {
+        return {};
+    }
+    return utf16;
+}
+#else
+std::string narrow(const std::string& utf16) { return utf16; }
+std::string widen(const std::string& utf8) { return utf8; }
+#endif
diff --git a/tests/framework/util/wide_char_handling.h b/tests/framework/util/wide_char_handling.h
new file mode 100644
index 0000000..805afe1
--- /dev/null
+++ b/tests/framework/util/wide_char_handling.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2025 The Khronos Group Inc.
+ * Copyright (c) 2025 Valve Corporation
+ * Copyright (c) 2025 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+
+#pragma once
+
+#include <string>
+
+// Define it here so that json_writer.h has access to these functions
+#if defined(_WIN32)
+// Convert an UTF-16 wstring to an UTF-8 string
+std::string narrow(const std::wstring& utf16);
+// Convert an UTF-8 string to an UTF-16 wstring
+std::wstring widen(const std::string& utf8);
+#else
+// Do nothing passthrough for the sake of Windows & UTF-16
+std::string narrow(const std::string& utf16);
+// Do nothing passthrough for the sake of Windows & UTF-16
+std::string widen(const std::string& utf8);
+#endif
diff --git a/tests/integration/CMakeLists.txt b/tests/integration/CMakeLists.txt
index f156852..e0f87e6 100644
--- a/tests/integration/CMakeLists.txt
+++ b/tests/integration/CMakeLists.txt
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # ~~~
-cmake_minimum_required(VERSION 3.17.2)
+cmake_minimum_required(VERSION 3.22.1)
 
 project(INTEGRATION LANGUAGES C)
 
diff --git a/tests/live_verification/dynamic_loader_behavior/dynamic_library.h b/tests/live_verification/dynamic_loader_behavior/dynamic_library.h
index 1d88d30..b4bff31 100644
--- a/tests/live_verification/dynamic_loader_behavior/dynamic_library.h
+++ b/tests/live_verification/dynamic_loader_behavior/dynamic_library.h
@@ -25,7 +25,12 @@
  * Author: Charles Giessen <charles@lunarg.com>
  */
 
-#include "test_util.h"
+#include <iostream>
+#include <string>
+
+#include "util/test_defines.h"
+#include "util/functions.h"
+#include "util/dynamic_library_wrapper.h"
 
 extern "C" {
 
@@ -38,7 +43,7 @@
 FRAMEWORK_EXPORT void init();
 };
 
-#if defined(WIN32)
+#if defined(_WIN32)
 #if !defined(LIB_EXT)
 #define LIB_EXT "dll"
 #endif
diff --git a/tests/live_verification/dynamic_loader_behavior/test_dynamic_linking.cpp b/tests/live_verification/dynamic_loader_behavior/test_dynamic_linking.cpp
index 2d2d6b3..943917e 100644
--- a/tests/live_verification/dynamic_loader_behavior/test_dynamic_linking.cpp
+++ b/tests/live_verification/dynamic_loader_behavior/test_dynamic_linking.cpp
@@ -42,4 +42,4 @@
     std::cout << "Success\n";
 #endif
     return 0;
-}
\ No newline at end of file
+}
diff --git a/tests/loader_alloc_callback_tests.cpp b/tests/loader_alloc_callback_tests.cpp
index 1701bfb..b10ade5 100644
--- a/tests/loader_alloc_callback_tests.cpp
+++ b/tests/loader_alloc_callback_tests.cpp
@@ -25,9 +25,9 @@
  * Author: Charles Giessen <charles@lunarg.com>
  */
 
+#include "manifest_builders.h"
 #include "test_environment.h"
 
-#include <fstream>
 #include <mutex>
 
 struct MemoryTrackerSettings {
@@ -184,7 +184,7 @@
 // a CreateInstance/DestroyInstance call pair.
 TEST(Allocation, Instance) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     MemoryTracker tracker;
     {
@@ -198,7 +198,7 @@
 // a CreateInstance/DestroyInstance call pair with a call to GetInstanceProcAddr.
 TEST(Allocation, GetInstanceProcAddr) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     MemoryTracker tracker;
     {
@@ -216,7 +216,7 @@
 // a vkEnumeratePhysicalDevices call pair.
 TEST(Allocation, EnumeratePhysicalDevices) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     MemoryTracker tracker;
     {
@@ -239,7 +239,7 @@
 // allocators used on both the instance and device.
 TEST(Allocation, InstanceAndDevice) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
         .add_physical_device(PhysicalDevice{"physical_device_0"}
                                  .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, false})
                                  .finish());
@@ -288,7 +288,7 @@
 // allocators used on only the instance and not the device.
 TEST(Allocation, InstanceButNotDevice) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
         .add_physical_device(PhysicalDevice{"physical_device_0"}
                                  .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, false})
                                  .finish());
@@ -337,17 +337,16 @@
 // allocators used on only the device and not the instance.
 TEST(Allocation, DeviceButNotInstance) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
         .add_physical_device(PhysicalDevice{"physical_device_0"}
                                  .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, false})
                                  .finish());
 
     const char* layer_name = "VK_LAYER_implicit";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ENV")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ENV")));
     env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
 
     MemoryTracker tracker;
@@ -394,14 +393,13 @@
 // one of the out-of-memory conditions trigger.
 TEST(Allocation, CreateInstanceIntentionalAllocFail) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("error,warn")};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     const char* layer_name = "VK_LAYER_implicit";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ENV")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ENV")));
     env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
 
     size_t fail_index = 0;
@@ -424,7 +422,7 @@
 // one of the out-of-memory conditions trigger and there are invalid jsons in the same folder
 TEST(Allocation, CreateInstanceIntentionalAllocFailInvalidManifests) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("error,warn")};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     std::vector<std::string> invalid_jsons;
     invalid_jsons.push_back(",");
@@ -440,15 +438,16 @@
         auto file_name = std::string("invalid_implicit_layer_") + std::to_string(i) + ".json";
         std::filesystem::path new_path =
             env.get_folder(ManifestLocation::implicit_layer).write_manifest(file_name, invalid_jsons[i]);
-        env.platform_shim->add_manifest(ManifestCategory::implicit_layer, new_path);
+#if defined(WIN32)
+        env.platform_shim->add_manifest_to_registry(ManifestCategory::implicit_layer, new_path);
+#endif
     }
 
     const char* layer_name = "VkLayerImplicit0";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ENV")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ENV")));
 
     size_t fail_index = 0;
     VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -470,14 +469,13 @@
 // one of the out-of-memory conditions trigger.
 TEST(Allocation, CreateSurfaceIntentionalAllocFail) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("error,warn")};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     const char* layer_name = "VK_LAYER_implicit";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ENV")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ENV")));
     env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
 
     size_t fail_index = 0;
@@ -515,14 +513,13 @@
 // one of the out-of-memory conditions trigger.
 TEST(Allocation, CreateInstanceIntentionalAllocFailWithSettingsFilePresent) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("error,warn")};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     const char* layer_name = "VK_LAYER_implicit";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ENV")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ENV")));
     env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
 
     env.update_loader_settings(
@@ -552,14 +549,13 @@
 // one of the out-of-memory conditions trigger.
 TEST(Allocation, CreateSurfaceIntentionalAllocFailWithSettingsFilePresent) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("error,warn")};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     const char* layer_name = "VK_LAYER_implicit";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ENV")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ENV")));
     env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
     env.update_loader_settings(
         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
@@ -603,14 +599,13 @@
 // one of the out-of-memory conditions trigger.
 TEST(Allocation, DriverEnvVarIntentionalAllocFail) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("error,warn")};
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2}.set_discovery_type(ManifestDiscoveryType::env_var));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var));
 
     const char* layer_name = "VK_LAYER_implicit";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ENV")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ENV")));
     env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
 
     env.env_var_vk_icd_filenames.add_to_list("totally_made_up/path_to_fake/jason_file.json");
@@ -637,7 +632,7 @@
 // may fail.
 TEST(Allocation, CreateDeviceIntentionalAllocFail) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("error,warn")};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
         .add_physical_device(PhysicalDevice{"physical_device_0"}
                                  .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, false})
                                  .finish())
@@ -646,11 +641,10 @@
                                  .finish());
 
     const char* layer_name = "VK_LAYER_implicit";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ENV")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ENV")));
     env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
 
     InstWrapper inst{env.vulkan_functions};
@@ -707,24 +701,22 @@
     uint32_t num_physical_devices = 4;
     uint32_t num_implicit_layers = 3;
     for (uint32_t i = 0; i < num_physical_devices; i++) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)
-                        .icd_manifest.set_is_portability_driver(false)
-                        .set_library_arch(sizeof(void*) == 8 ? "64" : "32"))
+        env.add_icd(TEST_ICD_PATH_VERSION_2, {},
+                    ManifestICD{}.set_is_portability_driver(false).set_library_arch(sizeof(void*) == 8 ? "64" : "32"))
             .set_icd_api_version(VK_API_VERSION_1_1)
             .add_instance_extension("VK_KHR_get_physical_device_properties2")
-            .add_physical_device("physical_device_0")
-            .physical_devices.at(0)
+            .add_and_get_physical_device("physical_device_0")
             .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, false})
             .add_extensions({"VK_EXT_one", "VK_EXT_two", "VK_EXT_three", "VK_EXT_four", "VK_EXT_five"});
     }
 
-    env.add_icd(TestICDDetails(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE).set_is_fake(true));
+    env.add_icd(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE, ManifestOptions{}.set_is_fake(true));
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none));
+    env.add_icd(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none));
 
     VkDirectDriverLoadingInfoLUNARG ddl_info{};
     ddl_info.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
-    ddl_info.pfnGetInstanceProcAddr = env.icds.back().icd_library.get_symbol("vk_icdGetInstanceProcAddr");
+    ddl_info.pfnGetInstanceProcAddr = env.icds.back().library.get_symbol("vk_icdGetInstanceProcAddr");
 
     VkDirectDriverLoadingListLUNARG ddl_list{};
     ddl_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
@@ -733,18 +725,16 @@
     ddl_list.pDrivers = &ddl_info;
 
     const char* layer_name = "VK_LAYER_ImplicitAllocFail";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ENV")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ENV")));
     env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
     for (uint32_t i = 1; i < num_implicit_layers + 1; i++) {
-        env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                             .set_name("VK_LAYER_Implicit1" + std::to_string(i))
-                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                             .set_disable_environment("DISABLE_ENV")),
-                               "test_layer_" + std::to_string(i) + ".json");
+        env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                                 .set_name("VK_LAYER_Implicit1" + std::to_string(i))
+                                                                 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                                 .set_disable_environment("DISABLE_ENV")));
     }
     // Throw in a complex json file to flex the json allocation routines
     env.write_file_from_source(COMPLEX_JSON_FILE, ManifestCategory::explicit_layer, ManifestLocation::explicit_layer,
@@ -826,15 +816,14 @@
 // an incompatible driver exists
 TEST(TryLoadWrongBinaries, CreateInstanceIntentionalAllocFail) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("error,warn")};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
-    env.add_icd(TestICDDetails(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE).set_is_fake(true));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
+    env.add_icd(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE, ManifestOptions{}.set_is_fake(true));
 
     const char* layer_name = "VK_LAYER_implicit";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ENV")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ENV")));
     env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
 
     size_t fail_index = 0;
@@ -858,14 +847,13 @@
 // leak memory if one of the out-of-memory conditions trigger.
 TEST(Allocation, EnumeratePhysicalDevicesIntentionalAllocFail) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("error,warn")};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     const char* layer_name = "VK_LAYER_implicit";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ENV")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ENV")));
     env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
 
     size_t fail_index = 0;
@@ -878,7 +866,7 @@
         auto& driver = env.reset_icd();
 
         for (uint32_t i = 0; i < physical_dev_count; i++) {
-            driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i))
+            driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i))
                 .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, false});
         }
         MemoryTracker tracker{{false, 0, true, fail_index}};
@@ -900,7 +888,7 @@
         ASSERT_EQ(physical_dev_count, returned_physical_count);
 
         for (uint32_t i = 0; i < 2; i++) {
-            driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(physical_dev_count))
+            driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(physical_dev_count))
                 .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, false});
             physical_dev_count += 1;
         }
@@ -969,21 +957,20 @@
 // leak memory if one of the out-of-memory conditions trigger.
 TEST(Allocation, CreateInstanceDeviceWithDXGIDriverIntentionalAllocFail) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("error,warn")};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6).set_discovery_type(ManifestDiscoveryType::null_dir));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_6, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::null_dir));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     for (uint32_t i = 0; i < 2; i++) {
         auto& driver = env.get_test_icd(i);
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i))
+        driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i))
             .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, false});
     }
 
     const char* layer_name = "VK_LAYER_implicit";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ENV")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ENV")));
     env.get_test_layer().set_do_spurious_allocations_in_create_instance(true).set_do_spurious_allocations_in_create_device(true);
 
     auto& known_driver = known_driver_list.at(2);  // which drive this test pretends to be
diff --git a/tests/loader_debug_ext_tests.cpp b/tests/loader_debug_ext_tests.cpp
index aa6b7f0..240c3a0 100644
--- a/tests/loader_debug_ext_tests.cpp
+++ b/tests/loader_debug_ext_tests.cpp
@@ -52,9 +52,9 @@
     virtual void SetUp() {
         env = std::unique_ptr<FrameworkEnvironment>(new FrameworkEnvironment());
         for (uint32_t icd = 0; icd < 3; ++icd) {
-            env->add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_0));
-            env->get_test_icd(icd).physical_devices.push_back({});
-            env->get_test_icd(icd).physical_devices.push_back({});
+            env->add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+            env->get_test_icd(icd).add_physical_device({});
+            env->get_test_icd(icd).add_physical_device({});
         }
         // Initialize the expected output
         allow_any_message = false;
@@ -386,9 +386,9 @@
     virtual void SetUp() {
         env = std::unique_ptr<FrameworkEnvironment>(new FrameworkEnvironment());
         for (uint32_t icd = 0; icd < 3; ++icd) {
-            env->add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_0));
-            env->get_test_icd(icd).physical_devices.push_back({});
-            env->get_test_icd(icd).physical_devices.push_back({});
+            env->add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+            env->get_test_icd(icd).add_physical_device({});
+            env->get_test_icd(icd).add_physical_device({});
         }
         // Initialize the expected output
         allow_any_message = false;
@@ -1041,9 +1041,8 @@
 
 TEST(GetProcAddr, DebugFuncsWithTerminator) {
     FrameworkEnvironment env{};
-    auto& driver =
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).setup_WSI().add_physical_device("physical_device_0");
-    driver.physical_devices.at(0).add_extensions({"VK_KHR_swapchain"});
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).setup_WSI();
+    auto& phys_dev = driver.add_and_get_physical_device("physical_device_0").add_extensions({"VK_KHR_swapchain"});
     // Hardware doesn't support the debug extensions
 
     // Use getDeviceProcAddr & vary enabling the debug extensions
@@ -1056,7 +1055,7 @@
 
     // Now set the hardware to support the extensions and run the situations again
     driver.add_instance_extensions({"VK_EXT_debug_utils", "VK_EXT_debug_report"});
-    driver.physical_devices.at(0).add_extensions({"VK_EXT_debug_marker"});
+    phys_dev.add_extensions({"VK_EXT_debug_marker"});
 
     // Use getDeviceProcAddr & vary enabling the debug extensions
     ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false, true));
@@ -1069,9 +1068,10 @@
 
 TEST(GetProcAddr, DebugFuncsWithTrampoline) {
     FrameworkEnvironment env{};
-    auto& driver =
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).setup_WSI().add_physical_device("physical_device_0");
-    driver.physical_devices.at(0).add_extensions({"VK_KHR_swapchain"});
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)
+                       .setup_WSI()
+                       .add_and_get_physical_device("physical_device_0")
+                       .add_extensions({"VK_KHR_swapchain"});
     // Hardware doesn't support the debug extensions
 
     // Use getDeviceProcAddr & vary enabling the debug extensions
@@ -1083,14 +1083,13 @@
     ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, false));
 
     // Now add a layer that supports the extensions and run the situations again
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_test_layer")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")
-                                                         .add_instance_extensions({{VK_EXT_DEBUG_REPORT_EXTENSION_NAME},
-                                                                                   {VK_EXT_DEBUG_UTILS_EXTENSION_NAME}})
-                                                         .add_device_extension({VK_EXT_DEBUG_MARKER_EXTENSION_NAME})),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_test_layer")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")
+                                                             .add_instance_extensions({{VK_EXT_DEBUG_REPORT_EXTENSION_NAME},
+                                                                                       {VK_EXT_DEBUG_UTILS_EXTENSION_NAME}})
+                                                             .add_device_extension({VK_EXT_DEBUG_MARKER_EXTENSION_NAME})));
 
     // // Use getDeviceProcAddr & vary enabling the debug extensions
     ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false, true));
@@ -1103,9 +1102,10 @@
 
 TEST(GetProcAddr, DebugFuncsWithDebugExtsForceAdded) {
     FrameworkEnvironment env{};
-    auto& driver =
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).setup_WSI().add_physical_device("physical_device_0");
-    driver.physical_devices.at(0).add_extensions({"VK_KHR_swapchain"});
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)
+                       .setup_WSI()
+                       .add_and_get_physical_device("physical_device_0")
+                       .add_extensions({"VK_KHR_swapchain"});
     // Hardware doesn't support the debug extensions
 
     // Use getDeviceProcAddr & vary enabling the debug extensions
@@ -1117,11 +1117,10 @@
     ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, false));
 
     // Now add a layer that supports the extensions and run the situations again
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_test_layer")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_test_layer")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     env.get_test_layer()
         .add_injected_instance_extensions({{VK_EXT_DEBUG_REPORT_EXTENSION_NAME}, {VK_EXT_DEBUG_UTILS_EXTENSION_NAME}})
         .add_injected_device_extension({VK_EXT_DEBUG_MARKER_EXTENSION_NAME});
@@ -1137,18 +1136,17 @@
 
 TEST(DebugUtils, WrappingLayer) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
         .set_min_icd_interface_version(5)
         .add_physical_device(PhysicalDevice{}.add_extension(VK_EXT_DEBUG_MARKER_EXTENSION_NAME).finish())
         .add_instance_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
 
     const char* wrap_objects_name = "VK_LAYER_LUNARG_wrap_objects";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(wrap_objects_name)
-                                                         .set_lib_path(TEST_LAYER_WRAP_OBJECTS)
-                                                         .set_disable_environment("DISABLE_ME")
-                                                         .add_instance_extension({VK_EXT_DEBUG_UTILS_EXTENSION_NAME})),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(wrap_objects_name)
+                                                             .set_lib_path(TEST_LAYER_WRAP_OBJECTS)
+                                                             .set_disable_environment("DISABLE_ME")
+                                                             .add_instance_extension({VK_EXT_DEBUG_UTILS_EXTENSION_NAME})));
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
diff --git a/tests/loader_envvar_tests.cpp b/tests/loader_envvar_tests.cpp
index c94c2ec..19b8fa6 100644
--- a/tests/loader_envvar_tests.cpp
+++ b/tests/loader_envvar_tests.cpp
@@ -26,15 +26,18 @@
  * Author: Mark Young <markylunarg.com>
  */
 
+#include "manifest_builders.h"
 #include "test_environment.h"
 
+#include "util/wide_char_handling.h"
+
 // Don't support vk_icdNegotiateLoaderICDInterfaceVersion
 // Loader calls vk_icdGetInstanceProcAddr second
 // does not support vk_icdGetInstanceProcAddr
 // must export vkGetInstanceProcAddr, vkCreateInstance, vkEnumerateInstanceExtensionProperties
 TEST(EnvVarICDOverrideSetup, version_0_none) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_discovery_type(ManifestDiscoveryType::env_var));
+    env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var));
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -46,7 +49,7 @@
 // the loader calls vk_icdGetInstanceProcAddr first
 TEST(EnvVarICDOverrideSetup, version_1_icd_gipa) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_ICD_GIPA).set_discovery_type(ManifestDiscoveryType::env_var));
+    env.add_icd(TEST_ICD_PATH_EXPORT_ICD_GIPA, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var));
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -57,8 +60,8 @@
 // support vk_icdNegotiateLoaderICDInterfaceVersion but not vk_icdGetInstanceProcAddr
 TEST(EnvVarICDOverrideSetup, version_negotiate_interface_version_death_test) {
     FrameworkEnvironment env{};
-    env.add_icd(
-        TestICDDetails(TEST_ICD_PATH_EXPORT_NEGOTIATE_INTERFACE_VERSION).set_discovery_type(ManifestDiscoveryType::env_var));
+    env.add_icd(TEST_ICD_PATH_EXPORT_NEGOTIATE_INTERFACE_VERSION,
+                ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var));
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
@@ -67,7 +70,7 @@
 // export vk_icdNegotiateLoaderICDInterfaceVersion and vk_icdGetInstanceProcAddr
 TEST(EnvVarICDOverrideSetup, version_2_negotiate_interface_version_and_icd_gipa) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).set_discovery_type(ManifestDiscoveryType::env_var));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var));
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -78,9 +81,10 @@
 // export vk_icdNegotiateLoaderICDInterfaceVersion and vk_icdGetInstanceProcAddr
 TEST(EnvVarICDOverrideSetup, version_2_negotiate_interface_version_and_icd_gipa_unicode) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(widen(TEST_ICD_PATH_VERSION_2_UNICODE))
+    env.add_icd(widen(TEST_ICD_PATH_VERSION_2_UNICODE),
+                ManifestOptions{}
                     .set_discovery_type(ManifestDiscoveryType::env_var)
-                    .set_json_name(widen(TEST_JSON_NAME_VERSION_2_UNICODE)));
+                    .set_json_name(widen(std::string(TEST_JSON_NAME_VERSION_2_UNICODE) + ".json")));
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -91,7 +95,7 @@
 // Test VK_DRIVER_FILES environment variable
 TEST(EnvVarICDOverrideSetup, TestOnlyDriverEnvVar) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_discovery_type(ManifestDiscoveryType::env_var));
+    env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var));
     env.get_test_icd(0).add_physical_device("pd0");
 
     InstWrapper inst1{env.vulkan_functions};
@@ -106,7 +110,7 @@
     ASSERT_EQ(phys_dev_count, 1U);
 
     for (uint32_t add = 0; add < 2; ++add) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_discovery_type(ManifestDiscoveryType::env_var))
+        env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var))
             .add_physical_device("pd" + std::to_string(add) + "0")
             .add_physical_device("pd" + std::to_string(add) + "1");
     }
@@ -120,24 +124,31 @@
     phys_dev_count = 5;
     ASSERT_EQ(inst2->vkEnumeratePhysicalDevices(inst2.inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
     ASSERT_EQ(phys_dev_count, 5U);
+}
 
-    env.debug_log.clear();
+// Test VK_DRIVER_FILES environment variable with elelvated privileges
+TEST(EnvVarICDOverrideSetup, TestOnlyDriverEnvVarRunningWithElevatedPrivileges) {
+    FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)};
+    env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var));
+    env.get_test_icd(0).add_physical_device("pd0");
 
-    env.platform_shim->set_elevated_privilege(true);
+    for (uint32_t add = 0; add < 2; ++add) {
+        env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var))
+            .add_physical_device("pd" + std::to_string(add) + "0")
+            .add_physical_device("pd" + std::to_string(add) + "1");
+    }
 
-    InstWrapper inst3{env.vulkan_functions};
-    FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log);
-    inst3.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
+    InstWrapper inst{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
 
     EXPECT_TRUE(env.debug_log.find("vkCreateInstance: Found no drivers!"));
-
-    env.platform_shim->set_elevated_privilege(false);
 }
 
 // Test VK_DRIVER_FILES environment variable containing a path to a folder
 TEST(EnvVarICDOverrideSetup, TestOnlyDriverEnvVarInFolder) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_discovery_type(ManifestDiscoveryType::env_var).set_is_dir(false));
+    env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var).set_is_dir(true));
     env.get_test_icd(0).add_physical_device("pd0");
 
     InstWrapper inst1{env.vulkan_functions};
@@ -152,39 +163,42 @@
     ASSERT_EQ(phys_dev_count, 1U);
 
     for (uint32_t add = 0; add < 2; ++add) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_discovery_type(ManifestDiscoveryType::env_var))
+        env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var))
             .add_physical_device("pd" + std::to_string(add) + "0")
             .add_physical_device("pd" + std::to_string(add) + "1");
     }
 
-    env.debug_log.clear();
-
     InstWrapper inst2{env.vulkan_functions};
-    FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
     inst2.CheckCreate();
 
     phys_dev_count = 5;
     ASSERT_EQ(inst2->vkEnumeratePhysicalDevices(inst2.inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
     ASSERT_EQ(phys_dev_count, 5U);
+}
+// Test VK_DRIVER_FILES environment variable containing a path to a folder  with elevated privileges
+TEST(EnvVarICDOverrideSetup, TestOnlyDriverEnvVarInFolderWithElevatedPrivileges) {
+    FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)};
+    env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var).set_is_dir(true));
+    env.get_test_icd(0).add_physical_device("pd0");
 
-    env.debug_log.clear();
+    for (uint32_t add = 0; add < 2; ++add) {
+        env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var))
+            .add_physical_device("pd" + std::to_string(add) + "0")
+            .add_physical_device("pd" + std::to_string(add) + "1");
+    }
 
-    env.platform_shim->set_elevated_privilege(true);
-
-    InstWrapper inst3{env.vulkan_functions};
-    FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log);
-    inst3.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
+    InstWrapper inst{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
 
     EXPECT_TRUE(env.debug_log.find("vkCreateInstance: Found no drivers!"));
-
-    env.platform_shim->set_elevated_privilege(false);
 }
 
 #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__GNU__) || defined(__QNX__)
 // Make sure the loader reports the correct message based on if LOADER_USE_UNSAFE_FILE_SEARCH is set or not
 TEST(EnvVarICDOverrideSetup, NonSecureEnvVarLookup) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
 
     DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT};
     InstWrapper inst{env.vulkan_functions};
@@ -203,15 +217,14 @@
     // Set up a layer path that includes default and user-specified locations,
     // so that the test app can find them.  Include some badly specified elements as well.
     // Need to redirect the 'home' directory
-    std::filesystem::path HOME = "/home/fake_home";
-    EnvVarWrapper home_env_var{"HOME", HOME};
-    EnvVarWrapper xdg_config_dirs_env_var{"XDG_CONFIG_DIRS", ":/tmp/goober:::::/tmp/goober/::::"};
-    EnvVarWrapper xdg_config_home_env_var{"XDG_CONFIG_HOME", ":/tmp/goober:::::/tmp/goober2/::::"};
-    EnvVarWrapper xdg_data_dirs_env_var{"XDG_DATA_DIRS", "::::/tmp/goober3:/tmp/goober4/with spaces:::"};
-    EnvVarWrapper xdg_data_home_env_var{"XDG_DATA_HOME", "::::/tmp/goober3:/tmp/goober4/with spaces:::"};
 
-    FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0");
+    FrameworkEnvironment env{FrameworkSettings{}
+                                 .set_home_env_var("/home/fake_home")
+                                 .set_xdg_config_dirs_env_var(":/tmp/goober:::::/tmp/goober/::::")
+                                 .set_xdg_config_home_env_var(":/tmp/goober:::::/tmp/goober2/::::")
+                                 .set_xdg_data_dirs_env_var("::::/tmp/goober3:/tmp/goober4/with spaces:::")
+                                 .set_xdg_data_home_env_var("::::/tmp/goober3:/tmp/goober4/with spaces:::")};
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
 
     InstWrapper inst{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
@@ -232,10 +245,8 @@
     // Set up a layer path that includes default and user-specified locations,
     // so that the test app can find them.  Include some badly specified elements as well.
     // Need to redirect the 'home' directory
-    EnvVarWrapper xdg_config_dirs_env_var{"XDG_CONFIG_DIRS", "bad_file.json"};
-
-    FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0");
+    FrameworkEnvironment env{FrameworkSettings{}.set_xdg_config_dirs_env_var("bad_file.json")};
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
 
     InstWrapper inst{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
@@ -246,27 +257,30 @@
 // Test VK_ADD_DRIVER_FILES environment variable
 TEST(EnvVarICDOverrideSetup, TestOnlyAddDriverEnvVar) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_discovery_type(ManifestDiscoveryType::add_env_var));
-    env.get_test_icd(0).physical_devices.emplace_back("pd0");
+    env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var));
+    env.get_test_icd(0).add_and_get_physical_device("pd0");
 
-    InstWrapper inst1{env.vulkan_functions};
-    FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
-    inst1.CheckCreate();
+    InstWrapper inst{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
 
     std::array<VkPhysicalDevice, 1> phys_devs_array;
     uint32_t phys_dev_count = 1;
-    ASSERT_EQ(inst1->vkEnumeratePhysicalDevices(inst1.inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
+    ASSERT_EQ(inst->vkEnumeratePhysicalDevices(inst.inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
     ASSERT_EQ(phys_dev_count, 1U);
+}
 
-    env.platform_shim->set_elevated_privilege(true);
+// Test VK_ADD_DRIVER_FILES environment variable with elelvated privileges
+TEST(EnvVarICDOverrideSetup, TestOnlyAddDriverEnvVarRunningWithElevatedPrivileges) {
+    FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)};
+    env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var));
+    env.get_test_icd(0).add_and_get_physical_device("pd0");
 
-    InstWrapper inst2{env.vulkan_functions};
-    FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
-    inst2.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
+    InstWrapper inst{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
 
     EXPECT_TRUE(env.debug_log.find("vkCreateInstance: Found no drivers!"));
-
-    env.platform_shim->set_elevated_privilege(false);
 }
 
 // Test Both VK_DRIVER_FILES and VK_ADD_DRIVER_FILES environment variable
@@ -274,10 +288,10 @@
     FrameworkEnvironment env{};
 
     // Add a driver that isn't enabled with the environment variable
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_discovery_type(ManifestDiscoveryType::env_var));
+    env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var));
     env.get_test_icd(0).add_physical_device("pd0").add_physical_device("pd1");
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_discovery_type(ManifestDiscoveryType::add_env_var));
+    env.add_icd(TEST_ICD_PATH_EXPORT_NONE, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var));
     env.get_test_icd(0).add_physical_device("pd2");
 
     InstWrapper inst{env.vulkan_functions};
@@ -294,15 +308,14 @@
 // Test VK_LAYER_PATH environment variable
 TEST(EnvVarICDOverrideSetup, TestOnlyLayerEnvVar) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0");
-    env.platform_shim->redirect_path("/tmp/carol", env.get_folder(ManifestLocation::explicit_layer_env_var).location());
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
+    env.file_system_manager.add_path_redirect("/tmp/carol", ManifestLocation::explicit_layer_env_var);
 
     const char* layer_name = "TestLayer";
     env.add_explicit_layer(
-        TestLayerDetails(ManifestLayer{}.add_layer(
-                             ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                         "test_layer.json")
-            .set_discovery_type(ManifestDiscoveryType::env_var));
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     // Now set up a layer path that includes default and user-specified locations,
     // so that the test app can find them.  Include some badly specified elements as well.
@@ -312,42 +325,56 @@
     std::string vk_layer_path = ":/tmp/carol::::/:";
     vk_layer_path += (HOME / "/ with spaces/:::::/tandy:");
     EnvVarWrapper layer_path_env_var{"VK_LAYER_PATH", vk_layer_path};
-    InstWrapper inst1{env.vulkan_functions};
-    inst1.create_info.add_layer(layer_name);
-    FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
-    inst1.CheckCreate();
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.add_layer(layer_name);
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
 
     // look for VK_LAYER_PATHS
     EXPECT_TRUE(env.debug_log.find("/tmp/carol"));
     EXPECT_TRUE(env.debug_log.find("/tandy"));
     EXPECT_TRUE(env.debug_log.find((HOME / "/ with spaces/")));
+}
+// Test VK_LAYER_PATH environment variable with elevated privileges
+TEST(EnvVarICDOverrideSetup, TestOnlyLayerEnvVarRunningWithElevatedPrivileges) {
+    FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)};
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
+    env.file_system_manager.add_path_redirect("/tmp/carol", ManifestLocation::explicit_layer_env_var);
 
-    env.debug_log.clear();
+    const char* layer_name = "TestLayer";
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
-    env.platform_shim->set_elevated_privilege(true);
+    // Now set up a layer path that includes default and user-specified locations,
+    // so that the test app can find them.  Include some badly specified elements as well.
+    // Need to redirect the 'home' directory
+    std::filesystem::path HOME = "/home/fake_home";
+    EnvVarWrapper home_env_var{"HOME", HOME};
+    std::string vk_layer_path = ":/tmp/carol::::/:";
+    vk_layer_path += (HOME / "/ with spaces/:::::/tandy:");
+    EnvVarWrapper layer_path_env_var{"VK_LAYER_PATH", vk_layer_path};
 
-    InstWrapper inst2{env.vulkan_functions};
-    inst2.create_info.add_layer(layer_name);
-    FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
-    inst2.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.add_layer(layer_name);
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
 
     EXPECT_FALSE(env.debug_log.find("/tmp/carol"));
-
-    env.platform_shim->set_elevated_privilege(false);
 }
 
 // Test VK_ADD_LAYER_PATH environment variable
 TEST(EnvVarICDOverrideSetup, TestOnlyAddLayerEnvVar) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0");
-    env.platform_shim->redirect_path("/tmp/carol", env.get_folder(ManifestLocation::explicit_layer_add_env_var).location());
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
+    env.file_system_manager.add_path_redirect("/tmp/carol", ManifestLocation::explicit_layer_add_env_var);
 
     const char* layer_name = "TestLayer";
     env.add_explicit_layer(
-        TestLayerDetails(ManifestLayer{}.add_layer(
-                             ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                         "test_layer.json")
-            .set_discovery_type(ManifestDiscoveryType::add_env_var));
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     // Set up a layer path that includes default and user-specified locations,
     // so that the test app can find them.  Include some badly specified elements as well.
@@ -358,43 +385,58 @@
     vk_layer_path += (HOME / "/ with spaces/:::::/tandy:");
     EnvVarWrapper add_layer_path_env_var{"VK_ADD_LAYER_PATH", vk_layer_path};
 
-    InstWrapper inst1{env.vulkan_functions};
-    inst1.create_info.add_layer(layer_name);
-    FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
-    inst1.CheckCreate();
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.add_layer(layer_name);
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
 
     // look for VK_ADD_LAYER_PATHS
     EXPECT_TRUE(env.debug_log.find("/tmp/carol"));
     EXPECT_TRUE(env.debug_log.find("/tandy"));
     EXPECT_TRUE(env.debug_log.find((HOME / "/ with spaces/")));
+}
 
-    env.debug_log.clear();
+// Test VK_ADD_LAYER_PATH environment variable with elevated privileges
+TEST(EnvVarICDOverrideSetup, TestOnlyAddLayerEnvVarRunningWithElevatedPrivileges) {
+    FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)};
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
+    env.file_system_manager.add_path_redirect("/tmp/carol", ManifestLocation::explicit_layer_add_env_var);
 
-    env.platform_shim->set_elevated_privilege(true);
+    const char* layer_name = "TestLayer";
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
-    InstWrapper inst2{env.vulkan_functions};
-    inst2.create_info.add_layer(layer_name);
-    FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
-    inst2.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
+    // Set up a layer path that includes default and user-specified locations,
+    // so that the test app can find them.  Include some badly specified elements as well.
+    // Need to redirect the 'home' directory
+    std::filesystem::path HOME = "/home/fake_home";
+    EnvVarWrapper home_env_var{"HOME", HOME};
+    std::string vk_layer_path = ":/tmp/carol::::/:";
+    vk_layer_path += (HOME / "/ with spaces/:::::/tandy:");
+    EnvVarWrapper add_layer_path_env_var{"VK_ADD_LAYER_PATH", vk_layer_path};
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.add_layer(layer_name);
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
 
     EXPECT_FALSE(env.debug_log.find("/tmp/carol"));
-
-    env.platform_shim->set_elevated_privilege(false);
 }
 
 // Test VK_IMPLICIT_LAYER_PATH environment variable
 TEST(EnvVarICDOverrideSetup, TestOnlyImplicitLayerEnvVar) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0");
-    env.platform_shim->redirect_path("/tmp/carol", env.get_folder(ManifestLocation::implicit_layer_env_var).location());
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
+    env.file_system_manager.add_path_redirect("/tmp/carol", ManifestLocation::implicit_layer_env_var);
 
     const char* layer_name = "TestLayer";
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("DISABLE_ENV")),
-                                            "test_layer.json")
-                               .set_discovery_type(ManifestDiscoveryType::env_var));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("DISABLE_ENV")));
 
     // Now set up a layer path that includes default and user-specified locations,
     // so that the test app can find them.  Include some badly specified elements as well.
@@ -404,47 +446,63 @@
     std::string vk_implicit_layer_path = ":/tmp/carol::::/:";
     vk_implicit_layer_path += (HOME / "/ with spaces/:::::/tandy:");
     EnvVarWrapper implicit_layer_path_env_var{"VK_IMPLICIT_LAYER_PATH", vk_implicit_layer_path};
-    InstWrapper inst1{env.vulkan_functions};
-    FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
-    inst1.CheckCreate();
+    InstWrapper inst{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
 
-    auto active_layers1 = inst1.GetActiveLayers(inst1.GetPhysDev(), 1);
-    ASSERT_TRUE(string_eq(active_layers1.at(0).layerName, layer_name));
+    auto active_layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
+    ASSERT_TRUE(string_eq(active_layers.at(0).layerName, layer_name));
 
     // look for VK_IMPLICIT_LAYER_PATHS
     EXPECT_TRUE(env.debug_log.find("/tmp/carol"));
     EXPECT_TRUE(env.debug_log.find("/tandy"));
     EXPECT_TRUE(env.debug_log.find((HOME / "/ with spaces/")));
+}
 
-    env.debug_log.clear();
+// Test VK_IMPLICIT_LAYER_PATH environment variable run with elevated privileges
+TEST(EnvVarICDOverrideSetup, TestOnlyImplicitLayerEnvVarRunningWithElevatedPrivileges) {
+    FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)};
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
+    env.file_system_manager.add_path_redirect("/tmp/carol", ManifestLocation::implicit_layer_env_var);
 
-    env.platform_shim->set_elevated_privilege(true);
+    const char* layer_name = "TestLayer";
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("DISABLE_ENV")));
 
-    InstWrapper inst2{env.vulkan_functions};
-    FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
-    inst2.CheckCreate();
+    // Now set up a layer path that includes default and user-specified locations,
+    // so that the test app can find them.  Include some badly specified elements as well.
+    // Need to redirect the 'home' directory
+    std::filesystem::path HOME = "/home/fake_home";
+    EnvVarWrapper home_env_var{"HOME", HOME};
+    std::string vk_implicit_layer_path = ":/tmp/carol::::/:";
+    vk_implicit_layer_path += (HOME / "/ with spaces/:::::/tandy:");
+    EnvVarWrapper implicit_layer_path_env_var{"VK_IMPLICIT_LAYER_PATH", vk_implicit_layer_path};
 
-    auto active_layers2 = inst2.GetActiveLayers(inst2.GetPhysDev(), 0);
-    ASSERT_TRUE(active_layers2.empty());
+    InstWrapper inst{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
+
+    auto active_layers = inst.GetActiveLayers(inst.GetPhysDev(), 0);
+    ASSERT_TRUE(active_layers.empty());
 
     EXPECT_FALSE(env.debug_log.find("/tmp/carol"));
-
-    env.platform_shim->set_elevated_privilege(false);
 }
 
 // Test VK_ADD_IMPLICIT_LAYER_PATH environment variable
 TEST(EnvVarICDOverrideSetup, TestOnlyAddImplicitLayerEnvVar) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0");
-    env.platform_shim->redirect_path("/tmp/carol", env.get_folder(ManifestLocation::implicit_layer_add_env_var).location());
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
+    env.file_system_manager.add_path_redirect("/tmp/carol", ManifestLocation::implicit_layer_add_env_var);
 
     const char* layer_name = "TestLayer";
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("DISABLE_ENV")),
-                                            "test_layer.json")
-                               .set_discovery_type(ManifestDiscoveryType::add_env_var));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("DISABLE_ENV")));
 
     // Set up a layer path that includes default and user-specified locations,
     // so that the test app can find them.  Include some badly specified elements as well.
@@ -453,7 +511,7 @@
     EnvVarWrapper home_env_var{"HOME", HOME};
     std::string vk_add_implicit_layer_path = ":/tmp/carol::::/:";
     vk_add_implicit_layer_path += (HOME / "/ with spaces/:::::/tandy:");
-    EnvVarWrapper add_implicit_layer_path_env_var{"VK_ADD_LAYER_PATH", vk_add_implicit_layer_path};
+    EnvVarWrapper add_implicit_layer_path_env_var{"VK_ADD_IMPLICIT_LAYER_PATH", vk_add_implicit_layer_path};
 
     InstWrapper inst1{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
@@ -466,21 +524,38 @@
     EXPECT_TRUE(env.debug_log.find("/tmp/carol"));
     EXPECT_TRUE(env.debug_log.find("/tandy"));
     EXPECT_TRUE(env.debug_log.find((HOME / "/ with spaces/")));
+}
 
-    env.debug_log.clear();
+// Test VK_ADD_IMPLICIT_LAYER_PATH environment variable running with elevated privileges
+TEST(EnvVarICDOverrideSetup, TestOnlyAddImplicitLayerEnvVarWithElevatedPrivileges) {
+    FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)};
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
+    env.file_system_manager.add_path_redirect("/tmp/carol", ManifestLocation::implicit_layer_add_env_var);
 
-    env.platform_shim->set_elevated_privilege(true);
+    const char* layer_name = "TestLayer";
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("DISABLE_ENV")));
 
-    InstWrapper inst2{env.vulkan_functions};
-    FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
-    inst2.CheckCreate();
+    // Set up a layer path that includes default and user-specified locations,
+    // so that the test app can find them.  Include some badly specified elements as well.
+    // Need to redirect the 'home' directory
+    std::filesystem::path HOME = "/home/fake_home";
+    EnvVarWrapper home_env_var{"HOME", HOME};
+    std::string vk_add_implicit_layer_path = ":/tmp/carol::::/:";
+    vk_add_implicit_layer_path += (HOME / "/ with spaces/:::::/tandy:");
+    EnvVarWrapper add_implicit_layer_path_env_var{"VK_ADD_IMPLICIT_LAYER_PATH", vk_add_implicit_layer_path};
 
-    auto active_layers2 = inst2.GetActiveLayers(inst2.GetPhysDev(), 0);
-    ASSERT_TRUE(active_layers2.empty());
+    InstWrapper inst{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
+
+    auto active_layers = inst.GetActiveLayers(inst.GetPhysDev(), 0);
+    ASSERT_TRUE(active_layers.empty());
 
     EXPECT_FALSE(env.debug_log.find("/tmp/carol"));
-
-    env.platform_shim->set_elevated_privilege(false);
 }
 
 #endif
@@ -490,9 +565,11 @@
     FrameworkEnvironment env{};
     EnvVarWrapper filter_select_env_var{"VK_LOADER_DRIVERS_SELECT"};
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6).set_disable_icd_inc(true).set_json_name("ABC_ICD"));
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_6, VK_API_VERSION_1_2}.set_disable_icd_inc(true).set_json_name("BCD_ICD"));
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_6, VK_API_VERSION_1_3}.set_disable_icd_inc(true).set_json_name("CDE_ICD"));
+    env.add_icd(TEST_ICD_PATH_VERSION_6, ManifestOptions{}.set_json_name("ABC_ICD.json"));
+    env.add_icd(TEST_ICD_PATH_VERSION_6, ManifestOptions{}.set_json_name("BCD_ICD.json"),
+                ManifestICD{}.set_api_version(VK_API_VERSION_1_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_6, ManifestOptions{}.set_json_name("CDE_ICD.json"),
+                ManifestICD{}.set_api_version(VK_API_VERSION_1_3));
 
     InstWrapper inst1{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
@@ -640,9 +717,11 @@
     FrameworkEnvironment env{};
     EnvVarWrapper filter_disable_env_var{"VK_LOADER_DRIVERS_DISABLE"};
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6).set_disable_icd_inc(true).set_json_name("ABC_ICD"));
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_6, VK_API_VERSION_1_2}.set_disable_icd_inc(true).set_json_name("BCD_ICD"));
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_6, VK_API_VERSION_1_3}.set_disable_icd_inc(true).set_json_name("CDE_ICD"));
+    env.add_icd(TEST_ICD_PATH_VERSION_6, ManifestOptions{}.set_json_name("ABC_ICD.json"));
+    env.add_icd(TEST_ICD_PATH_VERSION_6, ManifestOptions{}.set_json_name("BCD_ICD.json"),
+                ManifestICD{}.set_api_version(VK_API_VERSION_1_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_6, ManifestOptions{}.set_json_name("CDE_ICD.json"),
+                ManifestICD{}.set_api_version(VK_API_VERSION_1_3));
 
     InstWrapper inst1{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
@@ -774,9 +853,11 @@
     EnvVarWrapper filter_disable_env_var{"VK_LOADER_DRIVERS_DISABLE"};
     EnvVarWrapper filter_select_env_var{"VK_LOADER_DRIVERS_SELECT"};
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6).set_disable_icd_inc(true).set_json_name("ABC_ICD"));
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_6, VK_API_VERSION_1_2}.set_disable_icd_inc(true).set_json_name("BCD_ICD"));
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_6, VK_API_VERSION_1_3}.set_disable_icd_inc(true).set_json_name("CDE_ICD"));
+    env.add_icd(TEST_ICD_PATH_VERSION_6, ManifestOptions{}.set_json_name("ABC_ICD.json"));
+    env.add_icd(TEST_ICD_PATH_VERSION_6, ManifestOptions{}.set_json_name("BCD_ICD.json"),
+                ManifestICD{}.set_api_version(VK_API_VERSION_1_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_6, ManifestOptions{}.set_json_name("CDE_ICD.json"),
+                ManifestICD{}.set_api_version(VK_API_VERSION_1_3));
 
     InstWrapper inst1{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
diff --git a/tests/loader_fuzz_tests.cpp b/tests/loader_fuzz_tests.cpp
index 897e69a..50dedcd 100644
--- a/tests/loader_fuzz_tests.cpp
+++ b/tests/loader_fuzz_tests.cpp
@@ -25,7 +25,15 @@
  * Author: Charles Giessen <charles@lunarg.com>
  */
 
-#include "test_environment.h"
+#include "framework/test_environment.h"
+
+#include <fstream>
+
+extern "C" {
+#include "loader.h"
+#include "loader_json.h"
+#include "settings.h"
+}
 
 void execute_instance_enumerate_fuzzer(std::filesystem::path const& filename) {
     FrameworkEnvironment env{};
@@ -34,19 +42,15 @@
     env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
                                ManifestCategory::settings, ManifestLocation::settings_location, "vk_loader_settings.json");
 
-    uint32_t pPropertyCount;
+    uint32_t pPropertyCount = 1;
     VkExtensionProperties pProperties = {0};
 
     env.vulkan_functions.vkEnumerateInstanceExtensionProperties("test_auto", &pPropertyCount, &pProperties);
 }
-void execute_instance_create_fuzzer(std::filesystem::path const& filename) {
-    FrameworkEnvironment env{};
-    env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
-                               ManifestCategory::implicit_layer, ManifestLocation::implicit_layer, "complex_layer.json");
-    env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
-                               ManifestCategory::settings, ManifestLocation::settings_location, "vk_loader_settings.json");
-    env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
-                               ManifestCategory::icd, ManifestLocation::driver, "icd_test.json");
+// Common code for execute_instance_create_fuzzer and execute_instance_create_fuzzer_advanced
+void execute_instance_create_fuzzer_logic(FrameworkEnvironment& env) {
+    EnvVarWrapper enable_all_layers("VK_LOADER_LAYERS_ENABLE", "all");
+
     VkInstance inst = {0};
     const char* instance_layers[] = {"VK_LAYER_KHRONOS_validation", "VK_LAYER_test_layer_1", "VK_LAYER_test_layer_2"};
     VkApplicationInfo app{};
@@ -75,13 +79,72 @@
     env.vulkan_functions.vkDestroyInstance(inst, NULL);
 }
 
-void execute_json_load_fuzzer(std::filesystem::path const& filename) {
+void execute_instance_create_fuzzer(std::filesystem::path const& filename) {
+    FrameworkEnvironment env{};
+    env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
+                               ManifestCategory::implicit_layer, ManifestLocation::unsecured_implicit_layer, "complex_layer.json");
+    env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
+                               ManifestCategory::settings, ManifestLocation::unsecured_settings, "vk_loader_settings.json");
+    env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
+                               ManifestCategory::icd, ManifestLocation::unsecured_driver, "icd_test.json");
+
+    execute_instance_create_fuzzer_logic(env);
+}
+
+void execute_instance_create_advanced_fuzzer(std::filesystem::path const& filename) {
     FrameworkEnvironment env{};
 
-    env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
-                               ManifestCategory::explicit_layer, ManifestLocation::explicit_layer, "complex_layer.json");
-    uint32_t count = 0;
-    env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr);
+    // The file actually contains three subfiles with their lengths specified in the first 12 bytes of the file.
+    auto source_file = std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename;
+    std::fstream file{source_file.string(), std::ios_base::in | std::ios_base::binary};
+    ASSERT_TRUE(file.is_open());
+    std::stringstream file_stream;
+    file_stream << file.rdbuf();
+
+    auto data_string = file_stream.str();
+    auto data_cstring = data_string.c_str();
+    std::array<uint64_t, 3> sections;
+    memcpy(sections.data(), data_cstring, sizeof(uint64_t) * 3);
+    sections[0] = sections[0] % 40000;
+    sections[1] = sections[1] % 40000;
+    sections[2] = sections[2] % 40000;
+
+    uint64_t data_index = 3 * sizeof(uint64_t);
+    std::string first = data_string.substr(data_index, sections[0]);
+    data_index += sections[0];
+    std::string second = data_string.substr(data_index, sections[1]);
+    data_index += sections[1];
+    std::string third = data_string.substr(data_index, sections[2]);
+    data_index += sections[2];
+
+    env.platform_shim->fuzz_data.resize(data_string.size() - data_index);
+    memcpy(env.platform_shim->fuzz_data.data(), data_cstring + data_index, env.platform_shim->fuzz_data.size());
+
+    env.write_file_from_string(first, ManifestCategory::implicit_layer, ManifestLocation::implicit_layer, "complex_layer.json");
+    env.write_file_from_string(second, ManifestCategory::settings, ManifestLocation::settings_location, "vk_loader_settings.json");
+    env.write_file_from_string(third, ManifestCategory::settings, ManifestLocation::settings_location, "icd_test.json");
+
+    execute_instance_create_fuzzer_logic(env);
+}
+void execute_json_load_fuzzer(std::string const& filename) {
+    FrameworkEnvironment env{};
+
+    cJSON* json = NULL;
+    loader_get_json(NULL, filename.c_str(), &json);
+
+    if (json == NULL) {
+        return;
+    }
+    bool out_of_mem = false;
+    char* json_data = loader_cJSON_Print(json, &out_of_mem);
+
+    if (json_data != NULL) {
+        free(json_data);
+    }
+
+    if (json != NULL) {
+        loader_cJSON_Delete(json);
+    }
 }
 void execute_setting_fuzzer(std::filesystem::path const& filename) {
     FrameworkEnvironment env{};
@@ -89,8 +152,11 @@
     env.write_file_from_source((std::filesystem::path(CLUSTERFUZZ_TESTCASE_DIRECTORY) / filename).string().c_str(),
                                ManifestCategory::settings, ManifestLocation::settings_location, "vk_loader_settings.json");
 
-    uint32_t version = 0;
-    env.vulkan_functions.vkEnumerateInstanceVersion(&version);
+    update_global_loader_settings();
+    struct loader_layer_list settings_layers = {0};
+    bool should_search_for_other_layers = true;
+    get_settings_layers(NULL, &settings_layers, &should_search_for_other_layers);
+    loader_delete_layer_list_and_properties(NULL, &settings_layers);
 }
 
 TEST(BadJsonInput, ClusterFuzzTestCase_5599244505186304) {
@@ -114,7 +180,9 @@
     // Nullptr dereference in loader_copy_to_new_str
     execute_instance_enumerate_fuzzer("clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6583684169269248");
 }
-
+TEST(BadJsonInput, ClusterFuzzTestCase_6470575830925312) {
+    execute_instance_enumerate_fuzzer("clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6470575830925312");
+}
 TEST(BadJsonInput, ClusterFuzzTestCase_5258042868105216) {
     // Doesn't crash with ASAN or UBSAN
     // Doesn't reproducibly crash - json_load_fuzzer: Abrt in loader_cJSON_Delete
@@ -179,12 +247,28 @@
     // Stack overflow due to recursive meta layers
     execute_instance_create_fuzzer("clusterfuzz-testcase-minimized-instance_create_fuzzer-6353004288081920");
 }
+TEST(BadJsonInput, ClusterFuzzTestCase_5817896795701248) {
+    execute_instance_create_fuzzer("clusterfuzz-testcase-instance_create_fuzzer-5817896795701248");
+}
+TEST(BadJsonInput, ClusterFuzzTestCase_6541440380895232) {
+    execute_instance_create_fuzzer("clusterfuzz-testcase-instance_create_fuzzer-6541440380895232");
+}
+TEST(BadJsonInput, ClusterFuzzTestCase_5612556809207808) {
+    execute_instance_create_advanced_fuzzer("clusterfuzz-testcase-minimized-instance_create_advanced_fuzzer-5612556809207808");
+}
+TEST(BadJsonInput, ClusterFuzzTestCase_4788849181261824) {
+    execute_instance_create_advanced_fuzzer("clusterfuzz-testcase-minimized-instance_create_advanced_fuzzer-4788849181261824");
+}
 TEST(BadJsonInput, ClusterFuzzTestCase_6465902356791296) {
     // Does crash with UBSAN
     // Doesn't crash with ASAN
     // Causes an integer overflow - instance_enumerate_fuzzer: Integer-overflow in parse_value
     execute_instance_enumerate_fuzzer("clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6465902356791296");
 }
+TEST(BadJsonInput, ClusterFuzzTestCase_6740380288876544) {
+    // Does crash with ASAN
+    execute_instance_enumerate_fuzzer("clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6740380288876544");
+}
 TEST(BadJsonInput, ClusterFuzzTestCase_4512865114259456) {
     // Does crash with UBSAN and ASAN
     // malloc(): invalid size (unsorted)
@@ -254,3 +338,6 @@
     // Causes a leak - settings_fuzzer: Direct-leak in loader_append_layer_property
     execute_setting_fuzzer("clusterfuzz-testcase-minimized-settings_fuzzer-5123849246867456");
 }
+TEST(BadJsonInput, ClusterFuzzTestCase_4626669072875520) {
+    execute_setting_fuzzer("clusterfuzz-testcase-minimized-settings_fuzzer-4626669072875520");
+}
diff --git a/tests/loader_get_proc_addr_tests.cpp b/tests/loader_get_proc_addr_tests.cpp
index a2fe578..89fa51a 100644
--- a/tests/loader_get_proc_addr_tests.cpp
+++ b/tests/loader_get_proc_addr_tests.cpp
@@ -30,7 +30,7 @@
 // Verify that the various ways to get vkGetInstanceProcAddr return the same value
 TEST(GetProcAddr, VerifyGetInstanceProcAddr) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
     {
         InstWrapper inst{env.vulkan_functions};
         inst.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -61,7 +61,7 @@
 // Verify that the various ways to get vkGetDeviceProcAddr return the same value
 TEST(GetProcAddr, VerifyGetDeviceProcAddr) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -85,7 +85,7 @@
 // Call the function to make sure it is callable, don't care about what is returned.
 TEST(GetProcAddr, GlobalFunctions) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
 
     auto& gipa = env.vulkan_functions.vkGetInstanceProcAddr;
     // global entry points with NULL instance handle
@@ -180,7 +180,7 @@
 
 TEST(GetProcAddr, Verify10FunctionsFailToLoadWithSingleDriver) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({}).set_can_query_GetPhysicalDeviceFuncs(false);
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_can_query_GetPhysicalDeviceFuncs(false);
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
@@ -188,8 +188,8 @@
 
 TEST(GetProcAddr, Verify10FunctionsLoadWithMultipleDrivers) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({}).set_can_query_GetPhysicalDeviceFuncs(false);
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_can_query_GetPhysicalDeviceFuncs(false);
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -202,8 +202,8 @@
 // and return VK_SUCCESS to maintain previous behavior.
 TEST(GetDeviceProcAddr, SwapchainFuncsWithTerminator) {
     FrameworkEnvironment env{};
-    auto& driver =
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).setup_WSI().add_physical_device("physical_device_0");
+    auto& test_physical_device =
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).setup_WSI().add_and_get_physical_device("physical_device_0");
 
     InstWrapper inst(env.vulkan_functions);
     inst.create_info.add_extension("VK_EXT_debug_utils");
@@ -250,7 +250,7 @@
         log.logger.clear();
         ASSERT_FALSE(dev_funcs.vkDestroySwapchainKHR);
     }
-    driver.physical_devices.at(0).add_extensions({"VK_KHR_swapchain", "VK_KHR_display_swapchain", "VK_EXT_debug_marker"});
+    test_physical_device.add_extensions({"VK_KHR_swapchain", "VK_KHR_display_swapchain", "VK_EXT_debug_marker"});
     {
         DeviceWrapper dev{inst};
         dev.create_info.add_extensions({"VK_KHR_swapchain", "VK_KHR_display_swapchain", "VK_EXT_debug_marker"});
@@ -303,14 +303,13 @@
 // Verify that the various ways to get vkGetDeviceProcAddr return the same value
 TEST(GetProcAddr, PreserveLayerGettingVkCreateDeviceWithNullInstance) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
 
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name("VK_LAYER_technically_buggy_layer")
-                                                                          .set_description("actually_layer_1")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("if_you_can")),
-                                            "buggy_layer_1.json"));
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_technically_buggy_layer")
+                                                             .set_description("actually_layer_1")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("if_you_can")));
     env.get_test_layer().set_buggy_query_of_vkCreateDevice(true);
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -328,15 +327,15 @@
 
 TEST(GetDeviceProcAddr, AppQueries11FunctionsWhileOnlyEnabling10) {
     FrameworkEnvironment env{};
-    auto& driver =
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
+    auto& test_physical_device =
+        env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
             .set_icd_api_version(VK_API_VERSION_1_1)
-            .add_physical_device(
+            .add_and_get_physical_device(
                 PhysicalDevice{}.set_api_version(VK_API_VERSION_1_1).add_extension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME).finish());
 
     std::vector<const char*> functions = {"vkGetDeviceQueue2", "vkCmdDispatchBase", "vkCreateDescriptorUpdateTemplate"};
     for (const auto& f : functions) {
-        driver.physical_devices.back().add_device_function(VulkanFunction{f, [] {}});
+        test_physical_device.add_device_function(VulkanFunction{f, [] {}});
     }
     {  // doesn't enable the feature or extension
         InstWrapper inst{env.vulkan_functions};
@@ -382,15 +381,15 @@
 
 TEST(GetDeviceProcAddr, AppQueries12FunctionsWhileOnlyEnabling11) {
     FrameworkEnvironment env{};
-    auto& driver =
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2))
+    auto& test_physical_device =
+        env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
             .set_icd_api_version(VK_API_VERSION_1_2)
-            .add_physical_device(
+            .add_and_get_physical_device(
                 PhysicalDevice{}.set_api_version(VK_API_VERSION_1_2).add_extension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME).finish());
     std::vector<const char*> functions = {"vkCmdDrawIndirectCount", "vkCmdNextSubpass2", "vkGetBufferDeviceAddress",
                                           "vkGetDeviceMemoryOpaqueCaptureAddress"};
     for (const auto& f : functions) {
-        driver.physical_devices.back().add_device_function(VulkanFunction{f, [] {}});
+        test_physical_device.add_device_function(VulkanFunction{f, [] {}});
     }
     {  // doesn't enable the feature or extension
         InstWrapper inst{env.vulkan_functions};
@@ -439,16 +438,16 @@
 
 TEST(GetDeviceProcAddr, AppQueries13FunctionsWhileOnlyEnabling12) {
     FrameworkEnvironment env{};
-    auto& driver =
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_3))
+    auto& test_physical_device =
+        env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_3))
             .set_icd_api_version(VK_API_VERSION_1_3)
-            .add_physical_device(
+            .add_and_get_physical_device(
                 PhysicalDevice{}.set_api_version(VK_API_VERSION_1_3).add_extension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME).finish());
     std::vector<const char*> functions = {"vkCreatePrivateDataSlot", "vkGetDeviceBufferMemoryRequirements", "vkCmdWaitEvents2",
                                           "vkGetDeviceImageSparseMemoryRequirements"};
 
     for (const auto& f : functions) {
-        driver.physical_devices.back().add_device_function(VulkanFunction{f, [] {}});
+        test_physical_device.add_device_function(VulkanFunction{f, [] {}});
     }
     {  // doesn't enable the feature or extension
         InstWrapper inst{env.vulkan_functions};
diff --git a/tests/loader_handle_validation_tests.cpp b/tests/loader_handle_validation_tests.cpp
index 7154393..6ecf165 100644
--- a/tests/loader_handle_validation_tests.cpp
+++ b/tests/loader_handle_validation_tests.cpp
@@ -41,7 +41,7 @@
 
 TEST(LoaderHandleValidTests, BadInstEnumPhysDevices) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -55,7 +55,7 @@
 
 TEST(LoaderHandleValidTests, BadInstGetInstProcAddr) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -67,7 +67,7 @@
 
 TEST(LoaderHandleValidTests, BadInstDestroyInstance) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -82,9 +82,7 @@
     FrameworkEnvironment env{};
     Extension first_ext{"VK_KHR_surface"};
     Extension second_ext{"VK_EXT_headless_surface"};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_instance_extensions({first_ext, second_ext})
-        .add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_instance_extensions({first_ext, second_ext}).add_physical_device("physical_device_0");
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(first_ext.extensionName.c_str());
@@ -100,9 +98,7 @@
     FrameworkEnvironment env{};
     Extension first_ext{"VK_KHR_surface"};
     Extension second_ext{"VK_EXT_headless_surface"};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_instance_extensions({first_ext, second_ext})
-        .add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_instance_extensions({first_ext, second_ext}).add_physical_device("physical_device_0");
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extensions({first_ext.extensionName.c_str(), second_ext.extensionName.c_str()});
@@ -122,9 +118,7 @@
     FrameworkEnvironment env{};
     Extension first_ext{"VK_KHR_surface"};
     Extension second_ext{"VK_KHR_display"};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_instance_extensions({first_ext, second_ext})
-        .add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_instance_extensions({first_ext, second_ext}).add_physical_device("physical_device_0");
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extensions({first_ext.extensionName.c_str(), second_ext.extensionName.c_str()});
@@ -143,7 +137,7 @@
 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
 TEST(LoaderHandleValidTests, BadInstCreateAndroidSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -163,7 +157,7 @@
 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
 TEST(LoaderHandleValidTests, BadInstCreateDirectFBSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -183,7 +177,7 @@
 #if defined(VK_USE_PLATFORM_FUCHSIA)
 TEST(LoaderHandleValidTests, BadInstCreateFuchsiaSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -203,7 +197,7 @@
 #if defined(VK_USE_PLATFORM_GGP)
 TEST(LoaderHandleValidTests, BadInstCreateGGPSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -224,7 +218,7 @@
 #if defined(VK_USE_PLATFORM_IOS_MVK)
 TEST(LoaderHandleValidTests, BadInstCreateIOSSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -244,7 +238,7 @@
 #if defined(VK_USE_PLATFORM_MACOS_MVK)
 TEST(LoaderHandleValidTests, BadInstCreateMacOSSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -264,7 +258,7 @@
 #if defined(VK_USE_PLATFORM_METAL_EXT)
 TEST(LoaderHandleValidTests, BadInstCreateMetalSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -284,7 +278,7 @@
 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
 TEST(LoaderHandleValidTests, BadInstCreateQNXSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -305,7 +299,7 @@
 #if defined(VK_USE_PLATFORM_VI_NN)
 TEST(LoaderHandleValidTests, BadInstCreateViNNSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -326,7 +320,7 @@
 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
 TEST(LoaderHandleValidTests, BadInstCreateWaylandSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -347,7 +341,7 @@
 #if defined(VK_USE_PLATFORM_WIN32_KHR)
 TEST(LoaderHandleValidTests, BadInstCreateWin32Surf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -368,7 +362,7 @@
 #if defined(VK_USE_PLATFORM_XCB_KHR)
 TEST(LoaderHandleValidTests, BadInstCreateXCBSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -389,7 +383,7 @@
 #if defined(VK_USE_PLATFORM_XLIB_KHR)
 TEST(LoaderHandleValidTests, BadInstCreateXlibSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -411,9 +405,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevFeature) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -429,9 +421,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevFormatProps) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -447,9 +437,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevImgFormatProps) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -467,9 +455,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevProps) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -485,9 +471,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevQueueFamProps) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -502,9 +486,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevDevMemProps) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -520,9 +502,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevCreateDevice) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -556,9 +536,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevEnumDevExtProps) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -573,9 +551,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevEnumDevLayerProps) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -590,9 +566,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevSparseImgFormatProps) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -610,9 +584,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevFeature2) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -630,9 +602,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevFormatProps2) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -650,9 +620,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevImgFormatProps2) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -673,9 +641,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevProps2) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -693,9 +659,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevQueueFamProps2) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -710,9 +674,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevDevMemProps2) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -730,9 +692,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevSparseImgFormatProps2) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -751,9 +711,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevExternFenceProps) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -772,9 +730,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevExternBufferProps) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -793,9 +749,7 @@
 
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevExternSemaphoreProps) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device({})
-        .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({}).set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(1, 1, 0);
@@ -816,9 +770,7 @@
     FrameworkEnvironment env{};
     Extension first_ext{"VK_KHR_surface"};
     Extension second_ext{"VK_KHR_display"};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_instance_extensions({first_ext, second_ext})
-        .add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_instance_extensions({first_ext, second_ext}).add_physical_device("physical_device_0");
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(first_ext.extensionName.c_str());
@@ -836,9 +788,7 @@
     FrameworkEnvironment env{};
     Extension first_ext{"VK_KHR_surface"};
     Extension second_ext{"VK_KHR_display"};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_instance_extensions({first_ext, second_ext})
-        .add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_instance_extensions({first_ext, second_ext}).add_physical_device("physical_device_0");
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(first_ext.extensionName.c_str());
@@ -855,9 +805,7 @@
     FrameworkEnvironment env{};
     Extension first_ext{"VK_KHR_surface"};
     Extension second_ext{"VK_KHR_display"};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_instance_extensions({first_ext, second_ext})
-        .add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_instance_extensions({first_ext, second_ext}).add_physical_device("physical_device_0");
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(first_ext.extensionName.c_str());
@@ -874,9 +822,7 @@
     FrameworkEnvironment env{};
     Extension first_ext{"VK_KHR_surface"};
     Extension second_ext{"VK_KHR_display"};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_instance_extensions({first_ext, second_ext})
-        .add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_instance_extensions({first_ext, second_ext}).add_physical_device("physical_device_0");
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(first_ext.extensionName.c_str());
@@ -892,7 +838,7 @@
 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
 TEST(LoaderHandleValidTests, BadPhysDevGetDirectFBPresentSupportKHR) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -909,7 +855,7 @@
 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
 TEST(LoaderHandleValidTests, BadPhysDevGetQNXPresentSupportKHR) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -925,7 +871,7 @@
 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevWaylandPresentSupportKHR) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -941,7 +887,7 @@
 #if defined(VK_USE_PLATFORM_WIN32_KHR)
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevWin32PresentSupportKHR) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -957,7 +903,7 @@
 #if defined(VK_USE_PLATFORM_XCB_KHR)
 TEST(LoaderHandleValidTests, BadPhysDevGetXCBPresentSupportKHR) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -974,7 +920,7 @@
 #if defined(VK_USE_PLATFORM_XLIB_KHR)
 TEST(LoaderHandleValidTests, BadPhysDevGetXlibPresentSupportKHR) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -994,10 +940,7 @@
     for (const auto& ext : exts) {
         ext_modified.push_back(Extension{ext});
     }
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_instance_extensions(ext_modified)
-        .setup_WSI()
-        .add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_instance_extensions(ext_modified).setup_WSI().add_physical_device("physical_device_0");
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extensions(exts);
@@ -1281,7 +1224,7 @@
 #if defined(VK_USE_PLATFORM_WIN32_KHR)
 TEST(LoaderHandleValidTests, BadPhysDevGetPhysDevSurfacePresentModes2EXT) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -1315,12 +1258,12 @@
 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingAndroidSurface) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -1343,12 +1286,12 @@
 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingDirectFBSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -1371,12 +1314,12 @@
 #if defined(VK_USE_PLATFORM_FUCHSIA)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingFuchsiaSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -1399,12 +1342,12 @@
 #if defined(VK_USE_PLATFORM_GGP)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingGGPSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -1427,12 +1370,12 @@
 #if defined(VK_USE_PLATFORM_IOS_MVK)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingIOSSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -1455,12 +1398,12 @@
 #if defined(VK_USE_PLATFORM_MACOS_MVK)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingMacOSSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI("VK_USE_PLATFORM_MACOS_MVK");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI("VK_USE_PLATFORM_MACOS_MVK");
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI("VK_USE_PLATFORM_MACOS_MVK");
@@ -1483,12 +1426,12 @@
 #if defined(VK_USE_PLATFORM_METAL_EXT)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingMetalSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI("VK_USE_PLATFORM_METAL_EXT");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI("VK_USE_PLATFORM_METAL_EXT");
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI("VK_USE_PLATFORM_METAL_EXT");
@@ -1511,12 +1454,12 @@
 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingQNXSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -1539,12 +1482,12 @@
 #if defined(VK_USE_PLATFORM_VI_NN)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingViNNSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -1567,12 +1510,12 @@
 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingWaylandSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI("VK_USE_PLATFORM_WAYLAND_KHR");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI("VK_USE_PLATFORM_WAYLAND_KHR");
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI("VK_USE_PLATFORM_WAYLAND_KHR");
@@ -1595,12 +1538,12 @@
 #if defined(VK_USE_PLATFORM_WIN32_KHR)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingWin32Surf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -1623,12 +1566,12 @@
 #if defined(VK_USE_PLATFORM_XCB_KHR)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingXCBSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI();
@@ -1651,12 +1594,12 @@
 #if defined(VK_USE_PLATFORM_XLIB_KHR)
 TEST(LoaderHandleValidTests, VerifyHandleWrappingXlibSurf) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).setup_WSI("VK_USE_PLATFORM_XLIB_KHR");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI("VK_USE_PLATFORM_XLIB_KHR");
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.setup_WSI("VK_USE_PLATFORM_XLIB_KHR");
@@ -1691,12 +1634,12 @@
 TEST(LoaderHandleValidTests, VerifyHandleWrappingDebugUtilsMessenger) {
     FrameworkEnvironment env{};
     Extension ext{"VK_EXT_debug_utils"};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_instance_extensions({ext});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_instance_extensions({ext});
 
     const char* wrap_objects_name = "WrapObjectsLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension("VK_EXT_debug_utils");
diff --git a/tests/loader_layer_tests.cpp b/tests/loader_layer_tests.cpp
index 156d8ee..a88280c 100644
--- a/tests/loader_layer_tests.cpp
+++ b/tests/loader_layer_tests.cpp
@@ -27,6 +27,9 @@
 
 #include "test_environment.h"
 
+#include "util/test_defines.h"
+#include "util/get_executable_path.h"
+
 void CheckLogForLayerString(FrameworkEnvironment& env, const char* implicit_layer_name, bool check_for_enable) {
     {
         InstWrapper inst{env.vulkan_functions};
@@ -45,18 +48,17 @@
 
 TEST(ImplicitLayers, WithEnableAndDisableEnvVar) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
 
     EnvVarWrapper enable_env_var{"ENABLE_ME"};
     EnvVarWrapper disable_env_var{"DISABLE_ME"};
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment(disable_env_var.get())
-                                                         .set_enable_environment(enable_env_var.get())),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment(disable_env_var.get())
+                                                             .set_enable_environment(enable_env_var.get())));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name));
@@ -91,15 +93,14 @@
 
 TEST(ImplicitLayers, OnlyDisableEnvVar) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
     EnvVarWrapper disable_env_var{"DISABLE_ME"};
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment(disable_env_var.get())),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment(disable_env_var.get())));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name));
@@ -126,20 +127,19 @@
 
 TEST(ImplicitLayers, PreInstanceEnumInstLayerProps) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
     EnvVarWrapper disable_env_var{"DISABLE_ME"};
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(implicit_layer_name)
-                .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                .set_disable_environment(disable_env_var.get())
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceLayerProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))),
-        "implicit_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(implicit_layer_name)
+                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                    .set_disable_environment(disable_env_var.get())
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceLayerProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))));
 
     uint32_t layer_props = 43;
     auto& layer = env.get_test_layer(0);
@@ -160,20 +160,19 @@
 
 TEST(ImplicitLayers, PreInstanceEnumInstExtProps) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
     EnvVarWrapper disable_env_var{"DISABLE_ME"};
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(implicit_layer_name)
-                .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                .set_disable_environment(disable_env_var.get())
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceExtensionProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))),
-        "implicit_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(implicit_layer_name)
+                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                    .set_disable_environment(disable_env_var.get())
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceExtensionProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))));
 
     uint32_t ext_props = 52;
     auto& layer = env.get_test_layer(0);
@@ -194,14 +193,15 @@
 
 TEST(ImplicitLayers, PreInstanceVersion) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)
         .add_physical_device({})
         .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3));
 
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
     EnvVarWrapper disable_env_var{"DISABLE_ME"};
 
-    env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+    env.add_implicit_layer({},
+                           ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
                                ManifestLayer::LayerDescription{}
                                    .set_name(implicit_layer_name)
                                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
@@ -209,8 +209,7 @@
                                    .set_disable_environment(disable_env_var.get())
                                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
                                                                   .set_vk_func("vkEnumerateInstanceVersion")
-                                                                  .set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
-                           "implicit_test_layer.json");
+                                                                  .set_override_name("test_preinst_vkEnumerateInstanceVersion"))));
 
     uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4);
     auto& layer = env.get_test_layer(0);
@@ -235,20 +234,19 @@
 // tested through behavior above).
 TEST(ImplicitLayers, OverrideGetInstanceProcAddr) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
     EnvVarWrapper disable_env_var{"DISABLE_ME"};
 
-    env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 0, 0}).add_layer(
-                               ManifestLayer::LayerDescription{}
-                                   .set_name(implicit_layer_name)
-                                   .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_1)
-                                   .set_disable_environment(disable_env_var.get())
-                                   .add_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                                     .set_vk_func("vkGetInstanceProcAddr")
-                                                     .set_override_name("test_override_vkGetInstanceProcAddr"))),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.set_file_format_version({1, 0, 0}).add_layer(
+                                   ManifestLayer::LayerDescription{}
+                                       .set_name(implicit_layer_name)
+                                       .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_1)
+                                       .set_disable_environment(disable_env_var.get())
+                                       .add_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                         .set_vk_func("vkGetInstanceProcAddr")
+                                                         .set_override_name("test_override_vkGetInstanceProcAddr"))));
 
     {
         InstWrapper inst1{env.vulkan_functions};
@@ -267,45 +265,43 @@
 TEST(ImplicitLayers, EnableWithFilter) {
     FrameworkEnvironment env;
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA))
-        .add_physical_device({})
-        .set_icd_api_version(VK_API_VERSION_1_2);
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({}).set_icd_api_version(VK_API_VERSION_1_2);
 
     const char* implicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer";
     const char* implicit_json_name_1 = "First_layer.json";
     const char* disable_layer_name_1 = "DISABLE_FIRST";
     const char* enable_layer_name_1 = "ENABLE_FIRST";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_implicit_layer(ManifestOptions{}.set_json_name(implicit_json_name_1),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(implicit_layer_name_1)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                          .set_enable_environment(enable_layer_name_1)
                                                          .set_disable_environment(disable_layer_name_1)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           implicit_json_name_1);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* implicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer";
     const char* implicit_json_name_2 = "Second_layer.json";
     const char* disable_layer_name_2 = "DISABLE_SECOND";
     const char* enable_layer_name_2 = "ENABLE_SECOND";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_implicit_layer(ManifestOptions{}.set_json_name(implicit_json_name_2),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(implicit_layer_name_2)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                          .set_enable_environment(enable_layer_name_2)
                                                          .set_disable_environment(disable_layer_name_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           implicit_json_name_2);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* implicit_layer_name_3 = "VK_LAYER_LUNARG_Second_test_layer";
     const char* implicit_json_name_3 = "Second_test_layer.json";
     const char* disable_layer_name_3 = "DISABLE_THIRD";
     const char* enable_layer_name_3 = "ENABLE_THIRD";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_implicit_layer(ManifestOptions{}.set_json_name(implicit_json_name_3),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(implicit_layer_name_3)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                          .set_enable_environment(enable_layer_name_3)
                                                          .set_disable_environment(disable_layer_name_3)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           implicit_json_name_3);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     EnvVarWrapper layers_enable_env_var{"VK_LOADER_LAYERS_ENABLE"};
     EnvVarWrapper layer_1_enable_env_var{enable_layer_name_1};
@@ -487,38 +483,38 @@
 // Force disabled with new filter env var
 TEST(ImplicitLayers, DisableWithFilter) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2);
 
     const char* implicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer";
     const char* implicit_json_name_1 = "First_layer.json";
     const char* disable_layer_name_1 = "DISABLE_FIRST";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_implicit_layer(ManifestOptions{}.set_json_name(implicit_json_name_1),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(implicit_layer_name_1)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                          .set_disable_environment(disable_layer_name_1)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           implicit_json_name_1);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* implicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer";
     const char* implicit_json_name_2 = "Second_layer.json";
     const char* disable_layer_name_2 = "DISABLE_SECOND";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_implicit_layer(ManifestOptions{}.set_json_name(implicit_json_name_2),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(implicit_layer_name_2)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                          .set_disable_environment(disable_layer_name_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           implicit_json_name_2);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* implicit_layer_name_3 = "VK_LAYER_LUNARG_Second_test_layer";
     const char* implicit_json_name_3 = "Second_test_layer.json";
     const char* disable_layer_name_3 = "DISABLE_THIRD";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_implicit_layer(ManifestOptions{}.set_json_name(implicit_json_name_3),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(implicit_layer_name_3)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                          .set_disable_environment(disable_layer_name_3)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           implicit_json_name_3);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"};
 
@@ -676,32 +672,32 @@
 // Force disabled with new filter env var
 TEST(ImplicitLayers, DisableWithFilterWhenLayersEnableEnvVarIsActive) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2);
 
     const char* implicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer";
     const char* implicit_json_name_1 = "First_layer.json";
     const char* disable_layer_name_1 = "DISABLE_FIRST";
     const char* enable_layer_name_1 = "ENABLE_FIRST";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_implicit_layer(ManifestOptions{}.set_json_name(implicit_json_name_1),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(implicit_layer_name_1)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                          .set_disable_environment(disable_layer_name_1)
                                                          .set_enable_environment(enable_layer_name_1)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           implicit_json_name_1);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* implicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer";
     const char* implicit_json_name_2 = "Second_layer.json";
     const char* disable_layer_name_2 = "DISABLE_SECOND";
     const char* enable_layer_name_2 = "ENABLE_SECOND";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_implicit_layer(ManifestOptions{}.set_json_name(implicit_json_name_2),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(implicit_layer_name_2)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                          .set_disable_environment(disable_layer_name_2)
                                                          .set_enable_environment(enable_layer_name_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           implicit_json_name_2);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"};
     EnvVarWrapper layer_1_enable_env_var{enable_layer_name_1};
@@ -781,38 +777,38 @@
 // override the disable.
 TEST(ImplicitLayers, EnableAndDisableWithFilter) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2);
 
     const char* implicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer";
     const char* implicit_json_name_1 = "First_layer.json";
     const char* disable_layer_name_1 = "DISABLE_FIRST";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_implicit_layer(ManifestOptions{}.set_json_name(implicit_json_name_1),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(implicit_layer_name_1)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                          .set_disable_environment(disable_layer_name_1)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           implicit_json_name_1);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* implicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer";
     const char* implicit_json_name_2 = "Second_layer.json";
     const char* disable_layer_name_2 = "DISABLE_SECOND";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_implicit_layer(ManifestOptions{}.set_json_name(implicit_json_name_2),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(implicit_layer_name_2)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                          .set_disable_environment(disable_layer_name_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           implicit_json_name_2);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* implicit_layer_name_3 = "VK_LAYER_LUNARG_Second_test_layer";
     const char* implicit_json_name_3 = "Second_test_layer.json";
     const char* disable_layer_name_3 = "DISABLE_THIRD";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_implicit_layer(ManifestOptions{}.set_json_name(implicit_json_name_3),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(implicit_layer_name_3)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                          .set_disable_environment(disable_layer_name_3)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           implicit_json_name_3);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"};
     EnvVarWrapper layers_enable_env_var{"VK_LOADER_LAYERS_ENABLE"};
@@ -960,42 +956,32 @@
 // Expect the second layer to be found first, because it'll be in a path that is searched first.
 TEST(ImplicitLayers, DuplicateLayers) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* same_layer_name_1 = "VK_LAYER_RegularLayer1";
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(same_layer_name_1)
-                                                                          .set_description("actually_layer_1")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("if_you_can")),
-                                            "regular_layer_1.json"));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(same_layer_name_1)
+                                                         .set_description("actually_layer_1")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("if_you_can")));
     auto& layer1 = env.get_test_layer(0);
     layer1.set_description("actually_layer_1");
     layer1.set_make_spurious_log_in_create_instance("actually_layer_1");
 
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(same_layer_name_1)
-                                                                          .set_description("actually_layer_2")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("if_you_can")),
-                                            "regular_layer_1.json")
-                               // use override folder as just a folder and manually add it to the implicit layer search paths
-                               .set_discovery_type(ManifestDiscoveryType::override_folder));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::generic),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(same_layer_name_1)
+                                                         .set_description("actually_layer_2")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("if_you_can")));
     auto& layer2 = env.get_test_layer(1);
     layer2.set_description("actually_layer_2");
     layer2.set_make_spurious_log_in_create_instance("actually_layer_2");
-#if defined(WIN32)
-    env.platform_shim->add_manifest(ManifestCategory::implicit_layer, env.get_folder(ManifestLocation::override_layer).location());
-#elif COMMON_UNIX_PLATFORMS
-    env.platform_shim->redirect_path(std::filesystem::path(USER_LOCAL_SHARE_DIR "/vulkan/implicit_layer.d"),
-                                     env.get_folder(ManifestLocation::override_layer).location());
-#endif
 
-    auto layer_props = env.GetLayerProperties(2);
+    auto layer_props = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[0].layerName));
-    ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[1].layerName));
     ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description));
-    ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description));
 
     InstWrapper inst{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
@@ -1008,19 +994,71 @@
     ASSERT_FALSE(env.debug_log.find("actually_layer_2"));
 }
 
+TEST(ImplicitLayer, DuplicateLayersWithDifferentExtensions) {
+    // Put the duplicate layer without the extension first
+    {
+        FrameworkEnvironment env{};
+        env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
+
+        env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                                 .set_name("VK_LAYER_tesssst")
+                                                                 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                                 .set_disable_environment("delete me")));
+        env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                                 .set_name("VK_LAYER_tesssst")
+                                                                 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                                 .add_instance_extension({"VK_EXT_layer_settings"})
+                                                                 .set_disable_environment("delete me")));
+        env.layers.back().get_test_binary().instance_extensions.push_back("VK_EXT_layer_settings");
+
+        auto layer_props = env.GetLayerProperties(1);
+
+        auto ext_props = env.GetInstanceExtensions(6);
+
+        InstWrapper inst{env.vulkan_functions};
+        inst.create_info.add_extension("VK_EXT_layer_settings");
+        inst.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT);
+    }
+    // Do the same but put the layer with the extension first
+    {
+        FrameworkEnvironment env{};
+        env.add_icd(TEST_ICD_PATH_VERSION_2).setup_WSI();
+
+        env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                                 .set_name("VK_LAYER_tesssst")
+                                                                 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                                 .add_instance_extension({"VK_EXT_layer_settings"})
+                                                                 .set_disable_environment("delete me")));
+        env.layers.back().get_test_binary().instance_extensions.push_back("VK_EXT_layer_settings");
+
+        env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                                 .set_name("VK_LAYER_tesssst")
+                                                                 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                                 .set_disable_environment("delete me")));
+
+        auto layer_props = env.GetLayerProperties(1);
+
+        auto ext_props = env.GetInstanceExtensions(7);
+
+        InstWrapper inst{env.vulkan_functions};
+        inst.create_info.add_extension("VK_EXT_layer_settings");
+        inst.CheckCreate();
+    }
+}
+
 TEST(ImplicitLayers, VkImplicitLayerPathEnvVar) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     // verify layer loads successfully when setting VK_IMPLICIT_LAYER_PATH to a full filepath
     const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1";
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(regular_layer_name_1)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("Yikes")),
-                                            "regular_layer_1.json")
-                               .set_discovery_type(ManifestDiscoveryType::env_var)
-                               .set_is_dir(false));
+    env.add_implicit_layer(ManifestOptions{}
+
+                               .set_discovery_type(ManifestDiscoveryType::env_var),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(regular_layer_name_1)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("Yikes")));
 
     InstWrapper inst(env.vulkan_functions);
     inst.CheckCreate();
@@ -1030,26 +1068,22 @@
 
 TEST(ImplicitLayers, VkImplicitLayerPathEnvVarContainsMultipleFilePaths) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     // verify layers load successfully when setting VK_IMPLICIT_LAYER_PATH to multiple full filepaths
     const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1";
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(regular_layer_name_1)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("Yikes")),
-                                            "regular_layer_1.json")
-                               .set_discovery_type(ManifestDiscoveryType::env_var)
-                               .set_is_dir(false));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(regular_layer_name_1)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("Yikes")));
 
     const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2";
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(regular_layer_name_2)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("Yikes")),
-                                            "regular_layer_2.json")
-                               .set_discovery_type(ManifestDiscoveryType::env_var)
-                               .set_is_dir(false));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(regular_layer_name_2)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("Yikes")));
 
     InstWrapper inst(env.vulkan_functions);
     inst.CheckCreate();
@@ -1059,24 +1093,22 @@
 
 TEST(ImplicitLayers, VkImplicitLayerPathEnvVarIsDirectory) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     // verify layers load successfully when setting VK_IMPLICIT_LAYER_PATH to a directory
     const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1";
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(regular_layer_name_1)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("Yikes")),
-                                            "regular_layer_1.json")
-                               .set_discovery_type(ManifestDiscoveryType::env_var));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(regular_layer_name_1)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("Yikes")));
 
     const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2";
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(regular_layer_name_2)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("Yikes")),
-                                            "regular_layer_2.json")
-                               .set_discovery_type(ManifestDiscoveryType::env_var));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(regular_layer_name_2)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("Yikes")));
 
     InstWrapper inst(env.vulkan_functions);
     inst.CheckCreate();
@@ -1087,38 +1119,33 @@
 // Test to make sure order layers are found in VK_IMPLICIT_LAYER_PATH is what decides which layer is loaded
 TEST(ImplicitLayers, DuplicateLayersInVkImplicitLayerPath) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* layer_name = "VK_LAYER_RegularLayer1";
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name)
-                                                                          .set_description("actually_layer_1")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("Boo!")),
-                                            "layer.json")
-                               .set_discovery_type(ManifestDiscoveryType::env_var)
-                               .set_is_dir(true));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var).set_is_dir(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_description("actually_layer_1")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("Boo!")));
     auto& layer1 = env.get_test_layer(0);
     layer1.set_description("actually_layer_1");
 
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name)
-                                                                          .set_description("actually_layer_2")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("Ah!")),
-                                            "layer.json")
+    env.add_implicit_layer(ManifestOptions{}
                                // putting it in a separate folder then manually adding the folder to VK_IMPLICIT_LAYER_PATH
-                               .set_discovery_type(ManifestDiscoveryType::override_folder)
-                               .set_is_dir(true));
+                               .set_discovery_type(ManifestDiscoveryType::override_folder),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_description("actually_layer_2")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("Ah!")));
     auto& layer2 = env.get_test_layer(1);
     layer2.set_description("actually_layer_2");
     env.env_var_vk_implicit_layer_paths.add_to_list(env.get_folder(ManifestLocation::override_layer).location().string());
 
-    auto layer_props = env.GetLayerProperties(2);
+    auto layer_props = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layer_name, layer_props[0].layerName));
     ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description));
-    ASSERT_TRUE(string_eq(layer_name, layer_props[1].layerName));
-    ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description));
 
     EnvVarWrapper inst_layers_env_var{"VK_INSTANCE_LAYERS"};
     inst_layers_env_var.add_to_list(layer_name);
@@ -1134,40 +1161,35 @@
 
 TEST(ImplicitLayers, DuplicateLayersInVK_ADD_IMPLICIT_LAYER_PATH) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* same_layer_name_1 = "VK_LAYER_RegularLayer1";
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(same_layer_name_1)
-                                                                          .set_description("actually_layer_1")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("Red")),
-                                            "regular_layer_1.json")
+    env.add_implicit_layer(ManifestOptions{}
                                // use override folder as just a folder and manually set the VK_ADD_IMPLICIT_LAYER_PATH env-var to it
-                               .set_discovery_type(ManifestDiscoveryType::override_folder)
-                               .set_is_dir(true));
+                               .set_discovery_type(ManifestDiscoveryType::override_folder),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(same_layer_name_1)
+                                                         .set_description("actually_layer_1")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("Red")));
     auto& layer1 = env.get_test_layer(0);
     layer1.set_description("actually_layer_1");
     layer1.set_make_spurious_log_in_create_instance("actually_layer_1");
     env.add_env_var_vk_implicit_layer_paths.add_to_list(env.get_folder(ManifestLocation::override_layer).location());
 
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(same_layer_name_1)
-                                                                          .set_description("actually_layer_2")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("Blue")),
-                                            "regular_layer_1.json")
-                               .set_discovery_type(ManifestDiscoveryType::add_env_var)
-                               .set_is_dir(true));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var).set_is_dir(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(same_layer_name_1)
+                                                         .set_description("actually_layer_2")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("Blue")));
     auto& layer2 = env.get_test_layer(1);
     layer2.set_description("actually_layer_2");
     layer2.set_make_spurious_log_in_create_instance("actually_layer_2");
 
-    auto layer_props = env.GetLayerProperties(2);
+    auto layer_props = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[0].layerName));
-    ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[1].layerName));
     ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description));
-    ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description));
 
     InstWrapper inst{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
@@ -1179,27 +1201,72 @@
     ASSERT_FALSE(env.debug_log.find("actually_layer_2"));
 }
 
+TEST(ImplicitLayers, OrderedByVK_INSTANCE_LAYERS) {
+    FrameworkEnvironment env;
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
+    const char* implicit_layer_name = "VK_LAYER_implicit";
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("foo")));
+    const char* explicit_layer_name = "VK_LAYER_explicit";
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+    // Only enable the explicit layer through the env-var
+    {
+        EnvVarWrapper env_var("VK_INSTANCE_LAYERS");
+        env_var.add_to_list(explicit_layer_name);
+        InstWrapper inst{env.vulkan_functions};
+        inst.CheckCreate();
+        auto active_layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
+        ASSERT_TRUE(string_eq(active_layers.at(0).layerName, implicit_layer_name));
+        ASSERT_TRUE(string_eq(active_layers.at(1).layerName, explicit_layer_name));
+    }
+    // Enable both layers, implicit then explicit
+    {
+        EnvVarWrapper env_var("VK_INSTANCE_LAYERS");
+        env_var.add_to_list(implicit_layer_name);
+        env_var.add_to_list(explicit_layer_name);
+        InstWrapper inst{env.vulkan_functions};
+        inst.CheckCreate();
+        auto active_layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
+        ASSERT_TRUE(string_eq(active_layers.at(0).layerName, implicit_layer_name));
+        ASSERT_TRUE(string_eq(active_layers.at(1).layerName, explicit_layer_name));
+    }
+    // Enable both layers, explicit then implicit
+    {
+        EnvVarWrapper env_var("VK_INSTANCE_LAYERS");
+        env_var.add_to_list(explicit_layer_name);
+        env_var.add_to_list(implicit_layer_name);
+        InstWrapper inst{env.vulkan_functions};
+        inst.CheckCreate();
+        auto active_layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
+        ASSERT_TRUE(string_eq(active_layers.at(0).layerName, explicit_layer_name));
+        ASSERT_TRUE(string_eq(active_layers.at(1).layerName, implicit_layer_name));
+    }
+}
+
 // Meta layer which contains component layers that do not exist.
 TEST(MetaLayers, InvalidComponentLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     const char* meta_layer_name = "VK_LAYER_MetaTestLayer";
     const char* invalid_layer_name_1 = "VK_LAYER_InvalidLayer1";
     const char* invalid_layer_name_2 = "VK_LAYER_InvalidLayer2";
-    env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-                               ManifestLayer::LayerDescription{}
-                                   .set_name(meta_layer_name)
-                                   .add_component_layers({invalid_layer_name_1, invalid_layer_name_2})
-                                   .set_disable_environment("NotGonnaWork")
-                                   .add_instance_extension({"NeverGonnaGiveYouUp"})
-                                   .add_device_extension({"NeverGonnaLetYouDown"})),
-                           "meta_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                                   ManifestLayer::LayerDescription{}
+                                       .set_name(meta_layer_name)
+                                       .add_component_layers({invalid_layer_name_1, invalid_layer_name_2})
+                                       .set_disable_environment("NotGonnaWork")
+                                       .add_instance_extension({"NeverGonnaGiveYouUp"})
+                                       .add_device_extension({"NeverGonnaLetYouDown"})));
 
     const char* regular_layer_name = "TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     // should find 1, the 'regular' layer
     auto layer_props = env.GetLayerProperties(1);
@@ -1222,18 +1289,16 @@
 // Meta layer that is an explicit layer
 TEST(MetaLayers, ExplicitMetaLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
     const char* meta_layer_name = "VK_LAYER_MetaTestLayer";
     const char* regular_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})));
 
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     {  // global functions
        // should find 1, the 'regular' layer
@@ -1263,22 +1328,20 @@
 // Meta layer which adds itself in its list of component layers
 TEST(MetaLayers, MetaLayerNameInComponentLayers) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     const char* meta_layer_name = "VK_LAYER_MetaTestLayer";
     const char* regular_layer_name = "VK_LAYER_TestLayer";
-    env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-                               ManifestLayer::LayerDescription{}
-                                   .set_name(meta_layer_name)
-                                   .add_component_layers({meta_layer_name, regular_layer_name})
-                                   .set_disable_environment("NotGonnaWork")
-                                   .add_instance_extension({"NeverGonnaGiveYouUp"})
-                                   .add_device_extension({"NeverGonnaLetYouDown"})),
-                           "meta_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                                   ManifestLayer::LayerDescription{}
+                                       .set_name(meta_layer_name)
+                                       .add_component_layers({meta_layer_name, regular_layer_name})
+                                       .set_disable_environment("NotGonnaWork")
+                                       .add_instance_extension({"NeverGonnaGiveYouUp"})
+                                       .add_device_extension({"NeverGonnaLetYouDown"})));
 
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     // should find 1, the 'regular' layer
     auto layer_props = env.GetLayerProperties(1);
@@ -1301,23 +1364,22 @@
 // Meta layer which adds another meta layer as a component layer
 TEST(MetaLayers, MetaLayerWhichAddsMetaLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     const char* meta_layer_name = "VK_LAYER_MetaTestLayer";
     const char* meta_meta_layer_name = "VK_LAYER_MetaMetaTestLayer";
     const char* regular_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})),
-        "meta_test_layer.json");
-    env.add_explicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-                               ManifestLayer::LayerDescription{}
-                                   .set_name(meta_meta_layer_name)
-                                   .add_component_layers({meta_layer_name, regular_layer_name})),
-                           "meta_meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})));
+
+    env.add_explicit_layer({}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                                   ManifestLayer::LayerDescription{}
+                                       .set_name(meta_meta_layer_name)
+                                       .add_component_layers({meta_layer_name, regular_layer_name})));
 
     auto layer_props = env.GetLayerProperties(3);
     EXPECT_TRUE(check_permutation({regular_layer_name, meta_layer_name, meta_meta_layer_name}, layer_props));
@@ -1338,20 +1400,18 @@
 
 TEST(MetaLayers, InstanceExtensionInComponentLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* meta_layer_name = "VK_LAYER_MetaTestLayer";
     const char* regular_layer_name = "VK_LAYER_TestLayer";
     const char* instance_ext_name = "VK_EXT_headless_surface";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(regular_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .add_instance_extension({instance_ext_name})),
-                           "regular_test_layer.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(regular_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .add_instance_extension({instance_ext_name})));
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})));
 
     auto extensions = env.GetInstanceExtensions(1, meta_layer_name);
     EXPECT_TRUE(string_eq(extensions[0].extensionName, instance_ext_name));
@@ -1359,20 +1419,18 @@
 
 TEST(MetaLayers, DeviceExtensionInComponentLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* meta_layer_name = "VK_LAYER_MetaTestLayer";
     const char* regular_layer_name = "VK_LAYER_TestLayer";
     const char* device_ext_name = "VK_EXT_fake_dev_ext";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(regular_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .add_device_extension({device_ext_name})),
-                           "regular_test_layer.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(regular_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .add_device_extension({device_ext_name})));
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})));
 
     ASSERT_NO_FATAL_FAILURE(env.GetInstanceExtensions(0, meta_layer_name));
 
@@ -1402,22 +1460,20 @@
 // Override meta layer missing disable environment variable still enables the layer
 TEST(OverrideMetaLayer, InvalidDisableEnvironment) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* regular_layer_name = "VK_LAYER_TestLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(regular_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                         .add_device_extension({"NeverGonnaLetYouDown"})),
-                           "regular_test_layer.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(regular_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                             .add_device_extension({"NeverGonnaLetYouDown"})));
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .add_component_layers({regular_layer_name})),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_component_layers({regular_layer_name})));
 
     auto layer_props = env.GetLayerProperties(1);
     EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
@@ -1429,23 +1485,21 @@
 // Override meta layer whose version is less than the api version of the instance
 TEST(OverrideMetaLayer, OlderVersionThanInstance) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* regular_layer_name = "VK_LAYER_TestLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(regular_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                         .add_device_extension({"NeverGonnaLetYouDown"})),
-                           "regular_test_layer.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(regular_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                             .add_device_extension({"NeverGonnaLetYouDown"})));
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .set_disable_environment("DisableMeIfYouCan")
-                                                                         .add_component_layers({regular_layer_name})),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .set_disable_environment("DisableMeIfYouCan")
+                                                                             .add_component_layers({regular_layer_name})));
     {  // global functions
         auto layer_props = env.GetLayerProperties(2);
         EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
@@ -1472,23 +1526,21 @@
 
 TEST(OverrideMetaLayer, OlderMetaLayerWithNewerInstanceVersion) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* regular_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(regular_layer_name)
-                                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(regular_layer_name)
+                                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))));
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .add_component_layers({regular_layer_name})
-                                                                         .set_disable_environment("DisableMeIfYouCan")),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_component_layers({regular_layer_name})
+                                                                             .set_disable_environment("DisableMeIfYouCan")));
     {  // global functions
         auto layer_props = env.GetLayerProperties(2);
         EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
@@ -1516,23 +1568,21 @@
 
 TEST(OverrideMetaLayer, NewerComponentLayerInMetaLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* regular_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(regular_layer_name)
-                                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                         .set_api_version(VK_API_VERSION_1_2)),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(regular_layer_name)
+                                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                                             .set_api_version(VK_API_VERSION_1_2)));
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .add_component_layers({regular_layer_name})
-                                                                         .set_disable_environment("DisableMeIfYouCan")),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_component_layers({regular_layer_name})
+                                                                             .set_disable_environment("DisableMeIfYouCan")));
 
     {  // global functions
         auto layer_props = env.GetLayerProperties(2);
@@ -1568,23 +1618,21 @@
 
 TEST(OverrideMetaLayer, OlderComponentLayerInMetaLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* regular_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(regular_layer_name)
-                                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(regular_layer_name)
+                                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .add_component_layers({regular_layer_name})
-                                                                         .set_disable_environment("DisableMeIfYouCan")),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_component_layers({regular_layer_name})
+                                                                             .set_disable_environment("DisableMeIfYouCan")));
     {  // global functions
         auto layer_props = env.GetLayerProperties(1);
         EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
@@ -1618,28 +1666,25 @@
 
 TEST(OverrideMetaLayer, ApplicationEnabledLayerInBlacklist) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* automatic_regular_layer_name = "VK_LAYER_TestLayer_1";
     const char* manual_regular_layer_name = "VK_LAYER_TestLayer_2";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(automatic_regular_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))),
-                           "regular_test_layer_1.json");
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(manual_regular_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))),
-                           "regular_test_layer_2.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(automatic_regular_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))));
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(manual_regular_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))));
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .add_component_layer(automatic_regular_layer_name)
-                                                                         .add_blacklisted_layer(manual_regular_layer_name)
-                                                                         .set_disable_environment("DisableMeIfYouCan")),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_component_layer(automatic_regular_layer_name)
+                                                                             .add_blacklisted_layer(manual_regular_layer_name)
+                                                                             .set_disable_environment("DisableMeIfYouCan")));
     {  // Check that enumerating the layers returns only the non-blacklisted layers + override layer
         auto layer_props = env.GetLayerProperties(2);
         ASSERT_TRUE(check_permutation({automatic_regular_layer_name, lunarg_meta_layer_name}, layer_props));
@@ -1670,9 +1715,9 @@
 
 TEST(OverrideMetaLayer, BasicOverridePaths) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
-    fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"};
+    auto& override_layer_folder = env.get_folder(ManifestLocation::override_layer);
 
     const char* regular_layer_name = "VK_LAYER_TestLayer_1";
     override_layer_folder.write_manifest("regular_test_layer.json",
@@ -1683,13 +1728,12 @@
                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)))
                                              .get_manifest_str());
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .add_component_layer(regular_layer_name)
-                                                                         .set_disable_environment("DisableMeIfYouCan")
-                                                                         .add_override_path(override_layer_folder.location())),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_component_layer(regular_layer_name)
+                                                                             .set_disable_environment("DisableMeIfYouCan")
+                                                                             .add_override_path(override_layer_folder.location())));
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.set_api_version(1, 1, 0);
@@ -1701,17 +1745,16 @@
 
 TEST(OverrideMetaLayer, BasicOverridePathsIgnoreOtherLayers) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
-    fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"};
+    auto& override_layer_folder = env.get_folder(ManifestLocation::override_layer);
 
     const char* regular_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(regular_layer_name)
-                                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(regular_layer_name)
+                                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* special_layer_name = "VK_LAYER_TestLayer_1";
     override_layer_folder.write_manifest("regular_test_layer.json",
@@ -1722,13 +1765,12 @@
                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)))
                                              .get_manifest_str());
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .add_component_layer(special_layer_name)
-                                                                         .set_disable_environment("DisableMeIfYouCan")
-                                                                         .add_override_path(override_layer_folder.location())),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_component_layer(special_layer_name)
+                                                                             .set_disable_environment("DisableMeIfYouCan")
+                                                                             .add_override_path(override_layer_folder.location())));
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.set_api_version(1, 1, 0);
@@ -1741,35 +1783,32 @@
 
 TEST(OverrideMetaLayer, OverridePathsInteractionWithVK_LAYER_PATH) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     // add explicit layer to VK_LAYER_PATH folder
     const char* env_var_layer_name = "VK_LAYER_env_var_set_path";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
         ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
                                                                          .set_name(env_var_layer_name)
                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-        "regular_test_layer.json"}
-                               .set_discovery_type(ManifestDiscoveryType::env_var));
+                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     // add layer to regular explicit layer folder
     const char* regular_layer_name = "VK_LAYER_regular_layer_path";
-    env.add_explicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(regular_layer_name)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))),
-                                            "regular_test_layer.json"}
-                               .set_discovery_type(ManifestDiscoveryType::override_folder));
+    env.add_explicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(regular_layer_name)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))));
 
-    env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(
-                               ManifestLayer::LayerDescription{}
-                                   .set_name(lunarg_meta_layer_name)
-                                   .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                   .add_component_layer(regular_layer_name)
-                                   .set_disable_environment("DisableMeIfYouCan")
-                                   .add_override_path(env.get_folder(ManifestLocation::override_layer).location())),
-                           "meta_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(
+                                   ManifestLayer::LayerDescription{}
+                                       .set_name(lunarg_meta_layer_name)
+                                       .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                       .add_component_layer(regular_layer_name)
+                                       .set_disable_environment("DisableMeIfYouCan")
+                                       .add_override_path(env.get_folder(ManifestLocation::override_layer).location())));
 
     auto meta_layer_path = env.get_folder(ManifestLocation::override_layer).location();
 
@@ -1791,16 +1830,16 @@
 // Make sure that implicit layers not in the override paths aren't found by mistake
 TEST(OverrideMetaLayer, OverridePathsEnableImplicitLayerInDefaultPaths) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
-    fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"};
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
+
+    auto& override_layer_folder = env.get_folder(ManifestLocation::override_layer);
 
     const char* implicit_layer_name = "VK_LAYER_ImplicitLayer";
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(implicit_layer_name)
-                                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-        "implicit_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(implicit_layer_name)
+                                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* regular_layer_name = "VK_LAYER_TestLayer_1";
     override_layer_folder.write_manifest("regular_test_layer.json",
@@ -1810,14 +1849,13 @@
                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)))
                                              .get_manifest_str());
-    env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(
-                               ManifestLayer::LayerDescription{}
-                                   .set_name(lunarg_meta_layer_name)
-                                   .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                   .add_component_layers({regular_layer_name, implicit_layer_name})
-                                   .set_disable_environment("DisableMeIfYouCan")
-                                   .add_override_path(override_layer_folder.location())),
-                           "meta_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(
+                                   ManifestLayer::LayerDescription{}
+                                       .set_name(lunarg_meta_layer_name)
+                                       .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                       .add_component_layers({regular_layer_name, implicit_layer_name})
+                                       .set_disable_environment("DisableMeIfYouCan")
+                                       .add_override_path(override_layer_folder.location())));
 
     InstWrapper inst{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
@@ -1831,8 +1869,9 @@
 
 TEST(OverrideMetaLayer, ManifestFileFormatVersionTooOld) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
-    fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"};
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
+
+    auto& override_layer_folder = env.get_folder(ManifestLocation::override_layer);
 
     const char* regular_layer_name = "VK_LAYER_TestLayer_1";
     override_layer_folder.write_manifest("regular_test_layer.json",
@@ -1843,13 +1882,12 @@
                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)))
                                              .get_manifest_str());
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 0, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .add_component_layer(regular_layer_name)
-                                                                         .set_disable_environment("DisableMeIfYouCan")
-                                                                         .add_override_path(override_layer_folder.location())),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 0, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_component_layer(regular_layer_name)
+                                                                             .set_disable_environment("DisableMeIfYouCan")
+                                                                             .add_override_path(override_layer_folder.location())));
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.set_api_version(1, 1, 0);
@@ -1864,23 +1902,21 @@
 // app_key contains test executable name, should activate the override layer
 TEST(OverrideMetaLayer, AppKeysDoesContainCurrentApplication) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* regular_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(
+                ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     std::string cur_path = test_platform_executable_path();
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .add_component_layers({regular_layer_name})
-                                                                         .set_disable_environment("DisableMeIfYouCan")
-                                                                         .add_app_key(cur_path)),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .add_component_layers({regular_layer_name})
+                                                                             .set_disable_environment("DisableMeIfYouCan")
+                                                                             .add_app_key(cur_path)));
     {  // global functions
         auto layer_props = env.GetLayerProperties(2);
         EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
@@ -1897,21 +1933,19 @@
 // app_key contains random strings, should not activate the override layer
 TEST(OverrideMetaLayer, AppKeysDoesNotContainCurrentApplication) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* regular_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(
+                ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
-    env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(
-                               ManifestLayer::LayerDescription{}
-                                   .set_name(lunarg_meta_layer_name)
-                                   .add_component_layers({regular_layer_name})
-                                   .set_disable_environment("DisableMeIfYouCan")
-                                   .add_app_keys({"/Hello", "Hi", "./../Uh-oh", "C:/Windows/Only"})),
-                           "meta_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(
+                                   ManifestLayer::LayerDescription{}
+                                       .set_name(lunarg_meta_layer_name)
+                                       .add_component_layers({regular_layer_name})
+                                       .set_disable_environment("DisableMeIfYouCan")
+                                       .add_app_keys({"/Hello", "Hi", "./../Uh-oh", "C:/Windows/Only"})));
     {  // global functions
         auto layer_props = env.GetLayerProperties(1);
         EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
@@ -1924,11 +1958,11 @@
     }
 }
 
-TEST(OverrideMetaLayer, RunningWithElevatedPrivilegesFromSecureLocation) {
+TEST(OverrideMetaLayer, RunningWithRegularPrivilegesFromSecureLocation) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
-    fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"};
+    auto& override_layer_folder = env.get_folder(ManifestLocation::override_layer);
 
     const char* regular_layer_name = "VK_LAYER_TestLayer_1";
     override_layer_folder.write_manifest("regular_test_layer.json",
@@ -1939,51 +1973,32 @@
                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)))
                                              .get_manifest_str());
     auto override_folder_location = override_layer_folder.location().string();
-    env.add_implicit_layer(TestLayerDetails{
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .add_component_layer(regular_layer_name)
-                                                                         .set_disable_environment("DisableMeIfYouCan")
-                                                                         .add_override_path(override_layer_folder.location())),
-        "meta_test_layer.json"});
+    env.add_implicit_layer(
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_component_layer(regular_layer_name)
+                                                                             .set_disable_environment("DisableMeIfYouCan")
+                                                                             .add_override_path(override_layer_folder.location())));
 
-    {  // try with no elevated privileges
-        auto layer_props = env.GetLayerProperties(2);
-        EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
+    // try with no elevated privileges
+    auto layer_props = env.GetLayerProperties(2);
+    EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
 
-        InstWrapper inst{env.vulkan_functions};
-        inst.create_info.set_api_version(1, 1, 0);
-        FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
-        inst.CheckCreate();
-        ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name));
-        auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2);
-        EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
-        env.debug_log.clear();
-    }
-
-    env.platform_shim->set_elevated_privilege(true);
-
-    {  // try with elevated privileges
-        auto layer_props = env.GetLayerProperties(2);
-        EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
-
-        InstWrapper inst{env.vulkan_functions};
-        inst.create_info.set_api_version(1, 1, 0);
-        FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
-        inst.CheckCreate();
-        ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name));
-        auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2);
-        EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, active_layer_props));
-    }
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.set_api_version(1, 1, 0);
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
+    ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name));
+    auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2);
+    EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
 }
 
-// Override layer should not be found and thus not loaded when running with elevated privileges
-TEST(OverrideMetaLayer, RunningWithElevatedPrivilegesFromUnsecureLocation) {
-    FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+TEST(OverrideMetaLayer, RunningWithElevatedPrivilegesFromSecureLocation) {
+    FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)};
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
-    fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"};
+    auto& override_layer_folder = env.get_folder(ManifestLocation::override_layer);
 
     const char* regular_layer_name = "VK_LAYER_TestLayer_1";
     override_layer_folder.write_manifest("regular_test_layer.json",
@@ -1993,66 +2008,119 @@
                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)))
                                              .get_manifest_str());
-    env.add_implicit_layer(TestLayerDetails{
+    auto override_folder_location = override_layer_folder.location().string();
+    env.add_implicit_layer(
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_component_layer(regular_layer_name)
+                                                                             .set_disable_environment("DisableMeIfYouCan")
+                                                                             .add_override_path(override_layer_folder.location())));
+
+    // try with elevated privileges
+    auto layer_props = env.GetLayerProperties(2);
+    EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.set_api_version(1, 1, 0);
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
+    ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name));
+    auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2);
+    EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, active_layer_props));
+}
+
+// Override layer should not be found and thus not loaded when running with elevated privileges
+TEST(OverrideMetaLayer, RunningWithRegularPrivilegesFromUnsecureLocation) {
+    FrameworkEnvironment env;
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
+
+    auto& override_layer_folder = env.get_folder(ManifestLocation::override_layer);
+
+    const char* regular_layer_name = "VK_LAYER_TestLayer_1";
+    override_layer_folder.write_manifest("regular_test_layer.json",
+                                         ManifestLayer{}
+                                             .add_layer(ManifestLayer::LayerDescription{}
+                                                            .set_name(regular_layer_name)
+                                                            .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                            .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)))
+                                             .get_manifest_str());
+    env.add_implicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::unsecured_generic),
         ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
                                                                          .set_name(lunarg_meta_layer_name)
                                                                          .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
                                                                          .add_component_layer(regular_layer_name)
                                                                          .set_disable_environment("DisableMeIfYouCan")
-                                                                         .add_override_path(override_layer_folder.location())),
-        "meta_test_layer.json"}
-                               .set_discovery_type(ManifestDiscoveryType::unsecured_generic));
+                                                                         .add_override_path(override_layer_folder.location())));
 
-    {  // try with no elevated privileges
-        auto layer_props = env.GetLayerProperties(2);
-        EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
+    auto layer_props = env.GetLayerProperties(2);
+    EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
 
-        InstWrapper inst{env.vulkan_functions};
-        inst.create_info.set_api_version(1, 1, 0);
-        FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
-        inst.CheckCreate();
-        ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name));
-        env.debug_log.clear();
-        auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2);
-        EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, active_layer_props));
-    }
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.set_api_version(1, 1, 0);
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
+    ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name));
+    env.debug_log.clear();
+    auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2);
+    EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, active_layer_props));
+}
 
-    env.platform_shim->set_elevated_privilege(true);
+TEST(OverrideMetaLayer, RunningWithElevatedPrivilegesFromUnsecureLocation) {
+    FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)};
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
-    {  // try with no elevated privileges
-        ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
+    auto& override_layer_folder = env.get_folder(ManifestLocation::override_layer);
 
-        InstWrapper inst{env.vulkan_functions};
-        inst.create_info.set_api_version(1, 1, 0);
-        FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
-        inst.CheckCreate();
-        ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name));
-        ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
-    }
+    const char* regular_layer_name = "VK_LAYER_TestLayer_1";
+    override_layer_folder.write_manifest("regular_test_layer.json",
+                                         ManifestLayer{}
+                                             .add_layer(ManifestLayer::LayerDescription{}
+                                                            .set_name(regular_layer_name)
+                                                            .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                            .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)))
+                                             .get_manifest_str());
+    env.add_implicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::unsecured_generic),
+        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                         .set_name(lunarg_meta_layer_name)
+                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                         .add_component_layer(regular_layer_name)
+                                                                         .set_disable_environment("DisableMeIfYouCan")
+                                                                         .add_override_path(override_layer_folder.location())));
+
+    ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.set_api_version(1, 1, 0);
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
+    ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name));
+    ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
 }
 
 // Makes sure explicit layers can't override pre-instance functions even if enabled by the override layer
 TEST(ExplicitLayers, OverridePreInstanceFunctions) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
     const char* explicit_layer_name = "VK_LAYER_enabled_by_override";
     const char* disable_env_var = "DISABLE_ME";
 
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(explicit_layer_name)
-                .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceLayerProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceExtensionProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceVersion")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
-        "explicit_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(explicit_layer_name)
+                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceLayerProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceExtensionProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceVersion")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceVersion"))));
 
     auto& layer = env.get_test_layer(0);
     layer.set_reported_layer_props(34);
@@ -2060,11 +2128,10 @@
     layer.set_reported_instance_version(VK_MAKE_API_VERSION(1, 0, 0, 1));
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .add_component_layers({explicit_layer_name})
-                                                                         .set_disable_environment(disable_env_var)),
-        "override_meta_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .add_component_layers({explicit_layer_name})
+                                                                             .set_disable_environment(disable_env_var)));
 
     uint32_t count = 0;
     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
@@ -2087,24 +2154,23 @@
 
 TEST(ExplicitLayers, LayerSettingsPreInstanceFunctions) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
     const char* explicit_layer_name = "VK_LAYER_enabled_by_override";
 
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(explicit_layer_name)
-                .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceLayerProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceExtensionProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceVersion")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
-        "explicit_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(explicit_layer_name)
+                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceLayerProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceExtensionProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceVersion")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceVersion"))));
 
     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
         LoaderSettingsLayerConfiguration{}
@@ -2139,24 +2205,23 @@
 
 TEST(ExplicitLayers, ContainsPreInstanceFunctions) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
     const char* explicit_layer_name = "VK_LAYER_enabled_by_override";
 
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(explicit_layer_name)
-                .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceLayerProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceExtensionProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceVersion")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
-        "explicit_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(explicit_layer_name)
+                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceLayerProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceExtensionProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceVersion")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceVersion"))));
 
     auto& layer = env.get_test_layer(0);
     layer.set_reported_layer_props(34);
@@ -2184,13 +2249,12 @@
 
 TEST(ExplicitLayers, CallsPreInstanceFunctionsInCreateInstance) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
     const char* explicit_layer_name = "VK_LAYER_enabled_by_override";
 
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     auto& layer = env.get_test_layer(0);
     layer.set_query_vkEnumerateInstanceLayerProperties(true);
@@ -2209,15 +2273,12 @@
 // succeeds and doesn't crash.
 TEST(LayerCreateInstance, GetPhysicalDeviceProperties2) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA))
-        .add_physical_device({})
-        .set_icd_api_version(VK_API_VERSION_1_1);
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({}).set_icd_api_version(VK_API_VERSION_1_1);
 
     const char* regular_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     auto& layer_handle = env.get_test_layer(0);
     layer_handle.set_create_instance_callback([](TestLayer& layer) -> VkResult {
@@ -2248,15 +2309,14 @@
 
 TEST(LayerCreateInstance, GetPhysicalDeviceProperties2KHR) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)
         .add_physical_device({})
         .add_instance_extension({"VK_KHR_get_physical_device_properties2", 0});
 
     const char* regular_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     auto& layer_handle = env.get_test_layer(0);
     layer_handle.set_create_instance_callback([](TestLayer& layer) -> VkResult {
@@ -2281,12 +2341,13 @@
 
 TEST(ExplicitLayers, MultipleLayersInSingleManifest) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1";
     const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2";
     const char* regular_layer_name_3 = "VK_LAYER_RegularLayer3";
-    env.add_explicit_layer(TestLayerDetails(
+    env.add_explicit_layer(
+        {},
         ManifestLayer{}
             .set_file_format_version({1, 0, 1})
             .add_layer(
@@ -2294,8 +2355,7 @@
             .add_layer(
                 ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2))
             .add_layer(
-                ManifestLayer::LayerDescription{}.set_name(regular_layer_name_3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "multi_layer_manifest.json"));
+                ManifestLayer::LayerDescription{}.set_name(regular_layer_name_3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     auto layer_props = env.GetLayerProperties(3);
     ASSERT_TRUE(string_eq(regular_layer_name_1, layer_props[0].layerName));
@@ -2305,24 +2365,22 @@
 
 TEST(ExplicitLayers, WrapObjects) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device("physical_device_0");
 
     const char* wrap_objects_name = "VK_LAYER_LUNARG_wrap_objects";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(
-                               ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-                           "wrap_objects_layer.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_layer_1.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_layer_2.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     {  // just the wrap layer
         InstWrapper inst{env.vulkan_functions};
@@ -2364,17 +2422,14 @@
 
 TEST(ExplicitLayers, VkLayerPathEnvVar) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     // verify layer loads successfully when setting VK_LAYER_PATH to a full filepath
     const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1";
     env.add_explicit_layer(
-        TestLayerDetails(
-            ManifestLayer{}.add_layer(
-                ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-            "regular_layer_1.json")
-            .set_discovery_type(ManifestDiscoveryType::env_var)
-            .set_is_dir(false));
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     InstWrapper inst(env.vulkan_functions);
     inst.create_info.add_layer(regular_layer_name_1);
@@ -2385,26 +2440,20 @@
 
 TEST(ExplicitLayers, VkLayerPathEnvVarContainsMultipleFilepaths) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     // verify layers load successfully when setting VK_LAYER_PATH to multiple full filepaths
     const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1";
     env.add_explicit_layer(
-        TestLayerDetails(
-            ManifestLayer{}.add_layer(
-                ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-            "regular_layer_1.json")
-            .set_discovery_type(ManifestDiscoveryType::env_var)
-            .set_is_dir(false));
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2";
     env.add_explicit_layer(
-        TestLayerDetails(
-            ManifestLayer{}.add_layer(
-                ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-            "regular_layer_2.json")
-            .set_discovery_type(ManifestDiscoveryType::env_var)
-            .set_is_dir(false));
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     InstWrapper inst(env.vulkan_functions);
     inst.create_info.add_layer(regular_layer_name_1);
@@ -2416,24 +2465,20 @@
 
 TEST(ExplicitLayers, VkLayerPathEnvVarIsDirectory) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     // verify layers load successfully when setting VK_LAYER_PATH to a directory
     const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1";
     env.add_explicit_layer(
-        TestLayerDetails(
-            ManifestLayer{}.add_layer(
-                ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-            "regular_layer_1.json")
-            .set_discovery_type(ManifestDiscoveryType::env_var));
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2";
     env.add_explicit_layer(
-        TestLayerDetails(
-            ManifestLayer{}.add_layer(
-                ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-            "regular_layer_2.json")
-            .set_discovery_type(ManifestDiscoveryType::env_var));
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     InstWrapper inst(env.vulkan_functions);
     inst.create_info.add_layer(regular_layer_name_1);
@@ -2445,39 +2490,35 @@
 
 TEST(ExplicitLayers, DuplicateLayersInVK_LAYER_PATH) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     // verify layer loads successfully when setting VK_LAYER_PATH to a full filepath
     const char* same_layer_name_1 = "VK_LAYER_RegularLayer1";
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(same_layer_name_1)
-                                                                          .set_description("actually_layer_1")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "regular_layer_1.json")
+    env.add_explicit_layer(ManifestOptions{}
                                // use override folder as just a folder and manually set the VK_LAYER_PATH env-var to it
                                .set_discovery_type(ManifestDiscoveryType::override_folder)
-                               .set_is_dir(true));
+                               .set_is_dir(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(same_layer_name_1)
+                                                         .set_description("actually_layer_1")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     auto& layer1 = env.get_test_layer(0);
     layer1.set_description("actually_layer_1");
     layer1.set_make_spurious_log_in_create_instance("actually_layer_1");
     env.env_var_vk_layer_paths.add_to_list(env.get_folder(ManifestLocation::override_layer).location());
 
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(same_layer_name_1)
-                                                                          .set_description("actually_layer_2")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "regular_layer_1.json")
-                               .set_discovery_type(ManifestDiscoveryType::env_var)
-                               .set_is_dir(true));
+    env.add_explicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var).set_is_dir(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(same_layer_name_1)
+                                                         .set_description("actually_layer_2")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     auto& layer2 = env.get_test_layer(1);
     layer2.set_description("actually_layer_2");
     layer2.set_make_spurious_log_in_create_instance("actually_layer_2");
 
-    auto layer_props = env.GetLayerProperties(2);
+    auto layer_props = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[0].layerName));
-    ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[1].layerName));
     ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description));
-    ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description));
     {
         InstWrapper inst{env.vulkan_functions};
         inst.create_info.add_layer(same_layer_name_1);
@@ -2520,38 +2561,33 @@
 
 TEST(ExplicitLayers, DuplicateLayersInVK_ADD_LAYER_PATH) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* same_layer_name_1 = "VK_LAYER_RegularLayer1";
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(same_layer_name_1)
-                                                                          .set_description("actually_layer_1")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "regular_layer_1.json")
+    env.add_explicit_layer(ManifestOptions{}
                                // use override folder as just a folder and manually set the VK_ADD_LAYER_PATH env-var to it
-                               .set_discovery_type(ManifestDiscoveryType::override_folder)
-                               .set_is_dir(true));
+                               .set_discovery_type(ManifestDiscoveryType::override_folder),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(same_layer_name_1)
+                                                         .set_description("actually_layer_1")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     auto& layer1 = env.get_test_layer(0);
     layer1.set_description("actually_layer_1");
     layer1.set_make_spurious_log_in_create_instance("actually_layer_1");
     env.add_env_var_vk_layer_paths.add_to_list(env.get_folder(ManifestLocation::override_layer).location());
 
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(same_layer_name_1)
-                                                                          .set_description("actually_layer_2")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "regular_layer_1.json")
-                               .set_discovery_type(ManifestDiscoveryType::add_env_var)
-                               .set_is_dir(true));
+    env.add_explicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var).set_is_dir(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(same_layer_name_1)
+                                                         .set_description("actually_layer_2")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     auto& layer2 = env.get_test_layer(1);
     layer2.set_description("actually_layer_2");
     layer2.set_make_spurious_log_in_create_instance("actually_layer_2");
 
-    auto layer_props = env.GetLayerProperties(2);
+    auto layer_props = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[0].layerName));
-    ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[1].layerName));
     ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description));
-    ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description));
     {
         InstWrapper inst{env.vulkan_functions};
         inst.create_info.add_layer(same_layer_name_1);
@@ -2594,27 +2630,23 @@
 
 TEST(ExplicitLayers, CorrectOrderOfEnvVarEnabledLayers) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* layer_name_1 = "VK_LAYER_RegularLayer1";
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name_1)
-                                                                          .set_description("actually_layer_1")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "regular_layer_1.json")
-                               .set_discovery_type(ManifestDiscoveryType::env_var)
-                               .set_is_dir(true));
+    env.add_explicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var).set_is_dir(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name_1)
+                                                         .set_description("actually_layer_1")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     auto& layer1 = env.get_test_layer(0);
     layer1.set_description("actually_layer_1");
 
     const char* layer_name_2 = "VK_LAYER_RegularLayer2";
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name_2)
-                                                                          .set_description("actually_layer_2")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "regular_layer_2.json")
-                               .set_discovery_type(ManifestDiscoveryType::env_var)
-                               .set_is_dir(true));
+    env.add_explicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var).set_is_dir(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name_2)
+                                                         .set_description("actually_layer_2")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     auto& layer2 = env.get_test_layer(1);
     layer2.set_description("actually_layer_2");
 
@@ -2659,36 +2691,31 @@
 // Test to make sure order layers are found in VK_LAYER_PATH is what decides which layer is loaded
 TEST(ExplicitLayers, DuplicateLayersInVkLayerPath) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* layer_name = "VK_LAYER_RegularLayer1";
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name)
-                                                                          .set_description("actually_layer_1")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "layer.json")
-                               .set_discovery_type(ManifestDiscoveryType::env_var)
-                               .set_is_dir(true));
+    env.add_explicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var).set_is_dir(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_description("actually_layer_1")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     auto& layer1 = env.get_test_layer(0);
     layer1.set_description("actually_layer_1");
 
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name)
-                                                                          .set_description("actually_layer_2")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "layer.json")
-                               // putting it in a separate folder then manually adding the folder to VK_LAYER_PATH
+    env.add_explicit_layer(ManifestOptions{}  // putting it in a separate folder then manually adding the folder to VK_LAYER_PATH
                                .set_discovery_type(ManifestDiscoveryType::override_folder)
-                               .set_is_dir(true));
+                               .set_is_dir(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_description("actually_layer_2")
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     auto& layer2 = env.get_test_layer(1);
     layer2.set_description("actually_layer_2");
     env.env_var_vk_layer_paths.add_to_list(env.get_folder(ManifestLocation::override_layer).location().string());
 
-    auto layer_props = env.GetLayerProperties(2);
+    auto layer_props = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layer_name, layer_props[0].layerName));
     ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description));
-    ASSERT_TRUE(string_eq(layer_name, layer_props[1].layerName));
-    ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description));
 
     EnvVarWrapper inst_layers_env_var{"VK_INSTANCE_LAYERS"};
     inst_layers_env_var.add_to_list(layer_name);
@@ -2704,23 +2731,21 @@
 
 TEST(ExplicitLayers, CorrectOrderOfEnvVarEnabledLayersFromSystemLocations) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* layer_name_1 = "VK_LAYER_RegularLayer1";
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name_1)
-                                                                          .set_description("actually_layer_1")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "regular_layer_1.json"));
+    env.add_explicit_layer(ManifestOptions{}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                                            .set_name(layer_name_1)
+                                                                            .set_description("actually_layer_1")
+                                                                            .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     auto& layer1 = env.get_test_layer(0);
     layer1.set_description("actually_layer_1");
 
     const char* layer_name_2 = "VK_LAYER_RegularLayer2";
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name_2)
-                                                                          .set_description("actually_layer_2")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "regular_layer_2.json"));
+    env.add_explicit_layer(ManifestOptions{}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                                            .set_name(layer_name_2)
+                                                                            .set_description("actually_layer_2")
+                                                                            .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     auto& layer2 = env.get_test_layer(1);
     layer2.set_description("actually_layer_2");
 
@@ -2763,24 +2788,22 @@
 
 TEST(ExplicitLayers, CorrectOrderOfApplicationEnabledLayers) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* layer_name_1 = "VK_LAYER_RegularLayer1";
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name_1)
-                                                                          .set_description("actually_layer_1")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "regular_layer_1.json"));
+    env.add_explicit_layer(ManifestOptions{}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                                            .set_name(layer_name_1)
+                                                                            .set_description("actually_layer_1")
+                                                                            .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     auto& layer1 = env.get_test_layer(0);
     layer1.set_description("actually_layer_1");
     layer1.set_make_spurious_log_in_create_instance("actually_layer_1");
 
     const char* layer_name_2 = "VK_LAYER_RegularLayer2";
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name_2)
-                                                                          .set_description("actually_layer_2")
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "regular_layer_2.json"));
+    env.add_explicit_layer(ManifestOptions{}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                                            .set_name(layer_name_2)
+                                                                            .set_description("actually_layer_2")
+                                                                            .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     auto& layer2 = env.get_test_layer(1);
     layer2.set_description("actually_layer_2");
     layer2.set_make_spurious_log_in_create_instance("actually_layer_2");
@@ -2823,20 +2846,29 @@
     }
 }
 
+// Helpers
+bool contains(std::vector<VkExtensionProperties> const& vec, const char* name) {
+    return std::any_of(std::begin(vec), std::end(vec),
+                       [name](VkExtensionProperties const& elem) { return string_eq(name, elem.extensionName); });
+}
+bool contains(std::vector<VkLayerProperties> const& vec, const char* name) {
+    return std::any_of(std::begin(vec), std::end(vec),
+                       [name](VkLayerProperties const& elem) { return string_eq(name, elem.layerName); });
+}
+
 TEST(LayerExtensions, ImplicitNoAdditionalInstanceExtension) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     const char* enable_env_var = "ENABLE_ME";
     const char* disable_env_var = "DISABLE_ME";
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_WRAP_OBJECTS)
-                                                         .set_disable_environment(disable_env_var)
-                                                         .set_enable_environment(enable_env_var)),
-                           "implicit_wrap_layer_no_ext.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_WRAP_OBJECTS)
+                                                             .set_disable_environment(disable_env_var)
+                                                             .set_enable_environment(enable_env_var)));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name));
@@ -2865,21 +2897,20 @@
 
 TEST(LayerExtensions, ImplicitDirDispModeInstanceExtension) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     const char* enable_env_var = "ENABLE_ME";
     const char* disable_env_var = "DISABLE_ME";
 
     env.add_implicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(implicit_layer_name)
-                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
-                .set_disable_environment(disable_env_var)
-                .set_enable_environment(enable_env_var)
-                .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})),
-        "implicit_wrap_layer_dir_disp_mode.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(implicit_layer_name)
+                    .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
+                    .set_disable_environment(disable_env_var)
+                    .set_enable_environment(enable_env_var)
+                    .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name));
@@ -2909,21 +2940,21 @@
 
 TEST(LayerExtensions, ImplicitDispSurfCountInstanceExtension) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     const char* enable_env_var = "ENABLE_ME";
     const char* disable_env_var = "DISABLE_ME";
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
-                                                         .set_disable_environment(disable_env_var)
-                                                         .set_enable_environment(enable_env_var)
-                                                         .add_instance_extension({VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME,
-                                                                                  1,
-                                                                                  {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})),
-                           "implicit_wrap_layer_disp_surf_count.json");
+    env.add_implicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(implicit_layer_name)
+                    .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
+                    .set_disable_environment(disable_env_var)
+                    .set_enable_environment(enable_env_var)
+                    .add_instance_extension(
+                        {VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 1, {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name));
@@ -2950,23 +2981,22 @@
 
 TEST(LayerExtensions, ImplicitBothInstanceExtensions) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     const char* enable_env_var = "ENABLE_ME";
     const char* disable_env_var = "DISABLE_ME";
 
     env.add_implicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(implicit_layer_name)
-                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
-                .set_disable_environment(disable_env_var)
-                .set_enable_environment(enable_env_var)
-                .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})
-                .add_instance_extension(
-                    {VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 1, {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})),
-        "implicit_wrap_layer_both_inst.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(implicit_layer_name)
+                    .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
+                    .set_disable_environment(disable_env_var)
+                    .set_enable_environment(enable_env_var)
+                    .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})
+                    .add_instance_extension(
+                        {VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 1, {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name));
@@ -2995,13 +3025,12 @@
 
 TEST(LayerExtensions, ExplicitNoAdditionalInstanceExtension) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-        "explicit_wrap_layer_no_ext.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name));
@@ -3025,16 +3054,15 @@
 
 TEST(LayerExtensions, ExplicitDirDispModeInstanceExtension) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(explicit_layer_name)
-                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
-                .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})),
-        "explicit_wrap_layer_dir_disp_mode.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(explicit_layer_name)
+                    .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
+                    .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name));
@@ -3068,16 +3096,16 @@
 
 TEST(LayerExtensions, ExplicitDispSurfCountInstanceExtension) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(explicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
-                                                         .add_instance_extension({VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME,
-                                                                                  1,
-                                                                                  {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})),
-                           "explicit_wrap_layer_disp_surf_count.json");
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(explicit_layer_name)
+                    .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
+                    .add_instance_extension(
+                        {VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 1, {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name));
@@ -3111,18 +3139,17 @@
 
 TEST(LayerExtensions, ExplicitBothInstanceExtensions) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(explicit_layer_name)
-                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
-                .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})
-                .add_instance_extension(
-                    {VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 1, {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})),
-        "explicit_wrap_layer_both_inst.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(explicit_layer_name)
+                    .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
+                    .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})
+                    .add_instance_extension(
+                        {VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 1, {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name));
@@ -3171,18 +3198,17 @@
 
 TEST(LayerExtensions, ImplicitNoAdditionalDeviceExtension) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     const char* enable_env_var = "ENABLE_ME";
     const char* disable_env_var = "DISABLE_ME";
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_WRAP_OBJECTS)
-                                                         .set_disable_environment(disable_env_var)
-                                                         .set_enable_environment(enable_env_var)),
-                           "implicit_wrap_layer_no_ext.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_WRAP_OBJECTS)
+                                                             .set_disable_environment(disable_env_var)
+                                                             .set_enable_environment(enable_env_var)));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name));
@@ -3229,18 +3255,17 @@
 
 TEST(LayerExtensions, ImplicitMaintenanceDeviceExtension) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     const char* enable_env_var = "ENABLE_ME";
     const char* disable_env_var = "DISABLE_ME";
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
-                                                         .set_disable_environment(disable_env_var)
-                                                         .set_enable_environment(enable_env_var)),
-                           "implicit_wrap_layer_maint.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
+                                                             .set_disable_environment(disable_env_var)
+                                                             .set_enable_environment(enable_env_var)));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name));
@@ -3266,18 +3291,17 @@
 
 TEST(LayerExtensions, ImplicitPresentImageDeviceExtension) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     const char* enable_env_var = "ENABLE_ME";
     const char* disable_env_var = "DISABLE_ME";
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
-                                                         .set_disable_environment(disable_env_var)
-                                                         .set_enable_environment(enable_env_var)),
-                           "implicit_wrap_layer_pres.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
+                                                             .set_disable_environment(disable_env_var)
+                                                             .set_enable_environment(enable_env_var)));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name));
@@ -3303,18 +3327,17 @@
 
 TEST(LayerExtensions, ImplicitBothDeviceExtensions) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     const char* enable_env_var = "ENABLE_ME";
     const char* disable_env_var = "DISABLE_ME";
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
-                                                         .set_disable_environment(disable_env_var)
-                                                         .set_enable_environment(enable_env_var)),
-                           "implicit_wrap_layer_both_dev.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
+                                                             .set_disable_environment(disable_env_var)
+                                                             .set_enable_environment(enable_env_var)));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name));
@@ -3341,13 +3364,12 @@
 
 TEST(LayerExtensions, ExplicitNoAdditionalDeviceExtension) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
-        "explicit_wrap_layer_no_ext.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name));
@@ -3371,16 +3393,15 @@
 
 TEST(LayerExtensions, ExplicitMaintenanceDeviceExtension) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
-    env.add_explicit_layer(
-        ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                      .set_name(explicit_layer_name)
-                                      .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
-                                      .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
-                                      .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})),
-        "explicit_wrap_layer_maint.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(
+                                   ManifestLayer::LayerDescription{}
+                                       .set_name(explicit_layer_name)
+                                       .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
+                                       .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
+                                       .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name));
@@ -3405,17 +3426,16 @@
 
 TEST(LayerExtensions, ExplicitPresentImageDeviceExtension) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(explicit_layer_name)
-                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
-                .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
-                .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})),
-        "explicit_wrap_layer_pres.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(explicit_layer_name)
+                    .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
+                    .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
+                    .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name));
@@ -3440,18 +3460,17 @@
 
 TEST(LayerExtensions, ExplicitBothDeviceExtensions) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(explicit_layer_name)
-                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
-                .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
-                .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
-                .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})),
-        "explicit_wrap_layer_both_dev.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(explicit_layer_name)
+                    .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
+                    .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
+                    .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
+                    .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})));
 
     auto layers = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name));
@@ -3487,17 +3506,16 @@
 TEST(TestLayers, ExplicitlyEnableImplicitLayer) {
     FrameworkEnvironment env;
     uint32_t api_version = VK_API_VERSION_1_2;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, api_version))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(api_version))
         .set_icd_api_version(api_version)
         .add_physical_device(PhysicalDevice{}.set_api_version(api_version).finish());
 
     const char* regular_layer_name = "VK_LAYER_TestLayer1";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(regular_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                         .set_disable_environment("DisableMeIfYouCan")),
-                           "regular_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(regular_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                             .set_disable_environment("DisableMeIfYouCan")));
     {  // 1.1 instance
         InstWrapper inst{env.vulkan_functions};
         inst.create_info.add_layer(regular_layer_name);
@@ -3518,17 +3536,16 @@
 TEST(TestLayers, NewerInstanceVersionThanImplicitLayer) {
     FrameworkEnvironment env;
     uint32_t api_version = VK_API_VERSION_1_2;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, api_version))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(api_version))
         .set_icd_api_version(api_version)
         .add_physical_device(PhysicalDevice{}.set_api_version(api_version).finish());
 
     const char* regular_layer_name = "VK_LAYER_TestLayer1";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(regular_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                         .set_disable_environment("DisableMeIfYouCan")),
-                           "regular_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(regular_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                             .set_disable_environment("DisableMeIfYouCan")));
     {  // global functions
         auto layer_props = env.GetLayerProperties(1);
         EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
@@ -3559,17 +3576,16 @@
 TEST(TestLayers, ImplicitLayerPre10APIVersion) {
     FrameworkEnvironment env;
     uint32_t api_version = VK_API_VERSION_1_2;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, api_version))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(api_version))
         .set_icd_api_version(api_version)
         .add_physical_device(PhysicalDevice{}.set_api_version(api_version).finish());
 
     const char* regular_layer_name = "VK_LAYER_TestLayer1";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(regular_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 0, 1, 0))
-                                                         .set_disable_environment("DisableMeIfYouCan")),
-                           "regular_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(regular_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_MAKE_API_VERSION(0, 0, 1, 0))
+                                                             .set_disable_environment("DisableMeIfYouCan")));
     {  // global functions
         auto layer_props = env.GetLayerProperties(1);
         EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
@@ -3621,20 +3637,19 @@
 TEST(TestLayers, InstEnvironEnableExplicitLayer) {
     FrameworkEnvironment env;
     uint32_t api_version = VK_API_VERSION_1_2;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, api_version))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(api_version))
         .set_icd_api_version(api_version)
         .add_physical_device(PhysicalDevice{}.set_api_version(api_version).finish());
 
     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(explicit_layer_name)
-                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
-                .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
-                .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
-                .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})),
-        "explicit_wrap_layer_both_dev.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(explicit_layer_name)
+                    .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
+                    .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
+                    .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
+                    .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})));
 
     // First, test an instance/device without the layer forced on.  The extensions shouldn't be present and
     // the function pointers should be NULL.
@@ -3683,33 +3698,33 @@
 TEST(TestLayers, EnvironLayerEnableExplicitLayer) {
     FrameworkEnvironment env;
     uint32_t api_version = VK_API_VERSION_1_2;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, api_version))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(api_version))
         .set_icd_api_version(api_version)
         .add_physical_device(PhysicalDevice{});
 
     const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer";
     const char* explicit_json_name_1 = "First_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_1),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_1)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           explicit_json_name_1);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* explicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer";
     const char* explicit_json_name_2 = "Second_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_2),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_2)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           explicit_json_name_2);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* explicit_layer_name_3 = "VK_LAYER_LUNARG_second_test_layer";
     const char* explicit_json_name_3 = "second_test_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_3),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_3)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           explicit_json_name_3);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     EnvVarWrapper layers_enable_env_var{"VK_LOADER_LAYERS_ENABLE"};
 
@@ -3868,33 +3883,33 @@
 // it is set with VK_LOADER_LAYERS_DISABLE
 TEST(TestLayers, EnvironLayerDisableExplicitLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2)
         .add_physical_device(PhysicalDevice{});
 
     const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer";
     const char* explicit_json_name_1 = "First_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_1),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_1)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           explicit_json_name_1);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* explicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer";
     const char* explicit_json_name_2 = "Second_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_2),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_2)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           explicit_json_name_2);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* explicit_layer_name_3 = "VK_LAYER_LUNARG_Second_test_layer";
     const char* explicit_json_name_3 = "Second_test_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_3),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_3)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           explicit_json_name_3);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
     EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"};
 
     // First, test an instance/device without the layer forced on.
@@ -4105,32 +4120,32 @@
 // enabled)
 TEST(TestLayers, EnvironLayerEnableDisableExplicitLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2);
 
     const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer";
     const char* explicit_json_name_1 = "First_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_1),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_1)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           explicit_json_name_1);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* explicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer";
     const char* explicit_json_name_2 = "Second_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_2),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_2)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           explicit_json_name_2);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* explicit_layer_name_3 = "VK_LAYER_LUNARG_Second_test_layer";
     const char* explicit_json_name_3 = "Second_test_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_3),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_3)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           explicit_json_name_3);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     EnvVarWrapper layers_enable_env_var{"VK_LOADER_LAYERS_ENABLE"};
     EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"};
@@ -4299,24 +4314,24 @@
 // enabled)
 TEST(TestLayers, EnvironVkInstanceLayersAndDisableFilters) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2);
 
     const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer";
     const char* explicit_json_name_1 = "First_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_1),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_1)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           explicit_json_name_1);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     const char* explicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer";
     const char* explicit_json_name_2 = "Second_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_2),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_2)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           explicit_json_name_2);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     EnvVarWrapper layers_enable_env_var{"VK_INSTANCE_LAYERS"};
     EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"};
@@ -4378,13 +4393,12 @@
 // Verify that layers enabled through VK_INSTANCE_LAYERS which were not found get the proper error message
 TEST(TestLayers, NonExistantLayerInVK_INSTANCE_LAYERS) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* layer_name = "VK_LAYER_test_layer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     EnvVarWrapper layers_enable_env_var{"VK_INSTANCE_LAYERS", "VK_LAYER_I_dont_exist"};
     {
@@ -4425,13 +4439,12 @@
 // Verify that if the same layer appears twice in VK_INSTANCE_LAYERS nothing bad happens
 TEST(TestLayers, DuplicatesInEnvironVK_INSTANCE_LAYERS) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* layer_name = "VK_LAYER_test_layer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     EnvVarWrapper layers_enable_env_var{"VK_INSTANCE_LAYERS"};
 
@@ -4447,16 +4460,16 @@
 
 TEST(TestLayers, AppEnabledExplicitLayerFails) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2);
 
     const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer";
     const char* explicit_json_name_1 = "First_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_1),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_1)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
-                           explicit_json_name_1);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))));
 
     env.debug_log.clear();
     EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE", explicit_layer_name_1};
@@ -4476,23 +4489,23 @@
 
 TEST(TestLayers, OverrideEnabledExplicitLayerWithDisableFilter) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2);
 
     const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer";
     const char* explicit_json_name_1 = "First_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_1),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_1)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))),
-                           explicit_json_name_1);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))));
+
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .add_component_layer(explicit_layer_name_1)
-                                                                         .set_disable_environment("DisableMeIfYouCan")),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_component_layer(explicit_layer_name_1)
+                                                                             .set_disable_environment("DisableMeIfYouCan")));
 
     env.debug_log.clear();
     EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE", explicit_layer_name_1};
@@ -4526,23 +4539,22 @@
 
 TEST(TestLayers, OverrideEnabledExplicitLayerWithDisableFilterForOverrideLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2);
 
     const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer";
     const char* explicit_json_name_1 = "First_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_1),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_1)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))),
-                           explicit_json_name_1);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))));
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .add_component_layer(explicit_layer_name_1)
-                                                                         .set_disable_environment("DisableMeIfYouCan")),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_component_layer(explicit_layer_name_1)
+                                                                             .set_disable_environment("DisableMeIfYouCan")));
 
     env.debug_log.clear();
     EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE", lunarg_meta_layer_name};
@@ -4576,23 +4588,22 @@
 
 TEST(TestLayers, OverrideBlacklistedLayerWithEnableFilter) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2);
 
     const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer";
     const char* explicit_json_name_1 = "First_layer.json";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+    env.add_explicit_layer(ManifestOptions{}.set_json_name(explicit_json_name_1),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                                          .set_name(explicit_layer_name_1)
                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))),
-                           explicit_json_name_1);
+                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))));
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(lunarg_meta_layer_name)
-                                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                                         .add_blacklisted_layer(explicit_layer_name_1)
-                                                                         .set_disable_environment("DisableMeIfYouCan")),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(lunarg_meta_layer_name)
+                                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                                             .add_blacklisted_layer(explicit_layer_name_1)
+                                                                             .set_disable_environment("DisableMeIfYouCan")));
 
     env.debug_log.clear();
     EnvVarWrapper layers_enable_env_var{"VK_LOADER_LAYERS_ENABLE", explicit_layer_name_1};
@@ -4626,20 +4637,19 @@
 // Add a device layer, should not work
 TEST(TestLayers, DoNotUseDeviceLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2)
         .add_physical_device(PhysicalDevice{}.set_api_version(VK_API_VERSION_1_2).finish());
 
     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(explicit_layer_name)
-                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
-                .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
-                .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
-                .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})),
-        "explicit_wrap_layer_both_dev.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(explicit_layer_name)
+                    .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
+                    .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
+                    .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
+                    .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})));
 
     // First, test an instance/device without the layer forced on.  The extensions shouldn't be present and
     // the function pointers should be NULL.
@@ -4686,20 +4696,19 @@
 // Make sure that a layer enabled as both an instance and device layer works properly.
 TEST(TestLayers, InstanceAndDeviceLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2)
         .add_physical_device(PhysicalDevice{}.set_api_version(VK_API_VERSION_1_2).finish());
 
     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(explicit_layer_name)
-                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
-                .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
-                .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
-                .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})),
-        "explicit_wrap_layer_both_dev.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(explicit_layer_name)
+                    .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
+                    .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
+                    .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
+                    .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})));
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.add_layer(explicit_layer_name);
@@ -4723,7 +4732,7 @@
 // Make sure loader does not throw an error for a device layer  that is not present
 TEST(TestLayers, DeviceLayerNotPresent) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
         .set_icd_api_version(VK_API_VERSION_1_2)
         .add_physical_device(PhysicalDevice{}.set_api_version(VK_API_VERSION_1_2).finish());
     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
@@ -4739,22 +4748,22 @@
 
 TEST(LayerPhysDeviceMod, AddPhysicalDevices) {
     FrameworkEnvironment env;
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_LunarG_add_phys_dev")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_API_VERSION_1_1)
-                                                         .set_disable_environment("TEST_DISABLE_ADD_PHYS_DEV")),
-                           "test_layer_add.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_LunarG_add_phys_dev")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_API_VERSION_1_1)
+                                                             .set_disable_environment("TEST_DISABLE_ADD_PHYS_DEV")));
 
     auto& layer = env.get_test_layer(0);
     layer.set_add_phys_devs(true);
 
     for (uint32_t icd = 0; icd < 2; ++icd) {
-        auto& cur_icd =
-            env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2);
+        auto& cur_icd = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
+                            .set_icd_api_version(VK_API_VERSION_1_2);
         VkPhysicalDeviceProperties properties{};
         properties.apiVersion = VK_API_VERSION_1_2;
         properties.vendorID = 0x11000000 + (icd << 6);
+        std::array<PhysicalDevice*, 3> added_phys_devs;
         for (uint32_t dev = 0; dev < 3; ++dev) {
             properties.deviceID = properties.vendorID + dev;
             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
@@ -4764,12 +4773,11 @@
 #else
             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
 #endif
-            cur_icd.add_physical_device({});
-            cur_icd.physical_devices.back().set_properties(properties);
+            added_phys_devs[dev] = &cur_icd.add_and_get_physical_device({}).set_properties(properties);
         }
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
-        cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[0]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[1]);
+        cur_icd.physical_device_groups.back().use_physical_device(added_phys_devs[2]);
     }
     const uint32_t icd_devices = 6;
 
@@ -4816,22 +4824,22 @@
 
 TEST(LayerPhysDeviceMod, RemovePhysicalDevices) {
     FrameworkEnvironment env;
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_LunarG_remove_phys_dev")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_API_VERSION_1_1)
-                                                         .set_disable_environment("TEST_DISABLE_REMOVE_PHYS_DEV")),
-                           "test_layer_remove.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_LunarG_remove_phys_dev")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_API_VERSION_1_1)
+                                                             .set_disable_environment("TEST_DISABLE_REMOVE_PHYS_DEV")));
 
     auto& layer = env.get_test_layer(0);
     layer.set_remove_phys_devs(true);
 
     for (uint32_t icd = 0; icd < 2; ++icd) {
-        auto& cur_icd =
-            env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2);
+        auto& cur_icd = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
+                            .set_icd_api_version(VK_API_VERSION_1_2);
         VkPhysicalDeviceProperties properties{};
         properties.apiVersion = VK_API_VERSION_1_2;
         properties.vendorID = 0x11000000 + (icd << 6);
+        std::array<PhysicalDevice*, 3> added_phys_devs;
         for (uint32_t dev = 0; dev < 3; ++dev) {
             properties.deviceID = properties.vendorID + dev;
             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
@@ -4841,12 +4849,11 @@
 #else
             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
 #endif
-            cur_icd.add_physical_device({});
-            cur_icd.physical_devices.back().set_properties(properties);
+            added_phys_devs[dev] = &cur_icd.add_and_get_physical_device({}).set_properties(properties);
         }
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
-        cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[0]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[1]);
+        cur_icd.physical_device_groups.back().use_physical_device(added_phys_devs[2]);
     }
     const uint32_t icd_devices = 6;
 
@@ -4866,22 +4873,22 @@
 
 TEST(LayerPhysDeviceMod, ReorderPhysicalDevices) {
     FrameworkEnvironment env;
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_LunarG_reorder_phys_dev")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_API_VERSION_1_1)
-                                                         .set_disable_environment("TEST_DISABLE_REORDER_PHYS_DEV")),
-                           "test_layer_reorder.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_LunarG_reorder_phys_dev")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_API_VERSION_1_1)
+                                                             .set_disable_environment("TEST_DISABLE_REORDER_PHYS_DEV")));
 
     auto& layer = env.get_test_layer(0);
     layer.set_reorder_phys_devs(true);
 
     for (uint32_t icd = 0; icd < 2; ++icd) {
-        auto& cur_icd =
-            env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2);
+        auto& cur_icd = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
+                            .set_icd_api_version(VK_API_VERSION_1_2);
         VkPhysicalDeviceProperties properties{};
         properties.apiVersion = VK_API_VERSION_1_2;
         properties.vendorID = 0x11000000 + (icd << 6);
+        std::array<PhysicalDevice*, 3> added_phys_devs;
         for (uint32_t dev = 0; dev < 3; ++dev) {
             properties.deviceID = properties.vendorID + dev;
             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
@@ -4891,12 +4898,11 @@
 #else
             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
 #endif
-            cur_icd.add_physical_device({});
-            cur_icd.physical_devices.back().set_properties(properties);
+            added_phys_devs[dev] = &cur_icd.add_and_get_physical_device({}).set_properties(properties);
         }
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
-        cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[0]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[1]);
+        cur_icd.physical_device_groups.back().use_physical_device(added_phys_devs[2]);
     }
     const uint32_t icd_devices = 6;
 
@@ -4916,22 +4922,22 @@
 
 TEST(LayerPhysDeviceMod, AddRemoveAndReorderPhysicalDevices) {
     FrameworkEnvironment env;
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_LunarG_all_phys_dev")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_API_VERSION_1_1)
-                                                         .set_disable_environment("TEST_DISABLE_ALL_PHYS_DEV")),
-                           "test_layer_all.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_LunarG_all_phys_dev")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_API_VERSION_1_1)
+                                                             .set_disable_environment("TEST_DISABLE_ALL_PHYS_DEV")));
 
     auto& layer = env.get_test_layer(0);
     layer.set_add_phys_devs(true).set_remove_phys_devs(true).set_reorder_phys_devs(true);
 
     for (uint32_t icd = 0; icd < 2; ++icd) {
-        auto& cur_icd =
-            env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2);
+        auto& cur_icd = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
+                            .set_icd_api_version(VK_API_VERSION_1_2);
         VkPhysicalDeviceProperties properties{};
         properties.apiVersion = VK_API_VERSION_1_2;
         properties.vendorID = 0x11000000 + (icd << 6);
+        std::array<PhysicalDevice*, 3> added_phys_devs;
         for (uint32_t dev = 0; dev < 3; ++dev) {
             properties.deviceID = properties.vendorID + dev;
             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
@@ -4941,12 +4947,11 @@
 #else
             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
 #endif
-            cur_icd.add_physical_device({});
-            cur_icd.physical_devices.back().set_properties(properties);
+            added_phys_devs[dev] = &cur_icd.add_and_get_physical_device({}).set_properties(properties);
         }
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
-        cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[0]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[1]);
+        cur_icd.physical_device_groups.back().use_physical_device(added_phys_devs[2]);
     }
     const uint32_t icd_devices = 6;
 
@@ -4992,22 +4997,22 @@
 
 TEST(LayerPhysDeviceMod, AddPhysicalDeviceGroups) {
     FrameworkEnvironment env;
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_LunarG_add_phys_dev")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_API_VERSION_1_1)
-                                                         .set_disable_environment("TEST_DISABLE_ADD_PHYS_DEV")),
-                           "test_layer_remove.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_LunarG_add_phys_dev")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_API_VERSION_1_1)
+                                                             .set_disable_environment("TEST_DISABLE_ADD_PHYS_DEV")));
 
     auto& layer = env.get_test_layer(0);
     layer.set_add_phys_devs(true);
 
     for (uint32_t icd = 0; icd < 2; ++icd) {
-        auto& cur_icd =
-            env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2);
+        auto& cur_icd = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
+                            .set_icd_api_version(VK_API_VERSION_1_2);
         VkPhysicalDeviceProperties properties{};
         properties.apiVersion = VK_API_VERSION_1_2;
         properties.vendorID = 0x11000000 + (icd << 6);
+        std::array<PhysicalDevice*, 3> added_phys_devs;
         for (uint32_t dev = 0; dev < 3; ++dev) {
             properties.deviceID = properties.vendorID + dev;
             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
@@ -5017,12 +5022,11 @@
 #else
             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
 #endif
-            cur_icd.add_physical_device({});
-            cur_icd.physical_devices.back().set_properties(properties);
+            added_phys_devs[dev] = &cur_icd.add_and_get_physical_device({}).set_properties(properties);
         }
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
-        cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[0]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[1]);
+        cur_icd.physical_device_groups.back().use_physical_device(added_phys_devs[2]);
     }
     const uint32_t icd_groups = 4;
 
@@ -5079,22 +5083,22 @@
 TEST(LayerPhysDeviceMod, RemovePhysicalDeviceGroups) {
     FrameworkEnvironment env;
     EnvVarWrapper disable_linux_sort("VK_LOADER_DISABLE_SELECT", "1");
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_LunarG_remove_phys_dev")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_API_VERSION_1_1)
-                                                         .set_disable_environment("TEST_DISABLE_REMOVE_PHYS_DEV")),
-                           "test_layer_remove.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_LunarG_remove_phys_dev")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_API_VERSION_1_1)
+                                                             .set_disable_environment("TEST_DISABLE_REMOVE_PHYS_DEV")));
 
     auto& layer = env.get_test_layer(0);
     layer.set_remove_phys_devs(true);
 
     for (uint32_t icd = 0; icd < 2; ++icd) {
-        auto& cur_icd =
-            env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2);
+        auto& cur_icd = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
+                            .set_icd_api_version(VK_API_VERSION_1_2);
         VkPhysicalDeviceProperties properties{};
         properties.apiVersion = VK_API_VERSION_1_2;
         properties.vendorID = 0x11000000 + (icd << 6);
+        std::array<PhysicalDevice*, 3> added_phys_devs;
         for (uint32_t dev = 0; dev < 3; ++dev) {
             properties.deviceID = properties.vendorID + dev;
             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
@@ -5104,12 +5108,11 @@
 #else
             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
 #endif
-            cur_icd.add_physical_device({});
-            cur_icd.physical_devices.back().set_properties(properties);
+            added_phys_devs[dev] = &cur_icd.add_and_get_physical_device({}).set_properties(properties);
         }
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
-        cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[0]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[1]);
+        cur_icd.physical_device_groups.back().use_physical_device(added_phys_devs[2]);
     }
     const uint32_t icd_groups = 3;
 
@@ -5131,22 +5134,22 @@
 
 TEST(LayerPhysDeviceMod, ReorderPhysicalDeviceGroups) {
     FrameworkEnvironment env;
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_LunarG_reorder_phys_dev")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_API_VERSION_1_1)
-                                                         .set_disable_environment("TEST_DISABLE_REORDER_PHYS_DEV")),
-                           "test_layer_reorder.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_LunarG_reorder_phys_dev")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_API_VERSION_1_1)
+                                                             .set_disable_environment("TEST_DISABLE_REORDER_PHYS_DEV")));
 
     auto& layer = env.get_test_layer(0);
     layer.set_reorder_phys_devs(true);
 
     for (uint32_t icd = 0; icd < 2; ++icd) {
-        auto& cur_icd =
-            env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2);
+        auto& cur_icd = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
+                            .set_icd_api_version(VK_API_VERSION_1_2);
         VkPhysicalDeviceProperties properties{};
         properties.apiVersion = VK_API_VERSION_1_2;
         properties.vendorID = 0x11000000 + (icd << 6);
+        std::array<PhysicalDevice*, 3> added_phys_devs;
         for (uint32_t dev = 0; dev < 3; ++dev) {
             properties.deviceID = properties.vendorID + dev;
             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
@@ -5156,12 +5159,11 @@
 #else
             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
 #endif
-            cur_icd.add_physical_device({});
-            cur_icd.physical_devices.back().set_properties(properties);
+            added_phys_devs[dev] = &cur_icd.add_and_get_physical_device({}).set_properties(properties);
         }
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
-        cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[0]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[1]);
+        cur_icd.physical_device_groups.back().use_physical_device(added_phys_devs[2]);
     }
     const uint32_t icd_groups = 4;
 
@@ -5183,22 +5185,22 @@
 
 TEST(LayerPhysDeviceMod, AddRemoveAndReorderPhysicalDeviceGroups) {
     FrameworkEnvironment env;
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_LunarG_all_phys_dev")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_API_VERSION_1_1)
-                                                         .set_disable_environment("TEST_DISABLE_ALL_PHYS_DEV")),
-                           "test_layer_all.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_LunarG_all_phys_dev")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_API_VERSION_1_1)
+                                                             .set_disable_environment("TEST_DISABLE_ALL_PHYS_DEV")));
 
     auto& layer = env.get_test_layer(0);
     layer.set_add_phys_devs(true).set_remove_phys_devs(true).set_reorder_phys_devs(true);
 
     for (uint32_t icd = 0; icd < 2; ++icd) {
-        auto& cur_icd =
-            env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2);
+        auto& cur_icd = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_2))
+                            .set_icd_api_version(VK_API_VERSION_1_2);
         VkPhysicalDeviceProperties properties{};
         properties.apiVersion = VK_API_VERSION_1_2;
         properties.vendorID = 0x11000000 + (icd << 6);
+        std::array<PhysicalDevice*, 3> added_phys_devs;
         for (uint32_t dev = 0; dev < 3; ++dev) {
             properties.deviceID = properties.vendorID + dev;
             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
@@ -5208,12 +5210,11 @@
 #else
             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
 #endif
-            cur_icd.add_physical_device({});
-            cur_icd.physical_devices.back().set_properties(properties);
+            added_phys_devs[dev] = &cur_icd.add_and_get_physical_device({}).set_properties(properties);
         }
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
-        cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[1]);
-        cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[2]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[0]);
+        cur_icd.physical_device_groups.back().use_physical_device(added_phys_devs[1]);
+        cur_icd.physical_device_groups.emplace_back(added_phys_devs[2]);
     }
     const uint32_t icd_groups = 4;
 
@@ -5256,12 +5257,11 @@
 
 TEST(TestLayers, AllowFilterWithExplicitLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* layer_name = "VK_LAYER_test_layer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer_all.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     EnvVarWrapper allow{"VK_LOADER_LAYERS_ALLOW", layer_name};
     {
@@ -5333,14 +5333,13 @@
 
 TEST(TestLayers, AllowFilterWithImplicitLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* layer_name = "VK_LAYER_test_layer";
     const char* disable_env_var = "TEST_DISABLE_ENV_VAR";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment(disable_env_var)),
-                           "test_layer_all.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment(disable_env_var)));
 
     EnvVarWrapper allow{"VK_LOADER_LAYERS_ALLOW", layer_name};
 
@@ -5378,34 +5377,31 @@
         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
         ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name));
     }
+    env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
+        LoaderSettingsLayerConfiguration{}
+            .set_name(layer_name)
+            .set_control("on")
+            .set_path(env.get_shimmed_layer_manifest_path(0))
+            .set_treat_as_implicit_manifest(true)));
+    env.update_loader_settings(env.loader_settings);
     {
-        env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
-            LoaderSettingsLayerConfiguration{}
-                .set_name(layer_name)
-                .set_control("on")
-                .set_path(env.get_shimmed_layer_manifest_path(0))
-                .set_treat_as_implicit_manifest(true)));
-        env.update_loader_settings(env.loader_settings);
-
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
 
         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
         ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name));
     }
+    env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("off");
+    env.update_loader_settings(env.loader_settings);
     {
-        env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("off");
-        env.update_loader_settings(env.loader_settings);
-
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
 
         ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
     }
+    env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("auto");
+    env.update_loader_settings(env.loader_settings);
     {
-        env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("auto");
-        env.update_loader_settings(env.loader_settings);
-
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
 
@@ -5415,7 +5411,7 @@
 
     env.remove_loader_settings();
 
-    // Set the disable_environment variable
+    // Set the layer specific disable_environment variable - layer should never load if this is set
     EnvVarWrapper set_disable_env_var{disable_env_var, "1"};
 
     {
@@ -5439,7 +5435,6 @@
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
 
-        // layer's disable_environment takes priority
         ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
     }
     {
@@ -5486,15 +5481,14 @@
 
 TEST(TestLayers, AllowFilterWithConditionallyImlicitLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* layer_name = "VK_LAYER_test_layer";
     const char* enable_env_var = "TEST_ENABLE_ENV_VAR";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("TEST_DISABLE_ENV_VAR")
-                                                         .set_enable_environment(enable_env_var)),
-                           "test_layer_all.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("TEST_DISABLE_ENV_VAR")
+                                                             .set_enable_environment(enable_env_var)));
 
     EnvVarWrapper allow{"VK_LOADER_LAYERS_ALLOW", layer_name};
 
@@ -5641,26 +5635,24 @@
 
 TEST(TestLayers, AllowFilterWithConditionallyImlicitLayerWithOverrideLayer) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* layer_name = "VK_LAYER_test_layer";
     const char* enable_env_var = "TEST_ENABLE_ENV_VAR";
-    env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name)
-                                                                          .set_api_version(VK_API_VERSION_1_1)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("TEST_DISABLE_ENV_VAR")
-                                                                          .set_enable_environment(enable_env_var)),
-                                            "test_layer_all.json"}
-                               .set_discovery_type(ManifestDiscoveryType::override_folder));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_api_version(VK_API_VERSION_1_1)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("TEST_DISABLE_ENV_VAR")
+                                                         .set_enable_environment(enable_env_var)));
 
-    env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(
-                               ManifestLayer::LayerDescription{}
-                                   .set_name(lunarg_meta_layer_name)
-                                   .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                   .add_component_layer(layer_name)
-                                   .set_disable_environment("DisableMeIfYouCan")
-                                   .add_override_path(env.get_folder(ManifestLocation::override_layer).location().string())),
-                           "meta_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(
+                                   ManifestLayer::LayerDescription{}
+                                       .set_name(lunarg_meta_layer_name)
+                                       .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                       .add_component_layer(layer_name)
+                                       .set_disable_environment("DisableMeIfYouCan")
+                                       .add_override_path(env.get_folder(ManifestLocation::override_layer).location().string())));
 
     EnvVarWrapper allow{"VK_LOADER_LAYERS_ALLOW", layer_name};
 
diff --git a/tests/loader_phys_dev_inst_ext_tests.cpp b/tests/loader_phys_dev_inst_ext_tests.cpp
index 00c1eaf..3a4f43b 100644
--- a/tests/loader_phys_dev_inst_ext_tests.cpp
+++ b/tests/loader_phys_dev_inst_ext_tests.cpp
@@ -59,8 +59,8 @@
 // Test vkGetPhysicalDeviceProperties2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevProps2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -72,8 +72,8 @@
 // Test vkGetPhysicalDeviceProperties2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevProps2KHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -86,10 +86,10 @@
 // Test vkGetPhysicalDeviceProperties2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevProps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_API_VERSION_1_0, 5, 123);
+    FillInRandomDeviceProps(test_physical_device.properties, VK_API_VERSION_1_0, 5, 123);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -122,12 +122,12 @@
 // Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1
 TEST(LoaderInstPhysDevExts, PhysDevProps2Simple) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1;
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_API_VERSION_1_1, 5, 123);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device.properties, VK_API_VERSION_1_1, 5, 123);
     {
         InstWrapper instance(env.vulkan_functions);
         instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -184,11 +184,10 @@
         ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2.properties.pipelineCacheUUID, VK_UUID_SIZE));
         ASSERT_TRUE(log.find("Emulating call in ICD"));
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("modify_api_version_layer")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DisableEnvVar")),
-                           "modify_api_version_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("modify_api_version_layer")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DisableEnvVar")));
     env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1);
     {  // Now do the same as above but with a layer that updates the version to 1.1
         InstWrapper instance(env.vulkan_functions);
@@ -225,11 +224,11 @@
 // extension but the instance supports 1.1 and the extension
 TEST(LoaderInstPhysDevExts, PhysDevProps2KHRInstanceSupports11) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_API_VERSION_1_0, 5, 123);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device.properties, VK_API_VERSION_1_0, 5, 123);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -297,7 +296,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
 
         // ICD 1 should not have 1.1
@@ -312,8 +312,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -414,8 +413,8 @@
 // Test vkGetPhysicalDeviceFeatures2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevFeats2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -427,8 +426,8 @@
 // Test vkGetPhysicalDeviceFeatures2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevFeatsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -441,10 +440,10 @@
 // Test vkGetPhysicalDeviceFeatures2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevFeats2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomFeatures(env.get_test_icd(0).physical_devices.back().features);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomFeatures(test_physical_device.features);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -470,13 +469,13 @@
 // Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1
 TEST(LoaderInstPhysDevExts, PhysDevFeats2Simple) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1;
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    env.get_test_icd(0).physical_devices.back().set_api_version(VK_API_VERSION_1_1);
-    FillInRandomFeatures(env.get_test_icd(0).physical_devices.back().features);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    test_physical_device.set_api_version(VK_API_VERSION_1_1);
+    FillInRandomFeatures(test_physical_device.features);
     {
         InstWrapper instance(env.vulkan_functions);
         instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -519,11 +518,10 @@
 
         ASSERT_TRUE(log.find("Emulating call in ICD"));
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("modify_api_version_layer")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DisableEnvVar")),
-                           "modify_api_version_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("modify_api_version_layer")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DisableEnvVar")));
     env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1);
     {  // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application
         InstWrapper instance(env.vulkan_functions);
@@ -554,11 +552,11 @@
 // extension but the instance supports 1.1 and the extension
 TEST(LoaderInstPhysDevExts, PhysDevFeats2KHRInstanceSupports11) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    FillInRandomFeatures(env.get_test_icd(0).physical_devices.back().features);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    FillInRandomFeatures(test_physical_device.features);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -613,7 +611,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
 
         // ICD 1 should not have 1.1
@@ -628,8 +627,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -677,8 +675,8 @@
 // Test vkGetPhysicalDeviceFormatProperties2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevFormatProps2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -691,8 +689,8 @@
 // Test vkGetPhysicalDeviceFormatProperties2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevFormatPropsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -706,10 +704,10 @@
 // Test vkGetPhysicalDeviceFormatProperties2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevFormatProps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomFormatProperties(env.get_test_icd(0).physical_devices.back().format_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomFormatProperties(test_physical_device.format_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extensions(
@@ -742,13 +740,13 @@
 // Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1
 TEST(LoaderInstPhysDevExts, PhysDevFormatProps2Simple) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1;
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    env.get_test_icd(0).physical_devices.back().set_api_version(VK_API_VERSION_1_1);
-    FillInRandomFormatProperties(env.get_test_icd(0).physical_devices.back().format_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    test_physical_device.set_api_version(VK_API_VERSION_1_1);
+    FillInRandomFormatProperties(test_physical_device.format_properties);
     {
         InstWrapper instance(env.vulkan_functions);
         instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -796,11 +794,10 @@
         ASSERT_EQ(props.optimalTilingFeatures, props2.formatProperties.optimalTilingFeatures);
         ASSERT_TRUE(log.find("Emulating call in ICD"));
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("modify_api_version_layer")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DisableEnvVar")),
-                           "modify_api_version_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("modify_api_version_layer")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DisableEnvVar")));
     env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1);
     {  // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application
         InstWrapper instance(env.vulkan_functions);
@@ -832,11 +829,11 @@
 // extension but the instance supports 1.1 and the extension
 TEST(LoaderInstPhysDevExts, PhysDevFormatProps2KHRInstanceSupports11) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    FillInRandomFormatProperties(env.get_test_icd(0).physical_devices.back().format_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    FillInRandomFormatProperties(test_physical_device.format_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -897,7 +894,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
 
         // ICD 1 should not have 1.1
@@ -912,8 +910,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -965,8 +962,8 @@
 // Test vkGetPhysicalDeviceImageFormatProperties2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -979,8 +976,8 @@
 // Test vkGetPhysicalDeviceImageFormatProperties2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevImageFormatPropsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -994,10 +991,10 @@
 // Test vkGetPhysicalDeviceImageFormatProperties2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomImageFormatData(env.get_test_icd(0).physical_devices.back().image_format_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomImageFormatData(test_physical_device.image_format_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -1043,12 +1040,12 @@
 // Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1
 TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2Simple) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1;
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    FillInRandomImageFormatData(env.get_test_icd(0).physical_devices.back().image_format_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    FillInRandomImageFormatData(test_physical_device.image_format_properties);
     {
         InstWrapper instance(env.vulkan_functions);
         instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -1132,11 +1129,10 @@
         ASSERT_EQ(props.maxResourceSize, props2.imageFormatProperties.maxResourceSize);
         ASSERT_TRUE(log.find("Emulating call in ICD"));
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("modify_api_version_layer")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DisableEnvVar")),
-                           "modify_api_version_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("modify_api_version_layer")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DisableEnvVar")));
     env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1);
     {  // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application
         InstWrapper instance(env.vulkan_functions);
@@ -1187,11 +1183,11 @@
 // and a device under that ICD also support, so everything should work and return properly.
 TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2KHRInstanceSupports11) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    FillInRandomImageFormatData(env.get_test_icd(0).physical_devices.back().image_format_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    FillInRandomImageFormatData(test_physical_device.image_format_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -1274,7 +1270,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
 
         // ICD 1 should not have 1.1
@@ -1289,8 +1286,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -1348,8 +1344,8 @@
 // Test vkGetPhysicalDeviceMemoryProperties2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -1362,8 +1358,8 @@
 // Test vkGetPhysicalDeviceMemoryProperties2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevMemoryPropsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -1391,10 +1387,10 @@
 // Test vkGetPhysicalDeviceMemoryProperties2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomMemoryData(env.get_test_icd(0).physical_devices.back().memory_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomMemoryData(test_physical_device.memory_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -1422,12 +1418,12 @@
 // Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1
 TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2Simple) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1;
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    FillInRandomMemoryData(env.get_test_icd(0).physical_devices.back().memory_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    FillInRandomMemoryData(test_physical_device.memory_properties);
     {
         InstWrapper instance(env.vulkan_functions);
         instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -1471,11 +1467,10 @@
         ASSERT_EQ(props, props2);
         ASSERT_TRUE(log.find("Emulating call in ICD"));
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("modify_api_version_layer")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DisableEnvVar")),
-                           "modify_api_version_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("modify_api_version_layer")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DisableEnvVar")));
     env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1);
     {  // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application
         InstWrapper instance(env.vulkan_functions);
@@ -1506,11 +1501,11 @@
 // extension but the instance supports 1.1 and the extension
 TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2KHRInstanceSupports11) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    FillInRandomMemoryData(env.get_test_icd(0).physical_devices.back().memory_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    FillInRandomMemoryData(test_physical_device.memory_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -1565,7 +1560,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
 
         // ICD 1 should not have 1.1
@@ -1580,8 +1576,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -1620,8 +1615,8 @@
 // Test vkGetPhysicalDeviceQueueFamilyProperties2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -1634,8 +1629,8 @@
 // Test vkGetPhysicalDeviceQueueFamilyProperties2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyPropsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -1664,10 +1659,10 @@
 // Test vkGetPhysicalDeviceQueueFamilyProperties2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    uint32_t num_fam = FillInRandomQueueFamilyData(env.get_test_icd(0).physical_devices.back().queue_family_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    uint32_t num_fam = FillInRandomQueueFamilyData(test_physical_device.queue_family_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -1704,12 +1699,12 @@
 // Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1
 TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2Simple) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1;
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    uint32_t num_fam = FillInRandomQueueFamilyData(env.get_test_icd(0).physical_devices.back().queue_family_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    uint32_t num_fam = FillInRandomQueueFamilyData(test_physical_device.queue_family_properties);
     {
         InstWrapper instance(env.vulkan_functions);
         instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -1773,11 +1768,10 @@
         ASSERT_EQ(props, props2);
         ASSERT_TRUE(log.find("Emulating call in ICD"));
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("modify_api_version_layer")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DisableEnvVar")),
-                           "modify_api_version_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("modify_api_version_layer")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DisableEnvVar")));
     env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1);
     {  // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application
         InstWrapper instance(env.vulkan_functions);
@@ -1818,11 +1812,11 @@
 // extension but the instance supports 1.1 and the extension
 TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2KHRInstanceSupports11) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    uint32_t num_fam = FillInRandomQueueFamilyData(env.get_test_icd(0).physical_devices.back().queue_family_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    uint32_t num_fam = FillInRandomQueueFamilyData(test_physical_device.queue_family_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -1892,7 +1886,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
 
         // ICD 1 should not have 1.1
@@ -1907,8 +1902,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -1955,8 +1949,8 @@
 // Test vkGetPhysicalDeviceSparseImageFormatProperties2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -1969,8 +1963,8 @@
 // Test vkGetPhysicalDeviceSparseImageFormatProperties2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatPropsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -1995,10 +1989,10 @@
 // Test vkGetPhysicalDeviceSparseImageFormatProperties2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomSparseImageFormatData(env.get_test_icd(0).physical_devices.back().sparse_image_format_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomSparseImageFormatData(test_physical_device.sparse_image_format_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -2049,12 +2043,12 @@
 // Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1
 TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2Simple) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1;
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    FillInRandomSparseImageFormatData(env.get_test_icd(0).physical_devices.back().sparse_image_format_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    FillInRandomSparseImageFormatData(test_physical_device.sparse_image_format_properties);
     {
         InstWrapper instance(env.vulkan_functions);
         instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -2146,11 +2140,10 @@
         ASSERT_EQ(props, props2);
         ASSERT_TRUE(log.find("Emulating call in ICD"));
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("modify_api_version_layer")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DisableEnvVar")),
-                           "modify_api_version_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("modify_api_version_layer")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DisableEnvVar")));
     env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1);
     {  // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application
         InstWrapper instance(env.vulkan_functions);
@@ -2205,11 +2198,11 @@
 // supports extension but the instance supports 1.1 and the extension
 TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2KHRInstanceSupports11) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
-    FillInRandomSparseImageFormatData(env.get_test_icd(0).physical_devices.back().sparse_image_format_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+    FillInRandomSparseImageFormatData(test_physical_device.sparse_image_format_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -2294,7 +2287,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
 
         // ICD 1 should not have 1.1
@@ -2309,8 +2303,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -2377,8 +2370,8 @@
 // Test vkGetPhysicalDeviceExternalBufferPropertiesKHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevExtBufPropsKHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -2391,8 +2384,8 @@
 // Test vkGetPhysicalDeviceExternalBufferPropertiesKHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevExtBufPropsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
@@ -2413,10 +2406,10 @@
 // Test vkGetPhysicalDeviceExternalBufferPropertiesKHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevExtBufProps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomExtMemoryData(env.get_test_icd(0).physical_devices.back().external_memory_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomExtMemoryData(test_physical_device.external_memory_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
@@ -2434,7 +2427,7 @@
     VkPhysicalDeviceExternalBufferInfoKHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR};
     VkExternalBufferPropertiesKHR props{VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR};
     GetPhysicalDeviceExternalBufferPropertiesKHR(physical_device, &info, &props);
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().external_memory_properties, props.externalMemoryProperties);
+    ASSERT_EQ(test_physical_device.external_memory_properties, props.externalMemoryProperties);
 }
 
 // Test vkGetPhysicalDeviceExternalBufferProperties where instance supports, an ICD, and a device under that ICD
@@ -2442,12 +2435,12 @@
 // Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1
 TEST(LoaderInstPhysDevExts, PhysDevExtBufProps2Simple) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1;
     env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 0});
-    FillInRandomExtMemoryData(env.get_test_icd(0).physical_devices.back().external_memory_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 0});
+    FillInRandomExtMemoryData(test_physical_device.external_memory_properties);
     {
         InstWrapper instance(env.vulkan_functions);
         instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -2465,7 +2458,7 @@
         VkPhysicalDeviceExternalBufferInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO};
         VkExternalBufferProperties props{VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES};
         GetPhysicalDeviceExternalBufferProperties(physical_device, &info, &props);
-        ASSERT_EQ(env.get_test_icd(0).physical_devices.back().external_memory_properties, props.externalMemoryProperties);
+        ASSERT_EQ(test_physical_device.external_memory_properties, props.externalMemoryProperties);
     }
     {  // Now do the same logic but the application didn't enable 1.0 or the extension so they get the emulated call
         InstWrapper instance(env.vulkan_functions);
@@ -2490,11 +2483,10 @@
         ASSERT_EQ(VkExternalMemoryProperties{}, props.externalMemoryProperties);
         ASSERT_TRUE(log.find("Emulating call in ICD"));
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("modify_api_version_layer")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DisableEnvVar")),
-                           "modify_api_version_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("modify_api_version_layer")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DisableEnvVar")));
     env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1);
     {  // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application
         InstWrapper instance(env.vulkan_functions);
@@ -2515,7 +2507,7 @@
         VkPhysicalDeviceExternalBufferInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO};
         VkExternalBufferProperties props{VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES};
         GetPhysicalDeviceExternalBufferProperties(physical_device, &info, &props);
-        ASSERT_EQ(env.get_test_icd(0).physical_devices.back().external_memory_properties, props.externalMemoryProperties);
+        ASSERT_EQ(test_physical_device.external_memory_properties, props.externalMemoryProperties);
         ASSERT_FALSE(log.find("Emulating call in ICD"));
     }
 }
@@ -2540,7 +2532,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
 
         // ICD 1 should not have 1.1
@@ -2555,8 +2548,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -2590,8 +2582,7 @@
         for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
             auto& cur_icd = env.get_test_icd(icd);
             bool found = false;
-            for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) {
-                auto& cur_dev = cur_icd.physical_devices[pd];
+            for (auto const& [physical_device_handle, cur_dev] : cur_icd.physical_devices) {
                 // Find the ICD device matching the physical device we're looking at info for so we can compare the
                 // physical devices info with the returned info.
                 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID &&
@@ -2626,8 +2617,8 @@
 // Test vkGetPhysicalDeviceExternalSemaphorePropertiesKHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevExtSemPropsKHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -2640,8 +2631,8 @@
 // Test vkGetPhysicalDeviceExternalSemaphorePropertiesKHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevExtSemPropsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
@@ -2664,10 +2655,10 @@
 // Test vkGetPhysicalDeviceExternalSemaphorePropertiesKHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevExtSemProps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomExtSemData(env.get_test_icd(0).physical_devices.back().external_semaphore_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomExtSemData(test_physical_device.external_semaphore_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
@@ -2685,7 +2676,7 @@
     VkPhysicalDeviceExternalSemaphoreInfoKHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR};
     VkExternalSemaphorePropertiesKHR props{VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR};
     GetPhysicalDeviceExternalSemaphorePropertiesKHR(physical_device, &info, &props);
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().external_semaphore_properties, props);
+    ASSERT_EQ(test_physical_device.external_semaphore_properties, props);
 }
 
 // Test vkGetPhysicalDeviceExternalSemaphoreProperties where instance supports, an ICD, and a device under that ICD
@@ -2693,12 +2684,12 @@
 // Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1
 TEST(LoaderInstPhysDevExts, PhysDevExtSemProps2Simple) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1;
     env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, 0});
-    FillInRandomExtSemData(env.get_test_icd(0).physical_devices.back().external_semaphore_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, 0});
+    FillInRandomExtSemData(test_physical_device.external_semaphore_properties);
     {
         InstWrapper instance(env.vulkan_functions);
         instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -2716,7 +2707,7 @@
         VkPhysicalDeviceExternalSemaphoreInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO};
         VkExternalSemaphoreProperties props{VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES};
         GetPhysicalDeviceExternalSemaphoreProperties(physical_device, &info, &props);
-        ASSERT_EQ(env.get_test_icd(0).physical_devices.back().external_semaphore_properties, props);
+        ASSERT_EQ(test_physical_device.external_semaphore_properties, props);
     }
     {  // Now do the same logic but the application didn't enable 1.0 or the extension so they get the emulated call
         InstWrapper instance(env.vulkan_functions);
@@ -2740,11 +2731,10 @@
         ASSERT_EQ(VkExternalSemaphoreProperties{}, props);
         ASSERT_TRUE(log.find("Emulating call in ICD"));
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("modify_api_version_layer")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DisableEnvVar")),
-                           "modify_api_version_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("modify_api_version_layer")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DisableEnvVar")));
     env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1);
     {  // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application
         InstWrapper instance(env.vulkan_functions);
@@ -2764,7 +2754,7 @@
         VkPhysicalDeviceExternalSemaphoreInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO};
         VkExternalSemaphoreProperties props{VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES};
         GetPhysicalDeviceExternalSemaphoreProperties(physical_device, &info, &props);
-        ASSERT_EQ(env.get_test_icd(0).physical_devices.back().external_semaphore_properties, props);
+        ASSERT_EQ(test_physical_device.external_semaphore_properties, props);
         ASSERT_FALSE(log.find("Emulating call in ICD"));
     }
 }
@@ -2789,7 +2779,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
 
         // ICD 1 should not have 1.1
@@ -2804,8 +2795,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -2839,8 +2829,7 @@
         for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
             auto& cur_icd = env.get_test_icd(icd);
             bool found = false;
-            for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) {
-                auto& cur_dev = cur_icd.physical_devices[pd];
+            for (auto const& [physical_device_handle, cur_dev] : cur_icd.physical_devices) {
                 // Find the ICD device matching the physical device we're looking at info for so we can compare the
                 // physical devices info with the returned info.
                 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID &&
@@ -2874,8 +2863,8 @@
 // Test vkGetPhysicalDeviceExternalFencePropertiesKHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevExtFencePropsKHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -2888,8 +2877,8 @@
 // Test vkGetPhysicalDeviceExternalFencePropertiesKHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevExtFencePropsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME);
@@ -2912,10 +2901,10 @@
 // Test vkGetPhysicalDeviceExternalFencePropertiesKHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevExtFenceProps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomExtFenceData(env.get_test_icd(0).physical_devices.back().external_fence_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomExtFenceData(test_physical_device.external_fence_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME);
@@ -2933,7 +2922,7 @@
     VkPhysicalDeviceExternalFenceInfoKHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR};
     VkExternalFencePropertiesKHR props{VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR};
     GetPhysicalDeviceExternalFencePropertiesKHR(physical_device, &info, &props);
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().external_fence_properties, props);
+    ASSERT_EQ(test_physical_device.external_fence_properties, props);
 }
 
 // Test vkGetPhysicalDeviceExternalFenceProperties where instance supports, an ICD, and a device under that ICD
@@ -2941,12 +2930,12 @@
 // Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1
 TEST(LoaderInstPhysDevExts, PhysDevExtFenceProps2Simple) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1;
     env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, 0});
-    FillInRandomExtFenceData(env.get_test_icd(0).physical_devices.back().external_fence_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.extensions.push_back({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, 0});
+    FillInRandomExtFenceData(test_physical_device.external_fence_properties);
     {
         InstWrapper instance(env.vulkan_functions);
         instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -2964,7 +2953,7 @@
         VkPhysicalDeviceExternalFenceInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO};
         VkExternalFenceProperties props{VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES};
         GetPhysicalDeviceExternalFenceProperties(physical_device, &info, &props);
-        ASSERT_EQ(env.get_test_icd(0).physical_devices.back().external_fence_properties, props);
+        ASSERT_EQ(test_physical_device.external_fence_properties, props);
     }
     {  // Now do the same logic but the application didn't enable 1.0 or the extension so they get the emulated call
         InstWrapper instance(env.vulkan_functions);
@@ -2989,11 +2978,10 @@
         ASSERT_EQ(VkExternalFenceProperties{}, props);
         ASSERT_TRUE(log.find("Emulating call in ICD"));
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("modify_api_version_layer")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DisableEnvVar")),
-                           "modify_api_version_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("modify_api_version_layer")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DisableEnvVar")));
     env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1);
     {  // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application
         InstWrapper instance(env.vulkan_functions);
@@ -3013,7 +3001,7 @@
         VkPhysicalDeviceExternalFenceInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO};
         VkExternalFenceProperties props{VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES};
         GetPhysicalDeviceExternalFenceProperties(physical_device, &info, &props);
-        ASSERT_EQ(env.get_test_icd(0).physical_devices.back().external_fence_properties, props);
+        ASSERT_EQ(test_physical_device.external_fence_properties, props);
         ASSERT_FALSE(log.find("Emulating call in ICD"));
     }
 }
@@ -3037,7 +3025,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
 
         // ICD 1 should not have 1.1
@@ -3052,8 +3041,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -3087,8 +3075,7 @@
         for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
             auto& cur_icd = env.get_test_icd(icd);
             bool found = false;
-            for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) {
-                auto& cur_dev = cur_icd.physical_devices[pd];
+            for (auto const& [physical_device_handle, cur_dev] : cur_icd.physical_devices) {
                 // Find the ICD device matching the physical device we're looking at info for so we can compare the
                 // physical devices info with the returned info.
                 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID &&
@@ -3122,8 +3109,8 @@
 // Test vkGetPhysicalDeviceSurfaceCapabilities2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -3136,8 +3123,8 @@
 // Test vkGetPhysicalDeviceSurfaceCapabilities2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
@@ -3168,16 +3155,16 @@
 // Test vkGetPhysicalDeviceSurfaceCapabilities2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
     Extension second_ext{VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME};
     Extension third_ext{VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME};
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.add_instance_extensions({first_ext, second_ext, third_ext});
-    cur_icd.physical_devices.push_back({});
+    auto& test_physical_device = cur_icd.add_and_get_physical_device({});
     cur_icd.min_icd_interface_version = 3;
     cur_icd.enable_icd_wsi = true;
-    FillInRandomSurfaceCapsData(env.get_test_icd(0).physical_devices.back().surface_capabilities);
+    FillInRandomSurfaceCapsData(test_physical_device.surface_capabilities);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extensions(
@@ -3238,7 +3225,8 @@
     Extension third_ext{VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME};
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.min_icd_interface_version = 3;
@@ -3257,8 +3245,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
             cur_dev.extensions.push_back({VK_KHR_SURFACE_EXTENSION_NAME, 0});
             cur_dev.extensions.push_back({VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, 0});
 
@@ -3315,8 +3302,8 @@
 // Test vkGetPhysicalDeviceSurfaceFormats2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -3329,8 +3316,8 @@
 // Test vkGetPhysicalDeviceSurfaceFormats2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
@@ -3353,16 +3340,16 @@
 // Test vkGetPhysicalDeviceSurfaceFormats2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
     Extension second_ext{VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME};
     Extension third_ext{VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME};
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.add_instance_extensions({first_ext, second_ext, third_ext});
-    cur_icd.physical_devices.push_back({});
+    auto& test_physical_device = cur_icd.add_and_get_physical_device({});
     cur_icd.min_icd_interface_version = 3;
     cur_icd.enable_icd_wsi = true;
-    FillInRandomSurfaceFormatsData(env.get_test_icd(0).physical_devices.back().surface_formats);
+    FillInRandomSurfaceFormatsData(test_physical_device.surface_formats);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extensions(
@@ -3392,10 +3379,10 @@
     std::vector<VkSurfaceFormatKHR> formats{};
     uint32_t count_1 = 0;
     ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &count_1, nullptr));
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().surface_formats.size(), count_1);
+    ASSERT_EQ(test_physical_device.surface_formats.size(), count_1);
     formats.resize(count_1);
     ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &count_1, formats.data()));
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().surface_formats.size(), count_1);
+    ASSERT_EQ(test_physical_device.surface_formats.size(), count_1);
 
     VkPhysicalDeviceSurfaceInfo2KHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr, surface};
     std::vector<VkSurfaceFormat2KHR> formats2{};
@@ -3431,7 +3418,8 @@
     Extension third_ext{VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME};
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.enable_icd_wsi = true;
@@ -3450,8 +3438,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
             cur_dev.extensions.push_back({VK_KHR_SURFACE_EXTENSION_NAME, 0});
             cur_dev.extensions.push_back({VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, 0});
 
@@ -3522,8 +3509,8 @@
 // Test vkGetPhysicalDeviceDisplayPropertiesKHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -3536,8 +3523,8 @@
 // Test vkGetPhysicalDeviceDisplayPropertiesKHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME);
@@ -3572,10 +3559,10 @@
 // Test vGetPhysicalDeviceDisplayPropertiesKHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomDisplayPropData(env.get_test_icd(0).physical_devices.back().display_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomDisplayPropData(test_physical_device.display_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
@@ -3593,12 +3580,12 @@
     std::vector<VkDisplayPropertiesKHR> props{};
     uint32_t prop_count = 0;
     ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPropertiesKHR(physical_device, &prop_count, nullptr));
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_properties.size(), prop_count);
+    ASSERT_EQ(test_physical_device.display_properties.size(), prop_count);
     props.resize(prop_count);
     ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPropertiesKHR(physical_device, &prop_count, props.data()));
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_properties.size(), prop_count);
+    ASSERT_EQ(test_physical_device.display_properties.size(), prop_count);
 
-    ASSERT_EQ(props, env.get_test_icd(0).physical_devices.back().display_properties);
+    ASSERT_EQ(props, test_physical_device.display_properties);
 }
 
 // Test vkGetPhysicalDeviceDisplayPropertiesKHR where instance supports it with some ICDs that both support
@@ -3621,7 +3608,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
 
@@ -3637,8 +3625,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -3672,8 +3659,7 @@
         for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
             auto& cur_icd = env.get_test_icd(icd);
             bool found = false;
-            for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) {
-                auto& cur_dev = cur_icd.physical_devices[pd];
+            for (auto const& [physical_device_handle, cur_dev] : cur_icd.physical_devices) {
                 // Find the ICD device matching the physical device we're looking at info for so we can compare the
                 // physical devices info with the returned info.
                 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID &&
@@ -3710,8 +3696,8 @@
 // Test vkGetPhysicalDeviceDisplayPlanePropertiesKHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -3724,8 +3710,8 @@
 // Test vkGetPhysicalDeviceDisplayPlanePropertiesKHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME);
@@ -3748,10 +3734,10 @@
 // Test vGetPhysicalDeviceDisplayPlanePropertiesKHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomDisplayPlanePropData(env.get_test_icd(0).physical_devices.back().display_plane_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomDisplayPlanePropData(test_physical_device.display_plane_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
@@ -3769,12 +3755,12 @@
     std::vector<VkDisplayPlanePropertiesKHR> props{};
     uint32_t prop_count = 0;
     ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlanePropertiesKHR(physical_device, &prop_count, nullptr));
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_plane_properties.size(), prop_count);
+    ASSERT_EQ(test_physical_device.display_plane_properties.size(), prop_count);
     props.resize(prop_count);
     ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlanePropertiesKHR(physical_device, &prop_count, props.data()));
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_plane_properties.size(), prop_count);
+    ASSERT_EQ(test_physical_device.display_plane_properties.size(), prop_count);
 
-    ASSERT_EQ(props, env.get_test_icd(0).physical_devices.back().display_plane_properties);
+    ASSERT_EQ(props, test_physical_device.display_plane_properties);
 }
 
 // Test vkGetPhysicalDeviceDisplayPlanePropertiesKHR where instance supports it with some ICDs that both support
@@ -3797,7 +3783,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
 
@@ -3813,8 +3800,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -3848,8 +3834,7 @@
         for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
             auto& cur_icd = env.get_test_icd(icd);
             bool found = false;
-            for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) {
-                auto& cur_dev = cur_icd.physical_devices[pd];
+            for (auto const& [physical_device_handle, cur_dev] : cur_icd.physical_devices) {
                 // Find the ICD device matching the physical device we're looking at info for so we can compare the
                 // physical devices info with the returned info.
                 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID &&
@@ -3886,8 +3871,8 @@
 // Test vkGetDisplayPlaneSupportedDisplaysKHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -3900,8 +3885,8 @@
 // Test vkGetDisplayPlaneSupportedDisplaysKHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME);
@@ -3923,10 +3908,10 @@
 // Test vGetDisplayPlaneSupportedDisplaysKHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    GenerateRandomDisplays(env.get_test_icd(0).physical_devices.back().displays);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    GenerateRandomDisplays(test_physical_device.displays);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
@@ -3944,12 +3929,12 @@
     std::vector<VkDisplayKHR> disps{};
     uint32_t disp_count = 0;
     ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneSupportedDisplaysKHR(physical_device, 0, &disp_count, nullptr));
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().displays.size(), disp_count);
+    ASSERT_EQ(test_physical_device.displays.size(), disp_count);
     disps.resize(disp_count);
     ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneSupportedDisplaysKHR(physical_device, 0, &disp_count, disps.data()));
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().displays.size(), disp_count);
+    ASSERT_EQ(test_physical_device.displays.size(), disp_count);
 
-    ASSERT_EQ(disps, env.get_test_icd(0).physical_devices.back().displays);
+    ASSERT_EQ(disps, test_physical_device.displays);
 }
 
 // Test vkGetDisplayPlaneSupportedDisplaysKHR where instance supports it with some ICDs that both support
@@ -3972,7 +3957,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
 
@@ -3988,8 +3974,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -4023,8 +4008,7 @@
         for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
             auto& cur_icd = env.get_test_icd(icd);
             bool found = false;
-            for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) {
-                auto& cur_dev = cur_icd.physical_devices[pd];
+            for (auto const& [physical_device_handle, cur_dev] : cur_icd.physical_devices) {
                 // Find the ICD device matching the physical device we're looking at info for so we can compare the
                 // physical devices info with the returned info.
                 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID &&
@@ -4061,8 +4045,8 @@
 // Test vkGetDisplayModePropertiesKHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, GetDispModePropsKHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -4074,8 +4058,8 @@
 // Test vkGetDisplayModePropertiesKHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, GetDispModePropsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME);
@@ -4099,10 +4083,10 @@
 // Test vGetDisplayModePropertiesKHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, GetDispModePropsKHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    GenerateRandomDisplayModeProps(env.get_test_icd(0).physical_devices.back().display_mode_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    GenerateRandomDisplayModeProps(test_physical_device.display_mode_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
@@ -4119,12 +4103,12 @@
     std::vector<VkDisplayModePropertiesKHR> props{};
     uint32_t props_count = 0;
     ASSERT_EQ(VK_SUCCESS, GetDisplayModePropertiesKHR(physical_device, VK_NULL_HANDLE, &props_count, nullptr));
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_mode_properties.size(), props_count);
+    ASSERT_EQ(test_physical_device.display_mode_properties.size(), props_count);
     props.resize(props_count);
     ASSERT_EQ(VK_SUCCESS, GetDisplayModePropertiesKHR(physical_device, VK_NULL_HANDLE, &props_count, props.data()));
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_mode_properties.size(), props_count);
+    ASSERT_EQ(test_physical_device.display_mode_properties.size(), props_count);
 
-    ASSERT_EQ(props, env.get_test_icd(0).physical_devices.back().display_mode_properties);
+    ASSERT_EQ(props, test_physical_device.display_mode_properties);
 }
 
 // Test vkGetDisplayModePropertiesKHR where instance supports it with some ICDs that both support
@@ -4147,7 +4131,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
 
@@ -4163,8 +4148,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -4197,8 +4181,7 @@
         for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
             auto& cur_icd = env.get_test_icd(icd);
             bool found = false;
-            for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) {
-                auto& cur_dev = cur_icd.physical_devices[pd];
+            for (auto const& [physical_device_handle, cur_dev] : cur_icd.physical_devices) {
                 // Find the ICD device matching the physical device we're looking at info for so we can compare the
                 // physical devices info with the returned info.
                 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID &&
@@ -4236,8 +4219,8 @@
 // Test vkCreateDisplayModeKHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, GetDispModesKHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -4249,8 +4232,8 @@
 // Test vkCreateDisplayModeKHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, GetDispModesKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME);
@@ -4263,10 +4246,10 @@
 // Test vkCreateDisplayModeKHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, GetDispModesKHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.back().display_mode = CreateRandomDisplayMode();
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device.display_mode = CreateRandomDisplayMode();
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
@@ -4283,7 +4266,7 @@
     VkDisplayModeKHR mode{};
     VkDisplayModeCreateInfoKHR create_info{VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR};
     ASSERT_EQ(VK_SUCCESS, CreateDisplayModeKHR(physical_device, VK_NULL_HANDLE, &create_info, nullptr, &mode));
-    ASSERT_EQ(mode, env.get_test_icd(0).physical_devices.back().display_mode);
+    ASSERT_EQ(mode, test_physical_device.display_mode);
 }
 
 // Test vkCreateDisplayModeKHR where instance supports it with some ICDs that both support
@@ -4306,7 +4289,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
 
@@ -4322,8 +4306,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -4356,8 +4339,7 @@
         for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
             auto& cur_icd = env.get_test_icd(icd);
             bool found = false;
-            for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) {
-                auto& cur_dev = cur_icd.physical_devices[pd];
+            for (auto const& [physical_device_handle, cur_dev] : cur_icd.physical_devices) {
                 // Find the ICD device matching the physical device we're looking at info for so we can compare the
                 // physical devices info with the returned info.
                 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID &&
@@ -4389,8 +4371,8 @@
 // Test vkGetDisplayPlaneCapabilitiesKHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -4402,8 +4384,8 @@
 // Test vkGetDisplayPlaneCapabilitiesKHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME);
@@ -4437,10 +4419,10 @@
 // Test vkGetDisplayPlaneCapabilitiesKHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({});
-    GenerateRandomDisplayPlaneCaps(env.get_test_icd(0).physical_devices.back().display_plane_capabilities);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    GenerateRandomDisplayPlaneCaps(test_physical_device.display_plane_capabilities);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
@@ -4456,7 +4438,7 @@
 
     VkDisplayPlaneCapabilitiesKHR caps{};
     ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilitiesKHR(physical_device, 0, 0, &caps));
-    ASSERT_EQ(caps, env.get_test_icd(0).physical_devices.back().display_plane_capabilities);
+    ASSERT_EQ(caps, test_physical_device.display_plane_capabilities);
 }
 
 // Test vkGetDisplayPlaneCapabilitiesKHR where instance supports it with some ICDs that both support
@@ -4479,7 +4461,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
 
@@ -4495,8 +4478,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
             if ((icd == 0 && dev == 1) || icd == 3) {
@@ -4529,8 +4511,7 @@
         for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
             auto& cur_icd = env.get_test_icd(icd);
             bool found = false;
-            for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) {
-                auto& cur_dev = cur_icd.physical_devices[pd];
+            for (auto const& [physical_device_handle, cur_dev] : cur_icd.physical_devices) {
                 // Find the ICD device matching the physical device we're looking at info for so we can compare the
                 // physical devices info with the returned info.
                 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID &&
@@ -4562,8 +4543,8 @@
 // Test vkGetPhysicalDeviceDisplayProperties2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -4576,8 +4557,8 @@
 // Test vkGetPhysicalDeviceDisplayProperties2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME);
@@ -4591,12 +4572,12 @@
 // Test vGetPhysicalDeviceDisplayProperties2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME};
     Extension second_ext{VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME};
     env.get_test_icd(0).add_instance_extensions({first_ext, second_ext});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomDisplayPropData(env.get_test_icd(0).physical_devices.back().display_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomDisplayPropData(test_physical_device.display_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME});
@@ -4651,7 +4632,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
@@ -4668,8 +4650,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
             cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
@@ -4722,8 +4703,8 @@
 // Test vkGetPhysicalDeviceDisplayPlaneProperties2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -4736,8 +4717,8 @@
 // Test vkGetPhysicalDeviceDisplayPlaneProperties2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME);
@@ -4751,12 +4732,12 @@
 // Test vGetPhysicalDeviceDisplayPlaneProperties2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME};
     Extension second_ext{VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME};
     env.get_test_icd(0).add_instance_extensions({first_ext, second_ext});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomDisplayPlanePropData(env.get_test_icd(0).physical_devices.back().display_plane_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomDisplayPlanePropData(test_physical_device.display_plane_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME});
@@ -4810,7 +4791,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
@@ -4827,8 +4809,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
             cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
@@ -4880,8 +4861,8 @@
 // Test vkGetDisplayModeProperties2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -4893,8 +4874,8 @@
 // Test vkGetDisplayModeProperties2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME);
@@ -4907,12 +4888,12 @@
 // Test vGetDisplayModeProperties2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME};
     Extension second_ext{VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME};
     env.get_test_icd(0).add_instance_extensions({first_ext, second_ext});
-    env.get_test_icd(0).physical_devices.push_back({});
-    GenerateRandomDisplayModeProps(env.get_test_icd(0).physical_devices.back().display_mode_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    GenerateRandomDisplayModeProps(test_physical_device.display_mode_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME});
@@ -4964,7 +4945,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
@@ -4981,8 +4963,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
             cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
@@ -5032,8 +5013,8 @@
 // Test vkGetDisplayPlaneCapabilities2KHR where nothing supports it.
 TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -5045,8 +5026,8 @@
 // Test vkGetDisplayPlaneCapabilities2KHR where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME);
@@ -5059,12 +5040,12 @@
 // Test vkGetDisplayPlaneCapabilities2KHR where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME};
     Extension second_ext{VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME};
     env.get_test_icd(0).add_instance_extensions({first_ext, second_ext});
-    env.get_test_icd(0).physical_devices.push_back({});
-    FillInRandomDisplayPropData(env.get_test_icd(0).physical_devices.back().display_properties);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    FillInRandomDisplayPropData(test_physical_device.display_properties);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME});
@@ -5108,7 +5089,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
@@ -5125,8 +5107,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
             cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
@@ -5172,8 +5153,8 @@
 // Test vkAcquireDrmDisplayEXT where nothing supports it.
 TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -5185,8 +5166,8 @@
 // Test vkAcquireDrmDisplayEXT where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME);
@@ -5199,12 +5180,12 @@
 // Test vkAcquireDrmDisplayEXT where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME};
     Extension second_ext{VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME};
     env.get_test_icd(0).add_instance_extensions({first_ext, second_ext});
-    env.get_test_icd(0).physical_devices.push_back({});
-    GenerateRandomDisplays(env.get_test_icd(0).physical_devices.back().displays);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    GenerateRandomDisplays(test_physical_device.displays);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME});
@@ -5242,7 +5223,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
@@ -5259,8 +5241,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
             cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
@@ -5294,8 +5275,7 @@
         for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
             auto& cur_icd = env.get_test_icd(icd);
             bool found = false;
-            for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) {
-                auto& cur_dev = cur_icd.physical_devices[pd];
+            for (auto const& [physical_device_handle, cur_dev] : cur_icd.physical_devices) {
                 // Find the ICD device matching the physical device we're looking at info for so we can compare the
                 // physical devices info with the returned info.
                 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID &&
@@ -5324,8 +5304,8 @@
 // Test vkGetDrmDisplayEXT where nothing supports it.
 TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTNoSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -5337,8 +5317,8 @@
 // Test vkGetDrmDisplayEXT where instance supports it, but nothing else.
 TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(0).physical_devices.push_back({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.get_test_icd(0).add_physical_device({});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME);
@@ -5351,12 +5331,12 @@
 // Test vkGetDrmDisplayEXT where instance and ICD supports it, but device does not support it.
 TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTInstanceAndICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME};
     Extension second_ext{VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME};
     env.get_test_icd(0).add_instance_extensions({first_ext, second_ext});
-    env.get_test_icd(0).physical_devices.push_back({});
-    GenerateRandomDisplays(env.get_test_icd(0).physical_devices.back().displays);
+    auto& test_physical_device = env.get_test_icd(0).add_and_get_physical_device({});
+    GenerateRandomDisplays(test_physical_device.displays);
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME});
@@ -5372,7 +5352,7 @@
 
     VkDisplayKHR display = VK_NULL_HANDLE;
     ASSERT_EQ(VK_SUCCESS, GetDrmDisplayEXT(physical_device, 0, 0, &display));
-    ASSERT_EQ(display, env.get_test_icd(0).physical_devices.back().displays[0]);
+    ASSERT_EQ(display, test_physical_device.displays[0]);
 }
 
 // Test vkGetDrmDisplayEXT where instance supports it with some ICDs that both support
@@ -5395,7 +5375,8 @@
     const uint32_t max_phys_devs = 7;
 
     for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {},
+                    ManifestICD{}.set_api_version(icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0));
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME});
@@ -5412,8 +5393,7 @@
 
         for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) {
             uint32_t device_version = VK_API_VERSION_1_0;
-            cur_icd.physical_devices.push_back({});
-            auto& cur_dev = cur_icd.physical_devices.back();
+            auto& cur_dev = cur_icd.add_and_get_physical_device({});
             cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0});
 
             // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1
@@ -5447,8 +5427,7 @@
         for (uint32_t icd = 0; icd < max_icd_count; ++icd) {
             auto& cur_icd = env.get_test_icd(icd);
             bool found = false;
-            for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) {
-                auto& cur_dev = cur_icd.physical_devices[pd];
+            for (auto const& [physical_device_handle, cur_dev] : cur_icd.physical_devices) {
                 // Find the ICD device matching the physical device we're looking at info for so we can compare the
                 // physical devices info with the returned info.
                 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID &&
@@ -5479,20 +5458,20 @@
     FrameworkEnvironment env{};
 
     // Add 3 drivers each of which supports a different instance extension
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({"pd0"});
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 0});
+    env.get_test_icd(0).add_and_get_physical_device({"pd0"}).extensions.push_back(
+        {VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     env.get_test_icd(1).add_instance_extension({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME});
-    env.get_test_icd(1).physical_devices.push_back({"pd1"});
-    env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, 0});
+    env.get_test_icd(1).add_and_get_physical_device({"pd1"}).extensions.push_back(
+        {VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     env.get_test_icd(2).add_instance_extension({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME});
-    env.get_test_icd(2).physical_devices.push_back({"pd2"});
-    env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, 0});
+    env.get_test_icd(2).add_and_get_physical_device({"pd2"}).extensions.push_back(
+        {VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, 0});
 
     DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT};
     InstWrapper inst{env.vulkan_functions};
@@ -5534,17 +5513,14 @@
     FrameworkEnvironment env{};
 
     // Add 3 drivers each of which supports a different physical device extension
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
-    env.get_test_icd(0).physical_devices.push_back("pd0");
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME, 0});
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
+    env.get_test_icd(0).add_and_get_physical_device("pd0").extensions.push_back({VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
-    env.get_test_icd(1).physical_devices.push_back("pd1");
-    env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, 0});
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
+    env.get_test_icd(1).add_and_get_physical_device("pd1").extensions.push_back({VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
-    env.get_test_icd(2).physical_devices.push_back("pd2");
-    env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, 0});
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
+    env.get_test_icd(2).add_and_get_physical_device("pd2").extensions.push_back({VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, 0});
 
     DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT};
     InstWrapper inst{env.vulkan_functions};
diff --git a/tests/loader_regression_tests.cpp b/tests/loader_regression_tests.cpp
index 4c6ee6c..0b09cfe 100644
--- a/tests/loader_regression_tests.cpp
+++ b/tests/loader_regression_tests.cpp
@@ -27,6 +27,7 @@
  * Author: Charles Giessen <charles@lunarg.com>
  */
 
+#include "manifest_builders.h"
 #include "test_environment.h"
 
 // Test case origin
@@ -38,7 +39,7 @@
 
 TEST(CreateInstance, BasicRun) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).set_min_icd_interface_version(5);
+    env.add_icd(TEST_ICD_PATH_VERSION_2).set_min_icd_interface_version(5);
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -47,7 +48,7 @@
 // LX435
 TEST(CreateInstance, ConstInstanceInfo) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     VkInstance inst = VK_NULL_HANDLE;
     VkInstanceCreateInfo const info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr};
     ASSERT_EQ(env.vulkan_functions.vkCreateInstance(&info, VK_NULL_HANDLE, &inst), VK_SUCCESS);
@@ -58,21 +59,21 @@
 // VUID-vkDestroyInstance-instance-parameter, VUID-vkDestroyInstance-pAllocator-parameter
 TEST(CreateInstance, DestroyInstanceNullHandle) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     env.vulkan_functions.vkDestroyInstance(VK_NULL_HANDLE, nullptr);
 }
 
 // VUID-vkDestroyDevice-device-parameter, VUID-vkDestroyDevice-pAllocator-parameter
 TEST(CreateInstance, DestroyDeviceNullHandle) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     env.vulkan_functions.vkDestroyDevice(VK_NULL_HANDLE, nullptr);
 }
 
 // VUID-vkCreateInstance-ppEnabledExtensionNames-01388
 TEST(CreateInstance, ExtensionNotPresent) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     {
         InstWrapper inst{env.vulkan_functions};
         inst.create_info.add_extension("VK_EXT_validation_features");  // test icd won't report this as supported
@@ -87,7 +88,7 @@
 
 TEST(CreateInstance, LayerNotPresent) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.add_layer("VK_NON_EXISTANT_LAYER");
     inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
@@ -95,13 +96,12 @@
 
 TEST(CreateInstance, LayerPresent) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2}).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* layer_name = "TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.add_layer(layer_name);
@@ -110,14 +110,14 @@
 
 TEST(CreateInstance, RelativePaths) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2}.set_library_path_type(LibraryPathType::relative)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_library_path_type(LibraryPathType::relative))
+        .add_physical_device({});
 
     const char* layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        TestLayerDetails{ManifestLayer{}.add_layer(
-                             ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                         "test_layer.json"}
-            .set_library_path_type(LibraryPathType::relative));
+        ManifestOptions{}.set_library_path_type(LibraryPathType::relative),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.add_layer(layer_name);
@@ -129,7 +129,7 @@
 
 TEST(CreateInstance, ApiVersionBelow1_0) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).set_min_icd_interface_version(5);
+    env.add_icd(TEST_ICD_PATH_VERSION_2).set_min_icd_interface_version(5);
 
     DebugUtilsLogger debug_log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT};
     InstWrapper inst{env.vulkan_functions};
@@ -144,7 +144,7 @@
 
 TEST(CreateInstance, ConsecutiveCreate) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     for (uint32_t i = 0; i < 100; i++) {
         InstWrapper inst{env.vulkan_functions};
@@ -154,7 +154,7 @@
 
 TEST(CreateInstance, ConsecutiveCreateWithoutDestruction) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     std::vector<InstWrapper> instances;
     for (uint32_t i = 0; i < 100; i++) {
@@ -171,20 +171,18 @@
 
 TEST(EnumerateInstanceLayerProperties, UsageChecks) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     const char* layer_name_1 = "TestLayer1";
-    const char* layer_name_2 = "TestLayer1";
+    const char* layer_name_2 = "TestLayer2";
 
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer_1.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer_2.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     {  // OnePass
         VkLayerProperties layer_props[2] = {};
@@ -216,7 +214,7 @@
 
 TEST(EnumerateInstanceExtensionProperties, UsageChecks) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     Extension first_ext{"VK_EXT_validation_features"};  // known instance extensions
     Extension second_ext{"VK_EXT_headless_surface"};
@@ -250,7 +248,7 @@
 
 TEST(EnumerateInstanceExtensionProperties, PropertyCountLessThanAvailable) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     uint32_t extension_count = 0;
     std::array<VkExtensionProperties, 4> extensions;
@@ -280,7 +278,7 @@
 
 TEST(EnumerateInstanceExtensionProperties, FilterUnkownInstanceExtensions) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     Extension first_ext{"FirstTestExtension"};  // unknown instance extensions
     Extension second_ext{"SecondTestExtension"};
@@ -308,13 +306,12 @@
 
 TEST(EnumerateDeviceLayerProperties, LayersMatch) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     const char* layer_name = "TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.add_layer(layer_name);
@@ -335,11 +332,11 @@
 
 TEST(EnumerateDeviceExtensionProperties, DeviceExtensionEnumerated) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    auto& test_physical_device = env.add_icd(TEST_ICD_PATH_VERSION_2).add_and_get_physical_device("physical_device_0");
 
     std::array<Extension, 2> device_extensions = {Extension{"MyExtension0", 4}, Extension{"MyExtension1", 7}};
     for (auto& ext : device_extensions) {
-        driver.physical_devices.front().extensions.push_back(ext);
+        test_physical_device.extensions.push_back(ext);
     }
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -362,11 +359,11 @@
 
 TEST(EnumerateDeviceExtensionProperties, PropertyCountLessThanAvailable) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    auto& test_physical_device = env.add_icd(TEST_ICD_PATH_VERSION_2).add_and_get_physical_device("physical_device_0");
 
     std::array<Extension, 2> device_extensions = {Extension{"MyExtension0", 4}, Extension{"MyExtension1", 7}};
     for (auto& ext : device_extensions) {
-        driver.physical_devices.front().extensions.push_back(ext);
+        test_physical_device.extensions.push_back(ext);
     }
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -390,7 +387,7 @@
 
 TEST(EnumerateDeviceExtensionProperties, ZeroPhysicalDeviceExtensions) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
@@ -482,16 +479,12 @@
     std::vector<Extension> exts = {Extension{"MyDriverExtension0", 4}, Extension{"MyDriverExtension1", 7},
                                    Extension{"MyDriverExtension2", 6}, Extension{"MyDriverExtension3", 10}};
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .add_physical_device("physical_device_0")
-        .physical_devices.at(0)
-        .add_extensions(exts);
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_and_get_physical_device("physical_device_0").add_extensions(exts);
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -501,7 +494,7 @@
 
 TEST(EnumerateDeviceExtensionProperties, ImplicitLayerPresentWithExtensions) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    auto& test_physical_device = env.add_icd(TEST_ICD_PATH_VERSION_2).add_and_get_physical_device({});
 
     std::vector<Extension> exts;
     std::vector<ManifestLayer::LayerDescription::Extension> layer_exts;
@@ -509,19 +502,18 @@
         exts.emplace_back(std::string("LayerExtNumba") + std::to_string(i), i + 10);
         layer_exts.emplace_back(std::string("LayerExtNumba") + std::to_string(i), i + 10);
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")
-                                                         .add_device_extensions({layer_exts})),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")
+                                                             .add_device_extensions({layer_exts})));
     auto& layer = env.get_test_layer();
     layer.device_extensions = exts;
 
-    driver.physical_devices.front().extensions.emplace_back("MyDriverExtension0", 4);
-    driver.physical_devices.front().extensions.emplace_back("MyDriverExtension1", 7);
+    test_physical_device.extensions.emplace_back("MyDriverExtension0", 4);
+    test_physical_device.extensions.emplace_back("MyDriverExtension1", 7);
 
-    exts.insert(exts.begin(), driver.physical_devices.front().extensions.begin(), driver.physical_devices.front().extensions.end());
+    exts.insert(exts.begin(), test_physical_device.extensions.begin(), test_physical_device.extensions.end());
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -532,7 +524,7 @@
 
 TEST(EnumerateDeviceExtensionProperties, ImplicitLayerPresentWithLotsOfExtensions) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    auto& test_physical_device = env.add_icd(TEST_ICD_PATH_VERSION_2).add_and_get_physical_device({});
 
     std::vector<Extension> exts;
     std::vector<ManifestLayer::LayerDescription::Extension> layer_exts;
@@ -540,21 +532,20 @@
         exts.emplace_back(std::string("LayerExtNumba") + std::to_string(i), i + 10);
         layer_exts.emplace_back(std::string("LayerExtNumba") + std::to_string(i), i + 10);
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")
-                                                         .add_device_extensions({layer_exts})),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")
+                                                             .add_device_extensions({layer_exts})));
     auto& layer = env.get_test_layer();
     layer.device_extensions = exts;
 
-    driver.physical_devices.front().extensions.emplace_back("MyDriverExtension0", 4);
-    driver.physical_devices.front().extensions.emplace_back("MyDriverExtension1", 7);
-    driver.physical_devices.front().extensions.emplace_back("MyDriverExtension2", 6);
-    driver.physical_devices.front().extensions.emplace_back("MyDriverExtension3", 9);
+    test_physical_device.extensions.emplace_back("MyDriverExtension0", 4);
+    test_physical_device.extensions.emplace_back("MyDriverExtension1", 7);
+    test_physical_device.extensions.emplace_back("MyDriverExtension2", 6);
+    test_physical_device.extensions.emplace_back("MyDriverExtension3", 9);
 
-    exts.insert(exts.begin(), driver.physical_devices.front().extensions.begin(), driver.physical_devices.front().extensions.end());
+    exts.insert(exts.begin(), test_physical_device.extensions.begin(), test_physical_device.extensions.end());
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -565,7 +556,7 @@
 
 TEST(EnumerateDeviceExtensionProperties, NoDriverExtensionsImplicitLayerPresentWithExtensions) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     std::vector<Extension> exts;
     std::vector<ManifestLayer::LayerDescription::Extension> layer_exts;
@@ -573,12 +564,11 @@
         exts.emplace_back(std::string("LayerExtNumba") + std::to_string(i), i + 10);
         layer_exts.emplace_back(std::string("LayerExtNumba") + std::to_string(i), i + 10);
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")
-                                                         .add_device_extensions({layer_exts})),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")
+                                                             .add_device_extensions({layer_exts})));
     auto& layer = env.get_test_layer();
     layer.device_extensions = exts;
 
@@ -591,7 +581,7 @@
 
 TEST(EnumerateDeviceExtensionProperties, NoDriverExtensionsImplicitLayerPresentWithLotsOfExtensions) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     std::vector<Extension> exts;
     std::vector<ManifestLayer::LayerDescription::Extension> layer_exts;
@@ -599,12 +589,11 @@
         exts.emplace_back(std::string("LayerExtNumba") + std::to_string(i), i + 10);
         layer_exts.emplace_back(std::string("LayerExtNumba") + std::to_string(i), i + 10);
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")
-                                                         .add_device_extensions({layer_exts})),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")
+                                                             .add_device_extensions({layer_exts})));
     auto& layer = env.get_test_layer();
     layer.device_extensions = exts;
 
@@ -617,7 +606,7 @@
 
 TEST(EnumerateDeviceExtensionProperties, ImplicitLayerPresentWithDuplicateExtensions) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    auto& test_physical_device = env.add_icd(TEST_ICD_PATH_VERSION_2).add_and_get_physical_device({});
 
     std::vector<Extension> exts;
     std::vector<ManifestLayer::LayerDescription::Extension> layer_exts;
@@ -625,23 +614,22 @@
         exts.emplace_back(std::string("LayerExtNumba") + std::to_string(i), i + 10);
         layer_exts.emplace_back(std::string("LayerExtNumba") + std::to_string(i), i + 10);
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")
-                                                         .add_device_extensions({layer_exts})),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")
+                                                             .add_device_extensions({layer_exts})));
     auto& layer = env.get_test_layer();
     layer.device_extensions = exts;
 
-    driver.physical_devices.front().extensions.emplace_back("MyDriverExtension0", 4);
-    driver.physical_devices.front().extensions.emplace_back("MyDriverExtension1", 7);
+    test_physical_device.extensions.emplace_back("MyDriverExtension0", 4);
+    test_physical_device.extensions.emplace_back("MyDriverExtension1", 7);
 
-    driver.physical_devices.front().extensions.insert(driver.physical_devices.front().extensions.end(), exts.begin(), exts.end());
+    test_physical_device.extensions.insert(test_physical_device.extensions.end(), exts.begin(), exts.end());
     exts.emplace_back("MyDriverExtension0", 4);
     exts.emplace_back("MyDriverExtension1", 7);
 
-    driver.physical_devices.front().extensions = exts;
+    test_physical_device.extensions = exts;
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -652,7 +640,7 @@
 
 TEST(EnumerateDeviceExtensionProperties, ImplicitLayerPresentWithOnlyDuplicateExtensions) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    auto& test_physical_device = env.add_icd(TEST_ICD_PATH_VERSION_2).add_and_get_physical_device({});
 
     std::vector<Extension> exts;
     std::vector<ManifestLayer::LayerDescription::Extension> layer_exts;
@@ -660,16 +648,15 @@
         exts.emplace_back(std::string("LayerExtNumba") + std::to_string(i), i + 10);
         layer_exts.emplace_back(std::string("LayerExtNumba") + std::to_string(i), i + 10);
     }
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")
-                                                         .add_device_extensions({layer_exts})),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")
+                                                             .add_device_extensions({layer_exts})));
     auto& layer = env.get_test_layer();
     layer.device_extensions = exts;
 
-    driver.physical_devices.front().extensions = exts;
+    test_physical_device.extensions = exts;
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -680,7 +667,7 @@
 
 TEST(EnumeratePhysicalDevices, OneCall) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).set_min_icd_interface_version(5);
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2).set_min_icd_interface_version(5);
 
     driver.add_physical_device("physical_device_0");
     driver.add_physical_device("physical_device_1");
@@ -699,14 +686,14 @@
 
 TEST(EnumeratePhysicalDevices, TwoCall) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2)
                        .set_min_icd_interface_version(5)
                        .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
 
     const uint32_t real_device_count = 2;
     for (uint32_t i = 0; i < real_device_count; i++) {
-        driver.add_physical_device(std::string("physical_device_") + std::to_string(i));
-        driver.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+        driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i))
+            .extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
     }
 
     InstWrapper inst{env.vulkan_functions};
@@ -725,14 +712,14 @@
 
 TEST(EnumeratePhysicalDevices, MatchOneAndTwoCallNumbers) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2)
                        .set_min_icd_interface_version(5)
                        .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
 
     const uint32_t real_device_count = 3;
     for (uint32_t i = 0; i < real_device_count; i++) {
-        driver.add_physical_device(std::string("physical_device_") + std::to_string(i));
-        driver.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+        driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i))
+            .extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
     }
 
     InstWrapper inst1{env.vulkan_functions};
@@ -761,14 +748,14 @@
 
 TEST(EnumeratePhysicalDevices, TwoCallIncomplete) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2)
                        .set_min_icd_interface_version(5)
                        .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
 
     const uint32_t real_device_count = 2;
     for (uint32_t i = 0; i < real_device_count; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
-        driver.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+        driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i))
+            .extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
     }
 
     InstWrapper inst{env.vulkan_functions};
@@ -807,7 +794,7 @@
 
 TEST(EnumeratePhysicalDevices, ZeroPhysicalDevices) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0));
     inst.CheckCreate();
@@ -819,7 +806,8 @@
 
 TEST(EnumeratePhysicalDevices, ZeroPhysicalDevicesAfterCreateInstance) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1)).set_min_icd_interface_version(5);
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
+                       .set_min_icd_interface_version(5);
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.set_api_version(VK_API_VERSION_1_1);
     inst.CheckCreate();
@@ -841,10 +829,10 @@
 
 TEST(EnumeratePhysicalDevices, CallTwiceNormal) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).set_min_icd_interface_version(5);
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2).set_min_icd_interface_version(5);
 
     for (size_t i = 0; i < 4; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
+        driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
     }
 
     InstWrapper inst{env.vulkan_functions};
@@ -867,10 +855,10 @@
 
 TEST(EnumeratePhysicalDevices, CallTwiceIncompleteOnceNormal) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).set_min_icd_interface_version(5);
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2).set_min_icd_interface_version(5);
 
     for (size_t i = 0; i < 8; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
+        driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
     }
 
     InstWrapper inst{env.vulkan_functions};
@@ -903,10 +891,10 @@
 
 TEST(EnumeratePhysicalDevices, CallThriceSuccessReduce) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).set_min_icd_interface_version(5);
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2).set_min_icd_interface_version(5);
 
     for (size_t i = 0; i < 8; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
+        driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
     }
 
     InstWrapper inst{env.vulkan_functions};
@@ -939,10 +927,10 @@
 
 TEST(EnumeratePhysicalDevices, CallThriceAddInBetween) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).set_min_icd_interface_version(5);
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2).set_min_icd_interface_version(5);
 
-    driver.physical_devices.emplace_back("physical_device_0");
-    driver.physical_devices.emplace_back("physical_device_1");
+    driver.add_physical_device("physical_device_0");
+    driver.add_physical_device("physical_device_1");
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -953,8 +941,8 @@
     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles_1.data()));
     ASSERT_EQ(physical_count, returned_physical_count);
 
-    driver.physical_devices.emplace_back("physical_device_2");
-    driver.physical_devices.emplace_back("physical_device_3");
+    driver.add_physical_device("physical_device_2");
+    driver.add_physical_device("physical_device_3");
 
     std::vector<VkPhysicalDevice> physical_device_handles_2 = std::vector<VkPhysicalDevice>(returned_physical_count);
     ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles_2.data()));
@@ -978,10 +966,10 @@
 
 TEST(EnumeratePhysicalDevices, CallThriceRemoveInBetween) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).set_min_icd_interface_version(5);
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2).set_min_icd_interface_version(5);
 
     for (size_t i = 0; i < 4; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
+        driver.add_physical_device(std::string("physical_device_") + std::to_string(i));
     }
 
     InstWrapper inst{env.vulkan_functions};
@@ -1034,11 +1022,12 @@
 
 TEST(EnumeratePhysicalDevices, MultipleAddRemoves) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).set_min_icd_interface_version(5);
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2).set_min_icd_interface_version(5);
+    auto phys_dev_handle_0 = driver.add_and_get_physical_device("physical_device_0").vk_physical_device.handle;
+    auto phys_dev_handle_1 = driver.add_and_get_physical_device("physical_device_1").vk_physical_device.handle;
+    auto phys_dev_handle_2 = driver.add_and_get_physical_device("physical_device_2").vk_physical_device.handle;
+    auto phys_dev_handle_3 = driver.add_and_get_physical_device("physical_device_3").vk_physical_device.handle;
 
-    for (size_t i = 0; i < 4; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
-    }
     std::array<std::vector<VkPhysicalDevice>, 8> physical_dev_handles;
 
     InstWrapper inst{env.vulkan_functions};
@@ -1051,7 +1040,7 @@
     ASSERT_EQ(physical_count, returned_physical_count);
 
     // Delete the 2nd physical device (0, 2, 3)
-    driver.physical_devices.erase(std::next(driver.physical_devices.begin()));
+    driver.physical_devices.erase(phys_dev_handle_1);
 
     // Query using old number from last call (4), but it should only return 3
     physical_count = static_cast<uint32_t>(driver.physical_devices.size());
@@ -1061,8 +1050,8 @@
     physical_dev_handles[1].resize(returned_physical_count);
 
     // Add two new physical devices to the front (A, B, 0, 2, 3)
-    driver.physical_devices.emplace(driver.physical_devices.begin(), "physical_device_B");
-    driver.physical_devices.emplace(driver.physical_devices.begin(), "physical_device_A");
+    auto phys_dev_handle_a = driver.add_physical_device_at_index(0, "physical_device_B").vk_physical_device.handle;
+    auto phys_dev_handle_b = driver.add_physical_device_at_index(1, "physical_device_A").vk_physical_device.handle;
 
     // Query using old number from last call (3), but it should be 5
     physical_count = static_cast<uint32_t>(driver.physical_devices.size());
@@ -1078,7 +1067,7 @@
     ASSERT_EQ(physical_count, returned_physical_count);
 
     // Delete last two physical devices (A, B, 0, 2)
-    driver.physical_devices.pop_back();
+    driver.physical_devices.erase(phys_dev_handle_3);
 
     // Query using old number from last call (5), but it should be 4
     physical_count = static_cast<uint32_t>(driver.physical_devices.size());
@@ -1091,7 +1080,7 @@
     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_dev_handles[5].data()));
 
     // Insert a new physical device (A, B, C, 0, 2)
-    driver.physical_devices.insert(driver.physical_devices.begin() + 2, "physical_device_C");
+    auto phys_dev_handle_c = driver.add_physical_device_at_index(2, "physical_device_C").vk_physical_device.handle;
 
     // Query using old number from last call (4), but it should be 5
     physical_count = static_cast<uint32_t>(driver.physical_devices.size());
@@ -1165,7 +1154,7 @@
 
 TEST(EnumeratePhysicalDevices, OneDriverWithWrongErrorCodes) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -1196,8 +1185,8 @@
 
 TEST(EnumeratePhysicalDevices, TwoDriversOneWithWrongErrorCodes) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
-    TestICD& icd1 = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
+    TestICD& icd1 = env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -1223,9 +1212,216 @@
     }
 }
 
+TEST(EnumeratePhysicalDevices, DeviceFiltering) {
+    FrameworkEnvironment env{};
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2).set_min_icd_interface_version(5);
+
+    for (uint32_t i = 0; i < 10; i++) {
+        auto& physical_device = driver.add_and_get_physical_device("physical_device_" + std::to_string(i));
+        physical_device.properties.deviceID = 0x1000 + i;
+        physical_device.properties.vendorID = 0x2000 + i;
+    }
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+
+    uint32_t physical_count = static_cast<uint32_t>(driver.physical_devices.size());
+
+    // filter multiple device by device id
+    {
+        env.env_var_vk_loader_device_id_filter.set_new_value("0x1001-0x1003,0x1006");
+
+        uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(4, returned_physical_count);
+
+        env.env_var_vk_loader_device_id_filter.remove_value();
+    }
+
+    // filter multiple device by vendor id
+    {
+        env.env_var_vk_loader_vendor_id_filter.set_new_value("0x2001-0x2003,0x2006");
+
+        uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(4, returned_physical_count);
+
+        env.env_var_vk_loader_vendor_id_filter.remove_value();
+    }
+
+    // filter multiple device by vendor id and device id
+    {
+        env.env_var_vk_loader_device_id_filter.set_new_value("0x1002-0x1004");
+        env.env_var_vk_loader_vendor_id_filter.set_new_value("0x2003-0x2007");
+
+        uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(2, returned_physical_count);
+
+        env.env_var_vk_loader_vendor_id_filter.remove_value();
+        env.env_var_vk_loader_device_id_filter.remove_value();
+    }
+
+    // return value change by device filter
+    {
+        uint32_t returned_physical_count = 5;
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(5, returned_physical_count);
+
+        env.env_var_vk_loader_device_id_filter.set_new_value("0x1003-0x1004");
+
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(2, returned_physical_count);
+
+        env.env_var_vk_loader_device_id_filter.remove_value();
+    }
+
+    // return value change by vendor filter
+    {
+        uint32_t returned_physical_count = 5;
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(5, returned_physical_count);
+
+        env.env_var_vk_loader_vendor_id_filter.set_new_value("0x2005-0x2006");
+
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(2, returned_physical_count);
+
+        env.env_var_vk_loader_vendor_id_filter.remove_value();
+    }
+
+    // incomplete result with device filter
+    {
+        env.env_var_vk_loader_device_id_filter.set_new_value("0x1001-0x1006");
+
+        uint32_t returned_physical_count = 3;
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(3, returned_physical_count);
+
+        env.env_var_vk_loader_device_id_filter.remove_value();
+    }
+
+    // filter all device
+    {
+        env.env_var_vk_loader_device_id_filter.set_new_value("0x2002-0x2003");
+
+        uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(0, returned_physical_count);
+
+        env.env_var_vk_loader_device_id_filter.remove_value();
+    }
+
+    // no device filtering
+    {
+        env.env_var_vk_loader_vendor_id_filter.remove_value();
+        env.env_var_vk_loader_device_id_filter.remove_value();
+
+        uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(physical_count, returned_physical_count);
+    }
+}
+
+TEST(EnumeratePhysicalDevices, DeviceFilteringByDriverId) {
+    FrameworkEnvironment env{};
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
+                       .set_min_icd_interface_version(5)
+                       .set_icd_api_version(VK_API_VERSION_1_1)
+                       .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
+
+    for (uint32_t i = 0; i < 10; i++) {
+        auto& physical_device = driver.add_and_get_physical_device("physical_device_" + std::to_string(i));
+        physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+        physical_device.driver_properties.driverID = VkDriverId(100 + i);
+    }
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.set_api_version(VK_API_VERSION_1_1);
+    inst.CheckCreate();
+
+    uint32_t physical_count = static_cast<uint32_t>(driver.physical_devices.size());
+
+    // filter multiple device by driver id
+    {
+        env.env_var_vk_loader_driver_id_filter.set_new_value("103-105,107");
+
+        uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(4, returned_physical_count);
+
+        env.env_var_vk_loader_driver_id_filter.remove_value();
+    }
+
+    // return value change by driver filter
+    {
+        uint32_t returned_physical_count = 5;
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(5, returned_physical_count);
+
+        env.env_var_vk_loader_driver_id_filter.set_new_value("103-104");
+
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(2, returned_physical_count);
+
+        env.env_var_vk_loader_driver_id_filter.remove_value();
+    }
+
+    // incomplete result with driver filter
+    {
+        env.env_var_vk_loader_driver_id_filter.set_new_value("102-105");
+
+        uint32_t returned_physical_count = 3;
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(3, returned_physical_count);
+
+        env.env_var_vk_loader_driver_id_filter.remove_value();
+    }
+
+    // filter all device
+    {
+        env.env_var_vk_loader_driver_id_filter.set_new_value("50");
+
+        uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(0, returned_physical_count);
+
+        env.env_var_vk_loader_driver_id_filter.remove_value();
+    }
+
+    InstWrapper inst_1_0{env.vulkan_functions};
+    inst_1_0.create_info.set_api_version(VK_API_VERSION_1_0);
+    inst_1_0.CheckCreate();
+
+    // Unsupported device filtering by driver id
+    {
+        env.env_var_vk_loader_driver_id_filter.set_new_value("103-105,107");
+
+        uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
+        std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+        ASSERT_EQ(VK_SUCCESS,
+                  inst_1_0->vkEnumeratePhysicalDevices(inst_1_0, &returned_physical_count, physical_device_handles.data()));
+        ASSERT_EQ(0, returned_physical_count);
+
+        env.env_var_vk_loader_driver_id_filter.remove_value();
+    }
+}
+
 TEST(CreateDevice, ExtensionNotPresent) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -1243,7 +1439,7 @@
 // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#extendingvulkan-layers-devicelayerdeprecation
 TEST(CreateDevice, LayersNotPresent) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -1261,13 +1457,12 @@
 // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#extendingvulkan-layers-devicelayerdeprecation
 TEST(CreateDevice, MatchInstanceAndDeviceLayers) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     const char* layer_name = "TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.add_layer(layer_name);
@@ -1287,13 +1482,12 @@
 // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#extendingvulkan-layers-devicelayerdeprecation
 TEST(CreateDevice, UnmatchInstanceAndDeviceLayers) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     const char* layer_name = "TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     DebugUtilsLogger debug_log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT};
     InstWrapper inst{env.vulkan_functions};
@@ -1321,13 +1515,12 @@
 // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#extendingvulkan-layers-devicelayerdeprecation
 TEST(CreateDevice, CheckCopyOfInstanceLayerNames) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     const char* layer_name = "TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     InstWrapper inst{env.vulkan_functions};
     {
@@ -1348,10 +1541,10 @@
 
 TEST(CreateDevice, ConsecutiveCreate) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     for (uint32_t i = 0; i < 100; i++) {
-        driver.physical_devices.emplace_back("physical_device_0");
+        driver.add_physical_device("physical_device_0");
     }
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -1365,10 +1558,10 @@
 
 TEST(CreateDevice, ConsecutiveCreateWithoutDestruction) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     for (uint32_t i = 0; i < 100; i++) {
-        driver.physical_devices.emplace_back("physical_device_0");
+        driver.add_physical_device("physical_device_0");
     }
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -1386,8 +1579,8 @@
 
 TEST(TryLoadWrongBinaries, WrongICD) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
-    env.add_icd(TestICDDetails(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE).set_is_fake(true));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
+    env.add_icd(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE, ManifestOptions{}.set_is_fake(true));
 
     DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT};
     InstWrapper inst{env.vulkan_functions};
@@ -1412,13 +1605,13 @@
 
 TEST(TryLoadWrongBinaries, WrongExplicit) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     const char* layer_name = "DummyLayerExplicit";
-    env.add_fake_explicit_layer(
+    env.add_explicit_layer(
+        ManifestOptions{}.set_is_fake(true),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE)),
-        "dummy_test_layer.json");
+            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE)));
 
     auto layer_props = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layer_name, layer_props[0].layerName));
@@ -1435,21 +1628,21 @@
 #if !defined(__APPLE__)
     ASSERT_TRUE(log.find(std::string("Requested layer \"") + std::string(layer_name) + std::string("\" was wrong bit-type!")));
 #else   // __APPLE__
-    // Apple only throws a wrong library type of error
+        // Apple only throws a wrong library type of error
     ASSERT_TRUE(log.find(std::string("Requested layer \"") + std::string(layer_name) + std::string("\" failed to load!")));
 #endif  // __APPLE__
 }
 
 TEST(TryLoadWrongBinaries, WrongImplicit) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     const char* layer_name = "DummyLayerImplicit0";
-    env.add_fake_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                              .set_name(layer_name)
-                                                              .set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE)
-                                                              .set_disable_environment("DISABLE_ENV")),
-                                "dummy_test_layer.json");
+    env.add_implicit_layer(ManifestOptions{}.set_is_fake(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE)
+                                                         .set_disable_environment("DISABLE_ENV")));
 
     auto layer_props = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layer_name, layer_props[0].layerName));
@@ -1473,19 +1666,20 @@
 
 TEST(TryLoadWrongBinaries, WrongExplicitAndImplicit) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     const char* layer_name_0 = "DummyLayerExplicit";
-    env.add_fake_explicit_layer(
+    env.add_explicit_layer(
+        ManifestOptions{}.set_is_fake(true),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name_0).set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE)),
-        "dummy_test_layer_0.json");
+            ManifestLayer::LayerDescription{}.set_name(layer_name_0).set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE)));
+
     const char* layer_name_1 = "DummyLayerImplicit";
-    env.add_fake_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                              .set_name(layer_name_1)
-                                                              .set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE)
-                                                              .set_disable_environment("DISABLE_ENV")),
-                                "dummy_test_layer_1.json");
+    env.add_implicit_layer(ManifestOptions{}.set_is_fake(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name_1)
+                                                         .set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE)
+                                                         .set_disable_environment("DISABLE_ENV")));
 
     auto layer_props = env.GetLayerProperties(2);
     ASSERT_TRUE(check_permutation({layer_name_0, layer_name_1}, layer_props));
@@ -1512,19 +1706,20 @@
 
 TEST(TryLoadWrongBinaries, WrongExplicitAndImplicitErrorOnly) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     const char* layer_name_0 = "DummyLayerExplicit";
-    env.add_fake_explicit_layer(
+    env.add_explicit_layer(
+        ManifestOptions{}.set_is_fake(true),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name_0).set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE)),
-        "dummy_test_layer_0.json");
+            ManifestLayer::LayerDescription{}.set_name(layer_name_0).set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE)));
+
     const char* layer_name_1 = "DummyLayerImplicit";
-    env.add_fake_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                              .set_name(layer_name_1)
-                                                              .set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE)
-                                                              .set_disable_environment("DISABLE_ENV")),
-                                "dummy_test_layer_1.json");
+    env.add_implicit_layer(ManifestOptions{}.set_is_fake(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name_1)
+                                                         .set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_WRONG_TYPE)
+                                                         .set_disable_environment("DISABLE_ENV")));
 
     auto layer_props = env.GetLayerProperties(2);
     ASSERT_TRUE(check_permutation({layer_name_0, layer_name_1}, layer_props));
@@ -1550,13 +1745,13 @@
 
 TEST(TryLoadWrongBinaries, BadExplicit) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     const char* layer_name = "DummyLayerExplicit";
-    env.add_fake_explicit_layer(
+    env.add_explicit_layer(
+        ManifestOptions{}.set_is_fake(true),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_BAD)),
-        "dummy_test_layer.json");
+            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_BAD)));
 
     auto layer_props = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layer_name, layer_props[0].layerName));
@@ -1569,20 +1764,24 @@
     // Explicit layer not found should generate a VK_ERROR_LAYER_NOT_PRESENT error message.
     inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
 
-    // Should get an error message for the bad explicit
+// Should get an error message for the bad explicit
+#if defined(WIN32)
+    ASSERT_TRUE(log.find(std::string("Requested layer \"") + std::string(layer_name) + std::string("\" was wrong bit-type!")));
+#else
     ASSERT_TRUE(log.find(std::string("Requested layer \"") + std::string(layer_name) + std::string("\" failed to load!")));
+#endif  // defined(WIN32)
 }
 
 TEST(TryLoadWrongBinaries, BadImplicit) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     const char* layer_name = "DummyLayerImplicit0";
-    env.add_fake_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                              .set_name(layer_name)
-                                                              .set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_BAD)
-                                                              .set_disable_environment("DISABLE_ENV")),
-                                "dummy_test_layer.json");
+    env.add_implicit_layer(ManifestOptions{}.set_is_fake(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_BAD)
+                                                         .set_disable_environment("DISABLE_ENV")));
 
     auto layer_props = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(layer_name, layer_props[0].layerName));
@@ -1596,24 +1795,29 @@
     inst.CheckCreate();
 
     // Should get an info message for the bad implicit
+#if defined(WIN32)
+    ASSERT_TRUE(log.find(std::string("Requested layer \"") + std::string(layer_name) + std::string("\" was wrong bit-type.")));
+#else
     ASSERT_TRUE(log.find(std::string("Requested layer \"") + std::string(layer_name) + std::string("\" failed to load.")));
+#endif  // defined(WIN32)
 }
 
 TEST(TryLoadWrongBinaries, BadExplicitAndImplicit) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     const char* layer_name_0 = "DummyLayerExplicit";
-    env.add_fake_explicit_layer(
+    env.add_explicit_layer(
+        ManifestOptions{}.set_is_fake(true),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name_0).set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_BAD)),
-        "dummy_test_layer_0.json");
+            ManifestLayer::LayerDescription{}.set_name(layer_name_0).set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_BAD)));
+
     const char* layer_name_1 = "DummyLayerImplicit0";
-    env.add_fake_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                              .set_name(layer_name_1)
-                                                              .set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_BAD)
-                                                              .set_disable_environment("DISABLE_ENV")),
-                                "dummy_test_layer_1.json");
+    env.add_implicit_layer(ManifestOptions{}.set_is_fake(true),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name_1)
+                                                         .set_lib_path(CURRENT_PLATFORM_DUMMY_BINARY_BAD)
+                                                         .set_disable_environment("DISABLE_ENV")));
 
     auto layer_props = env.GetLayerProperties(2);
     ASSERT_TRUE(check_permutation({layer_name_0, layer_name_1}, layer_props));
@@ -1625,16 +1829,19 @@
 
     // Explicit layer not found should generate a VK_ERROR_LAYER_NOT_PRESENT error message.
     inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
-
-    // Apple only throws a wrong library type of error
+#if defined(WIN32)
+    ASSERT_TRUE(log.find(std::string("Requested layer \"") + std::string(layer_name_0) + std::string("\" was wrong bit-type!")));
+    ASSERT_TRUE(log.find(std::string("Requested layer \"") + std::string(layer_name_1) + std::string("\" was wrong bit-type.")));
+#else
     ASSERT_TRUE(log.find(std::string("Requested layer \"") + std::string(layer_name_0) + std::string("\" failed to load!")));
     ASSERT_TRUE(log.find(std::string("Requested layer \"") + std::string(layer_name_1) + std::string("\" failed to load.")));
+#endif  // defined(WIN32)
 }
 
 TEST(TryLoadWrongBinaries, WrongArchDriver) {
     FrameworkEnvironment env{};
     // Intentionally set the wrong arch
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2}.icd_manifest.set_library_arch(sizeof(void*) == 4 ? "64" : "32"))
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_library_arch(sizeof(void*) == 4 ? "64" : "32"))
         .add_physical_device("physical_device_0");
 
     DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT};
@@ -1648,15 +1855,14 @@
 
 TEST(TryLoadWrongBinaries, WrongArchLayer) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2}).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
 
     const char* layer_name = "TestLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         // Intentionally set the wrong arch
-                                                         .set_library_arch(sizeof(void*) == 4 ? "64" : "32")),
-                           "test_layer.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             // Intentionally set the wrong arch
+                                                             .set_library_arch(sizeof(void*) == 4 ? "64" : "32")));
 
     DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT};
     InstWrapper inst{env.vulkan_functions};
@@ -1669,20 +1875,22 @@
 
 TEST(EnumeratePhysicalDeviceGroups, OneCall) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
                        .set_min_icd_interface_version(5)
                        .set_icd_api_version(VK_API_VERSION_1_1)
                        .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
 
     // ICD contains 3 devices in two groups
+    std::array<PhysicalDevice*, 3> phys_devices;
     for (size_t i = 0; i < 3; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
-        driver.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-        driver.physical_devices.back().properties.apiVersion = VK_API_VERSION_1_1;
+        auto& test_physical_device = driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
+        test_physical_device.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+        test_physical_device.properties.apiVersion = VK_API_VERSION_1_1;
+        phys_devices[i] = &test_physical_device;
     }
-    driver.physical_device_groups.emplace_back(driver.physical_devices[0]);
-    driver.physical_device_groups.back().use_physical_device(driver.physical_devices[1]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[2]);
+    driver.physical_device_groups.emplace_back(phys_devices[0]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[1]);
+    driver.physical_device_groups.emplace_back(phys_devices[2]);
     const uint32_t max_physical_device_count = 3;
 
     // Core function
@@ -1803,20 +2011,22 @@
 
 TEST(EnumeratePhysicalDeviceGroups, TwoCall) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
                        .set_min_icd_interface_version(5)
                        .set_icd_api_version(VK_API_VERSION_1_1)
                        .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
 
     // ICD contains 3 devices in two groups
+    std::array<PhysicalDevice*, 3> phys_devices;
     for (size_t i = 0; i < 3; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
-        driver.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-        driver.physical_devices.back().properties.apiVersion = VK_API_VERSION_1_1;
+        auto& test_physical_device = driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
+        test_physical_device.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+        test_physical_device.properties.apiVersion = VK_API_VERSION_1_1;
+        phys_devices[i] = &test_physical_device;
     }
-    driver.physical_device_groups.emplace_back(driver.physical_devices[0]);
-    driver.physical_device_groups.back().use_physical_device(driver.physical_devices[1]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[2]);
+    driver.physical_device_groups.emplace_back(phys_devices[0]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[1]);
+    driver.physical_device_groups.emplace_back(phys_devices[2]);
     const uint32_t max_physical_device_count = 3;
 
     // Core function
@@ -1920,20 +2130,22 @@
 
 TEST(EnumeratePhysicalDeviceGroups, TwoCallIncomplete) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
                        .set_min_icd_interface_version(5)
                        .set_icd_api_version(VK_API_VERSION_1_1)
                        .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
 
     // ICD contains 3 devices in two groups
+    std::array<PhysicalDevice*, 3> phys_devices;
     for (size_t i = 0; i < 3; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
-        driver.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-        driver.physical_devices.back().properties.apiVersion = VK_API_VERSION_1_1;
+        auto& test_physical_device = driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
+        test_physical_device.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+        test_physical_device.properties.apiVersion = VK_API_VERSION_1_1;
+        phys_devices[i] = &test_physical_device;
     }
-    driver.physical_device_groups.emplace_back(driver.physical_devices[0]);
-    driver.physical_device_groups.back().use_physical_device(driver.physical_devices[1]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[2]);
+    driver.physical_device_groups.emplace_back(phys_devices[0]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[1]);
+    driver.physical_device_groups.emplace_back(phys_devices[2]);
 
     // Core function
     {
@@ -2020,26 +2232,26 @@
 // vkEnumeratePhysicalDeviceGroupsKHR, and make sure they return the same info.
 TEST(EnumeratePhysicalDeviceGroups, TestCoreVersusExtensionSameReturns) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
                        .set_min_icd_interface_version(5)
                        .set_icd_api_version(VK_API_VERSION_1_1)
                        .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME})
                        .add_instance_extension({VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME});
 
     // Generate the devices
+    std::array<PhysicalDevice*, 6> phys_devices;
     for (size_t i = 0; i < 6; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
-        driver.physical_devices.back().properties.apiVersion = VK_API_VERSION_1_1;
+        auto& test_physical_device = driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
+        test_physical_device.properties.apiVersion = VK_API_VERSION_1_1;
+        phys_devices[i] = &test_physical_device;
     }
 
     // Generate the starting groups
-    driver.physical_device_groups.emplace_back(driver.physical_devices[0]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[1]);
-    driver.physical_device_groups.back()
-        .use_physical_device(driver.physical_devices[2])
-        .use_physical_device(driver.physical_devices[3]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[4]);
-    driver.physical_device_groups.back().use_physical_device(driver.physical_devices[5]);
+    driver.physical_device_groups.emplace_back(phys_devices[0]);
+    driver.physical_device_groups.emplace_back(phys_devices[1]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[2]).use_physical_device(phys_devices[3]);
+    driver.physical_device_groups.emplace_back(phys_devices[4]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[5]);
 
     uint32_t expected_counts[3] = {1, 3, 2};
     uint32_t core_group_count = 0;
@@ -2110,24 +2322,24 @@
 // querying vkEnumeratePhysicalDeviceGroups before and after the add.
 TEST(EnumeratePhysicalDeviceGroups, CallThriceAddGroupInBetween) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
                        .set_min_icd_interface_version(5)
                        .set_icd_api_version(VK_API_VERSION_1_1);
 
     // Generate the devices
+    std::array<PhysicalDevice*, 7> phys_devices;
     for (size_t i = 0; i < 7; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
-        driver.physical_devices.back().properties.apiVersion = VK_API_VERSION_1_1;
+        auto& test_physical_device = driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
+        test_physical_device.properties.apiVersion = VK_API_VERSION_1_1;
+        phys_devices[i] = &test_physical_device;
     }
 
     // Generate the starting groups
-    driver.physical_device_groups.emplace_back(driver.physical_devices[0]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[1]);
-    driver.physical_device_groups.back()
-        .use_physical_device(driver.physical_devices[2])
-        .use_physical_device(driver.physical_devices[3]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[4]);
-    driver.physical_device_groups.back().use_physical_device(driver.physical_devices[5]);
+    driver.physical_device_groups.emplace_back(phys_devices[0]);
+    driver.physical_device_groups.emplace_back(phys_devices[1]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[2]).use_physical_device(phys_devices[3]);
+    driver.physical_device_groups.emplace_back(phys_devices[4]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[5]);
 
     uint32_t before_expected_counts[3] = {1, 3, 2};
     uint32_t after_expected_counts[4] = {1, 3, 1, 2};
@@ -2150,7 +2362,7 @@
     }
 
     // Insert new group after first two
-    driver.physical_device_groups.insert(driver.physical_device_groups.begin() + 2, driver.physical_devices[6]);
+    driver.physical_device_groups.insert(driver.physical_device_groups.begin() + 2, phys_devices[6]);
 
     std::vector<VkPhysicalDeviceGroupProperties> group_props_after{};
     group_props_after.resize(before_group_count,
@@ -2205,25 +2417,25 @@
 // querying vkEnumeratePhysicalDeviceGroups before and after the remove.
 TEST(EnumeratePhysicalDeviceGroups, CallTwiceRemoveGroupInBetween) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
                        .set_min_icd_interface_version(5)
                        .set_icd_api_version(VK_API_VERSION_1_1);
 
     // Generate the devices
+    std::array<PhysicalDevice*, 7> phys_devices;
     for (size_t i = 0; i < 7; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
-        driver.physical_devices.back().properties.apiVersion = VK_API_VERSION_1_1;
+        auto& test_physical_device = driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
+        test_physical_device.properties.apiVersion = VK_API_VERSION_1_1;
+        phys_devices[i] = &test_physical_device;
     }
 
     // Generate the starting groups
-    driver.physical_device_groups.emplace_back(driver.physical_devices[0]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[1]);
-    driver.physical_device_groups.back()
-        .use_physical_device(driver.physical_devices[2])
-        .use_physical_device(driver.physical_devices[3]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[4]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[5]);
-    driver.physical_device_groups.back().use_physical_device(driver.physical_devices[6]);
+    driver.physical_device_groups.emplace_back(phys_devices[0]);
+    driver.physical_device_groups.emplace_back(phys_devices[1]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[2]).use_physical_device(phys_devices[3]);
+    driver.physical_device_groups.emplace_back(phys_devices[4]);
+    driver.physical_device_groups.emplace_back(phys_devices[5]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[6]);
 
     uint32_t before_expected_counts[4] = {1, 3, 1, 2};
     uint32_t after_expected_counts[3] = {1, 3, 2};
@@ -2292,24 +2504,24 @@
 // querying vkEnumeratePhysicalDeviceGroups before and after the add.
 TEST(EnumeratePhysicalDeviceGroups, CallTwiceAddDeviceInBetween) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
                        .set_min_icd_interface_version(5)
                        .set_icd_api_version(VK_API_VERSION_1_1);
 
     // Generate the devices
+    std::array<PhysicalDevice*, 7> phys_devices;
     for (size_t i = 0; i < 7; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
-        driver.physical_devices.back().properties.apiVersion = VK_API_VERSION_1_1;
+        auto& test_physical_device = driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
+        test_physical_device.properties.apiVersion = VK_API_VERSION_1_1;
+        phys_devices[i] = &test_physical_device;
     }
 
     // Generate the starting groups
-    driver.physical_device_groups.emplace_back(driver.physical_devices[0]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[1]);
-    driver.physical_device_groups.back()
-        .use_physical_device(driver.physical_devices[2])
-        .use_physical_device(driver.physical_devices[3]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[4]);
-    driver.physical_device_groups.back().use_physical_device(driver.physical_devices[5]);
+    driver.physical_device_groups.emplace_back(phys_devices[0]);
+    driver.physical_device_groups.emplace_back(phys_devices[1]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[2]).use_physical_device(phys_devices[3]);
+    driver.physical_device_groups.emplace_back(phys_devices[4]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[5]);
 
     uint32_t expected_group_count = 3;
     uint32_t before_expected_counts[3] = {1, 3, 2};
@@ -2331,7 +2543,7 @@
     }
 
     // Insert new device to 2nd group
-    driver.physical_device_groups[1].use_physical_device(driver.physical_devices[6]);
+    driver.physical_device_groups[1].use_physical_device(phys_devices[6]);
 
     std::vector<VkPhysicalDeviceGroupProperties> group_props_after{};
     group_props_after.resize(expected_group_count,
@@ -2378,24 +2590,24 @@
 // querying vkEnumeratePhysicalDeviceGroups before and after the remove.
 TEST(EnumeratePhysicalDeviceGroups, CallTwiceRemoveDeviceInBetween) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
                        .set_min_icd_interface_version(5)
                        .set_icd_api_version(VK_API_VERSION_1_1);
 
     // Generate the devices
+    std::array<PhysicalDevice*, 6> phys_devices;
     for (size_t i = 0; i < 6; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
-        driver.physical_devices.back().properties.apiVersion = VK_API_VERSION_1_1;
+        auto& test_physical_device = driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
+        test_physical_device.properties.apiVersion = VK_API_VERSION_1_1;
+        phys_devices[i] = &test_physical_device;
     }
 
     // Generate the starting groups
-    driver.physical_device_groups.emplace_back(driver.physical_devices[0]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[1]);
-    driver.physical_device_groups.back()
-        .use_physical_device(driver.physical_devices[2])
-        .use_physical_device(driver.physical_devices[3]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[4]);
-    driver.physical_device_groups.back().use_physical_device(driver.physical_devices[5]);
+    driver.physical_device_groups.emplace_back(phys_devices[0]);
+    driver.physical_device_groups.emplace_back(phys_devices[1]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[2]).use_physical_device(phys_devices[3]);
+    driver.physical_device_groups.emplace_back(phys_devices[4]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[5]);
 
     uint32_t before_expected_counts[3] = {1, 3, 2};
     uint32_t after_expected_counts[3] = {1, 2, 2};
@@ -2475,24 +2687,24 @@
 // various devices and groups while querying in between.
 TEST(EnumeratePhysicalDeviceGroups, MultipleAddRemoves) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
                        .set_min_icd_interface_version(5)
                        .set_icd_api_version(VK_API_VERSION_1_1);
 
     // Generate the devices
+    std::array<PhysicalDevice*, 9> phys_devices;
     for (size_t i = 0; i < 9; i++) {
-        driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i));
-        driver.physical_devices.back().properties.apiVersion = VK_API_VERSION_1_1;
+        auto& test_physical_device = driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
+        test_physical_device.properties.apiVersion = VK_API_VERSION_1_1;
+        phys_devices[i] = &test_physical_device;
     }
 
     // Generate the starting groups
-    driver.physical_device_groups.emplace_back(driver.physical_devices[0]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[1]);
-    driver.physical_device_groups.back()
-        .use_physical_device(driver.physical_devices[2])
-        .use_physical_device(driver.physical_devices[3]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[4]);
-    driver.physical_device_groups.back().use_physical_device(driver.physical_devices[5]);
+    driver.physical_device_groups.emplace_back(phys_devices[0]);
+    driver.physical_device_groups.emplace_back(phys_devices[1]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[2]).use_physical_device(phys_devices[3]);
+    driver.physical_device_groups.emplace_back(phys_devices[4]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[5]);
 
     uint32_t before_expected_counts[3] = {1, 3, 2};
     uint32_t after_add_group_expected_counts[4] = {1, 3, 1, 2};
@@ -2519,7 +2731,7 @@
     }
 
     // Insert new group after first two
-    driver.physical_device_groups.insert(driver.physical_device_groups.begin() + 2, driver.physical_devices[6]);
+    driver.physical_device_groups.insert(driver.physical_device_groups.begin() + 2, phys_devices[6]);
 
     // Should be: 4 Groups { { 0 }, { 1, 2, 3 }, { 6 }, { 4, 5 } }
     std::vector<VkPhysicalDeviceGroupProperties> group_props_after_add_group{};
@@ -2564,9 +2776,7 @@
     }
 
     // Add two devices to last group
-    driver.physical_device_groups.back()
-        .use_physical_device(driver.physical_devices[7])
-        .use_physical_device(driver.physical_devices[8]);
+    driver.physical_device_groups.back().use_physical_device(phys_devices[7]).use_physical_device(phys_devices[8]);
 
     // Should be: 3 Groups { { 2, 3 }, { 6 }, { 4, 5, 7, 8 } }
     std::vector<VkPhysicalDeviceGroupProperties> group_props_after_add_device{};
@@ -2617,47 +2827,43 @@
     //   PhysDev 6: pd6, Discrete, Vulkan 1.1, Bus 2
     //   Group 0: PhysDev 5, PhysDev 6
     //   Group 1: PhysDev 4
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     auto& cur_icd_0 = env.get_test_icd(0);
     cur_icd_0.set_icd_api_version(VK_API_VERSION_1_1);
-    cur_icd_0.physical_devices.push_back({"pd0"});
-    cur_icd_0.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_0.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            888, 0xAAA001);
-    cur_icd_0.physical_devices.push_back({"pd1"});
-    cur_icd_0.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_0.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
-                            VK_API_VERSION_1_1, 888, 0xAAA002);
-    cur_icd_0.physical_devices.push_back({"pd2"});
-    cur_icd_0.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_0.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            888, 0xAAA003);
+    auto& test_physical_device_0 = cur_icd_0.add_and_get_physical_device({"pd0"});
+    test_physical_device_0.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_0.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA001);
+    auto& test_physical_device_1 = cur_icd_0.add_and_get_physical_device({"pd1"});
+    test_physical_device_1.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_1.properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA002);
+    auto& test_physical_device_2 = cur_icd_0.add_and_get_physical_device({"pd2"});
+    test_physical_device_2.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_2.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA003);
     cur_icd_0.physical_device_groups.push_back({});
-    cur_icd_0.physical_device_groups.back()
-        .use_physical_device(cur_icd_0.physical_devices[0])
-        .use_physical_device(cur_icd_0.physical_devices[2]);
-    cur_icd_0.physical_device_groups.push_back({cur_icd_0.physical_devices[1]});
+    cur_icd_0.physical_device_groups.back().use_physical_device(test_physical_device_0).use_physical_device(test_physical_device_2);
+    cur_icd_0.physical_device_groups.push_back({test_physical_device_1});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     auto& cur_icd_1 = env.get_test_icd(1);
     cur_icd_1.set_icd_api_version(VK_API_VERSION_1_1);
-    cur_icd_1.physical_devices.push_back({"pd4"});
-    cur_icd_1.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_1.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            75, 0xCCCC001);
-    cur_icd_1.physical_devices.push_back({"pd5"});
-    cur_icd_1.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_1.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            75, 0xCCCC002);
-    cur_icd_1.physical_devices.push_back({"pd6"});
-    cur_icd_1.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_1.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            75, 0xCCCC003);
+    auto& test_physical_device_4 = cur_icd_1.add_and_get_physical_device({"pd4"});
+    test_physical_device_4.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_4.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC001);
+    auto& test_physical_device_5 = cur_icd_1.add_and_get_physical_device({"pd5"});
+    test_physical_device_5.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_5.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC002);
+    auto& test_physical_device_6 = cur_icd_1.add_and_get_physical_device({"pd6"});
+    test_physical_device_6.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_6.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC003);
     cur_icd_1.physical_device_groups.push_back({});
-    cur_icd_1.physical_device_groups.back()
-        .use_physical_device(cur_icd_1.physical_devices[1])
-        .use_physical_device(cur_icd_1.physical_devices[2]);
-    cur_icd_1.physical_device_groups.push_back({cur_icd_1.physical_devices[0]});
+    cur_icd_1.physical_device_groups.back().use_physical_device(test_physical_device_5).use_physical_device(test_physical_device_6);
+    cur_icd_1.physical_device_groups.push_back({test_physical_device_4});
 
     InstWrapper inst(env.vulkan_functions);
     inst.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -2695,6 +2901,266 @@
     }
 }
 
+TEST(EnumeratePhysicalDeviceGroups, DeviceFiltering) {
+    FrameworkEnvironment env{};
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
+                       .set_min_icd_interface_version(5)
+                       .set_icd_api_version(VK_API_VERSION_1_1)
+                       .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
+
+    // ICD contains 10 devices in 5 groups
+    std::array<PhysicalDevice*, 10> phys_devices;
+    for (size_t i = 0; i < phys_devices.size(); i++) {
+        auto& physical_device = driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
+        physical_device.properties.apiVersion = VK_API_VERSION_1_1;
+
+        physical_device.properties.deviceID = 0x1000 + i;
+        physical_device.properties.vendorID = 0x2000 + i;
+
+        phys_devices[i] = &physical_device;
+    }
+
+    for (size_t i = 0; i < 5; i++) {
+        driver.physical_device_groups.emplace_back(phys_devices[2 * i]);
+        driver.physical_device_groups.back().use_physical_device(phys_devices[2 * i + 1]);
+    }
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+
+    uint32_t physical_device_group_count = static_cast<uint32_t>(driver.physical_device_groups.size());
+
+    // filter multiple device by device id
+    {
+        env.env_var_vk_loader_device_id_filter.set_new_value("0x1000-0x1002,0x1006-0x1010");
+
+        uint32_t returned_physical_device_group_count = static_cast<uint32_t>(driver.physical_device_groups.size());
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_device_group_count,
+                                                                    physical_device_group_properties.data()));
+        ASSERT_EQ(3, returned_physical_device_group_count);
+
+        env.env_var_vk_loader_device_id_filter.remove_value();
+    }
+
+    // filter multiple device by vendor id
+    {
+        env.env_var_vk_loader_vendor_id_filter.set_new_value("0x200-0x2002,0x2006-0x2010");
+
+        uint32_t returned_physical_device_group_count = static_cast<uint32_t>(driver.physical_device_groups.size());
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_device_group_count,
+                                                                    physical_device_group_properties.data()));
+        ASSERT_EQ(3, returned_physical_device_group_count);
+
+        env.env_var_vk_loader_vendor_id_filter.remove_value();
+    }
+
+    // filter multiple device by vendor id and device id
+    {
+        env.env_var_vk_loader_device_id_filter.set_new_value("0x1000-0x1007");
+        env.env_var_vk_loader_vendor_id_filter.set_new_value("0x2004-0x2009");
+
+        uint32_t returned_physical_device_group_count = static_cast<uint32_t>(driver.physical_device_groups.size());
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_device_group_count,
+                                                                    physical_device_group_properties.data()));
+        ASSERT_EQ(2, returned_physical_device_group_count);
+
+        env.env_var_vk_loader_vendor_id_filter.remove_value();
+        env.env_var_vk_loader_device_id_filter.remove_value();
+    }
+
+    // return value change by device filter
+    {
+        uint32_t returned_physical_group_count = 3;
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_group_count,
+                                                                       physical_device_group_properties.data()));
+        ASSERT_EQ(3, returned_physical_group_count);
+
+        env.env_var_vk_loader_device_id_filter.set_new_value("0x1000-0x1001,0x1004-0x1005");
+
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_group_count,
+                                                                    physical_device_group_properties.data()));
+        ASSERT_EQ(2, returned_physical_group_count);
+
+        env.env_var_vk_loader_device_id_filter.remove_value();
+    }
+
+    // return value change by vendor filter
+    {
+        uint32_t returned_physical_group_count = 3;
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_group_count,
+                                                                       physical_device_group_properties.data()));
+        ASSERT_EQ(3, returned_physical_group_count);
+
+        env.env_var_vk_loader_vendor_id_filter.set_new_value("0x2002-0x2005");
+
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_group_count,
+                                                                    physical_device_group_properties.data()));
+        ASSERT_EQ(2, returned_physical_group_count);
+
+        env.env_var_vk_loader_vendor_id_filter.remove_value();
+    }
+
+    // incomplete result with device filter
+    {
+        env.env_var_vk_loader_device_id_filter.set_new_value("0x1000-0x1007");
+
+        uint32_t returned_physical_group_count = 2;
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_group_count,
+                                                                       physical_device_group_properties.data()));
+        ASSERT_EQ(2, returned_physical_group_count);
+
+        env.env_var_vk_loader_device_id_filter.remove_value();
+    }
+
+    // filter all device
+    {
+        env.env_var_vk_loader_device_id_filter.set_new_value("0x2002-0x2003");
+
+        uint32_t returned_physical_group_count = static_cast<uint32_t>(driver.physical_device_groups.size());
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_group_count,
+                                                                    physical_device_group_properties.data()));
+        ASSERT_EQ(0, returned_physical_group_count);
+
+        env.env_var_vk_loader_device_id_filter.remove_value();
+    }
+
+    // no device filtering
+    {
+        env.env_var_vk_loader_vendor_id_filter.remove_value();
+        env.env_var_vk_loader_device_id_filter.remove_value();
+
+        uint32_t returned_physical_group_count = static_cast<uint32_t>(driver.physical_device_groups.size());
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_group_count,
+                                                                    physical_device_group_properties.data()));
+        ASSERT_EQ(physical_device_group_count, returned_physical_group_count);
+    }
+}
+
+TEST(EnumeratePhysicalDeviceGroups, DeviceFilteringByDriverId) {
+    FrameworkEnvironment env{};
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
+                       .set_min_icd_interface_version(5)
+                       .set_icd_api_version(VK_API_VERSION_1_1)
+                       .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
+
+    // ICD contains 10 devices in 5 groups
+    std::array<PhysicalDevice*, 10> phys_devices;
+    for (size_t i = 0; i < phys_devices.size(); i++) {
+        auto& physical_device = driver.add_and_get_physical_device(std::string("physical_device_") + std::to_string(i));
+        physical_device.properties.apiVersion = VK_API_VERSION_1_1;
+
+        physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0});
+        physical_device.driver_properties.driverID = VkDriverId(100 + i);
+
+        phys_devices[i] = &physical_device;
+    }
+
+    for (size_t i = 0; i < 5; i++) {
+        driver.physical_device_groups.emplace_back(phys_devices[2 * i]);
+        driver.physical_device_groups.back().use_physical_device(phys_devices[2 * i + 1]);
+    }
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.set_api_version(VK_API_VERSION_1_1);
+    inst.CheckCreate();
+
+    uint32_t physical_device_group_count = static_cast<uint32_t>(driver.physical_device_groups.size());
+
+    // filter multiple device by device id
+    {
+        env.env_var_vk_loader_driver_id_filter.set_new_value("102-105,108-109");
+
+        uint32_t returned_physical_device_group_count = static_cast<uint32_t>(driver.physical_device_groups.size());
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_device_group_count,
+                                                                    physical_device_group_properties.data()));
+        ASSERT_EQ(3, returned_physical_device_group_count);
+
+        env.env_var_vk_loader_driver_id_filter.remove_value();
+    }
+
+    // return value change by driver filter
+    {
+        uint32_t returned_physical_group_count = 3;
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_group_count,
+                                                                       physical_device_group_properties.data()));
+        ASSERT_EQ(3, returned_physical_group_count);
+
+        env.env_var_vk_loader_driver_id_filter.set_new_value("102-103,106-107");
+
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_group_count,
+                                                                    physical_device_group_properties.data()));
+        ASSERT_EQ(2, returned_physical_group_count);
+
+        env.env_var_vk_loader_driver_id_filter.remove_value();
+    }
+
+    // incomplete result with driver filter
+    {
+        env.env_var_vk_loader_driver_id_filter.set_new_value("102-109");
+
+        uint32_t returned_physical_group_count = 2;
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_group_count,
+                                                                       physical_device_group_properties.data()));
+        ASSERT_EQ(2, returned_physical_group_count);
+
+        env.env_var_vk_loader_driver_id_filter.remove_value();
+    }
+
+    // filter all device
+    {
+        env.env_var_vk_loader_driver_id_filter.set_new_value("50");
+
+        uint32_t returned_physical_group_count = static_cast<uint32_t>(driver.physical_device_groups.size());
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_physical_group_count,
+                                                                    physical_device_group_properties.data()));
+        ASSERT_EQ(0, returned_physical_group_count);
+
+        env.env_var_vk_loader_driver_id_filter.remove_value();
+    }
+
+    InstWrapper inst_1_0{env.vulkan_functions};
+    inst_1_0.create_info.set_api_version(VK_API_VERSION_1_0);
+    inst_1_0.CheckCreate();
+
+    // Unsupported device filtering by driver id
+    {
+        env.env_var_vk_loader_driver_id_filter.set_new_value("102-105,108-109");
+
+        uint32_t returned_physical_device_group_count = static_cast<uint32_t>(driver.physical_device_groups.size());
+        std::vector<VkPhysicalDeviceGroupProperties> physical_device_group_properties =
+            std::vector<VkPhysicalDeviceGroupProperties>(physical_device_group_count);
+        ASSERT_EQ(VK_SUCCESS, inst_1_0->vkEnumeratePhysicalDeviceGroups(inst_1_0, &returned_physical_device_group_count,
+                                                                        physical_device_group_properties.data()));
+        ASSERT_EQ(0, returned_physical_device_group_count);
+
+        env.env_var_vk_loader_driver_id_filter.remove_value();
+    }
+}
+
 TEST(ExtensionManual, ToolingProperties) {
     VkPhysicalDeviceToolPropertiesEXT icd_tool_props{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT,
                                                      nullptr,
@@ -2705,7 +3171,7 @@
                                                      "No-Layer"};
     {  // No support in driver
         FrameworkEnvironment env{};
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
@@ -2721,7 +3187,7 @@
     }
     {  // extension is supported in driver
         FrameworkEnvironment env{};
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA))
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)
             .set_supports_tooling_info_ext(true)
             .add_tooling_property(icd_tool_props)
             .add_physical_device(PhysicalDevice{}.add_extension(VK_EXT_TOOLING_INFO_EXTENSION_NAME).finish());
@@ -2743,11 +3209,10 @@
     }
     {  // core
         FrameworkEnvironment env{};
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_3))
-            .add_physical_device({})
+        env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_3))
             .set_supports_tooling_info_core(true)
             .add_tooling_property(icd_tool_props)
-            .physical_devices.back()
+            .add_and_get_physical_device({})
             .properties.apiVersion = VK_MAKE_API_VERSION(0, 1, 3, 0);
 
         InstWrapper inst{env.vulkan_functions};
@@ -2768,7 +3233,7 @@
 }
 TEST(CreateInstance, InstanceNullLayerPtr) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     VkInstance inst = VK_NULL_HANDLE;
     VkInstanceCreateInfo info{};
     info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
@@ -2778,7 +3243,7 @@
 }
 TEST(CreateInstance, InstanceNullExtensionPtr) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     VkInstance inst = VK_NULL_HANDLE;
     VkInstanceCreateInfo info{};
     info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
@@ -2791,47 +3256,46 @@
 // NOTE: Sort order only affects Linux
 TEST(SortedPhysicalDevices, DevicesSortEnabled10NoAppExt) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({"pd0"});
-    env.get_test_icd(0).physical_devices.back().set_pci_bus(7);
-    FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
-                            VK_API_VERSION_1_1, 888, 0xAAA001);
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    env.get_test_icd(0).physical_devices.push_back({"pd1"});
-    env.get_test_icd(0).physical_devices.back().set_pci_bus(3);
-    FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
-                            VK_API_VERSION_1_1, 888, 0xAAA002);
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_0 = env.get_test_icd(0).add_and_get_physical_device({"pd0"});
+    test_physical_device_0.set_pci_bus(7);
+    FillInRandomDeviceProps(test_physical_device_0.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA001);
+    test_physical_device_0.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_1 = env.get_test_icd(0).add_and_get_physical_device({"pd1"});
+    test_physical_device_1.set_pci_bus(3);
+    FillInRandomDeviceProps(test_physical_device_1.properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA002);
+    test_physical_device_1.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     env.get_test_icd(1).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(1).physical_devices.push_back({"pd2"});
-    env.get_test_icd(1).physical_devices.back().set_pci_bus(0);
-    FillInRandomDeviceProps(env.get_test_icd(1).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_0,
-                            1, 0xBBBB001);
-    env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_2 = env.get_test_icd(1).add_and_get_physical_device({"pd2"});
+    test_physical_device_2.set_pci_bus(0);
+    FillInRandomDeviceProps(test_physical_device_2.properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_0, 1, 0xBBBB001);
+    test_physical_device_2.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(2).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(2).physical_devices.push_back({"pd3"});
-    env.get_test_icd(2).physical_devices.back().set_pci_bus(1);
-    FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
-                            VK_API_VERSION_1_1, 75, 0xCCCC001);
-    env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    env.get_test_icd(2).physical_devices.push_back({"pd4"});
-    env.get_test_icd(2).physical_devices.back().set_pci_bus(4);
-    FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
-                            VK_API_VERSION_1_0, 75, 0xCCCC002);
-    env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_3 = env.get_test_icd(2).add_and_get_physical_device({"pd3"});
+    test_physical_device_3.set_pci_bus(1);
+    FillInRandomDeviceProps(test_physical_device_3.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC001);
+    test_physical_device_3.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_4 = env.get_test_icd(2).add_and_get_physical_device({"pd4"});
+    test_physical_device_4.set_pci_bus(4);
+    FillInRandomDeviceProps(test_physical_device_4.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_0, 75,
+                            0xCCCC002);
+    test_physical_device_4.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(3).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(3).physical_devices.push_back({"pd5"});
-    env.get_test_icd(3).physical_devices.back().set_pci_bus(0);
-    FillInRandomDeviceProps(env.get_test_icd(3).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU,
-                            VK_API_VERSION_1_1, 6940, 0xDDDD001);
-    env.get_test_icd(3).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_5 = env.get_test_icd(3).add_and_get_physical_device({"pd5"});
+    test_physical_device_5.set_pci_bus(0);
+    FillInRandomDeviceProps(test_physical_device_5.properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, VK_API_VERSION_1_1, 6940,
+                            0xDDDD001);
+    test_physical_device_5.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
     InstWrapper instance(env.vulkan_functions);
     instance.CheckCreate();
@@ -2899,47 +3363,46 @@
 
 TEST(SortedPhysicalDevices, DevicesSortEnabled10AppExt) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({"pd0"});
-    env.get_test_icd(0).physical_devices.back().set_pci_bus(7);
-    FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
-                            VK_API_VERSION_1_1, 888, 0xAAA001);
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    env.get_test_icd(0).physical_devices.push_back({"pd1"});
-    env.get_test_icd(0).physical_devices.back().set_pci_bus(3);
-    FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
-                            VK_API_VERSION_1_1, 888, 0xAAA002);
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_0 = env.get_test_icd(0).add_and_get_physical_device({"pd0"});
+    test_physical_device_0.set_pci_bus(7);
+    FillInRandomDeviceProps(test_physical_device_0.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA001);
+    test_physical_device_0.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_1 = env.get_test_icd(0).add_and_get_physical_device({"pd1"});
+    test_physical_device_1.set_pci_bus(3);
+    FillInRandomDeviceProps(test_physical_device_1.properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA002);
+    test_physical_device_1.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     env.get_test_icd(1).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(1).physical_devices.push_back({"pd2"});
-    env.get_test_icd(1).physical_devices.back().set_pci_bus(0);
-    FillInRandomDeviceProps(env.get_test_icd(1).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_0,
-                            1, 0xBBBB001);
-    env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_2 = env.get_test_icd(1).add_and_get_physical_device({"pd2"});
+    test_physical_device_2.set_pci_bus(0);
+    FillInRandomDeviceProps(test_physical_device_2.properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_0, 1, 0xBBBB001);
+    test_physical_device_2.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(2).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(2).physical_devices.push_back({"pd3"});
-    env.get_test_icd(2).physical_devices.back().set_pci_bus(1);
-    FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
-                            VK_API_VERSION_1_1, 75, 0xCCCC001);
-    env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    env.get_test_icd(2).physical_devices.push_back({"pd4"});
-    env.get_test_icd(2).physical_devices.back().set_pci_bus(4);
-    FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
-                            VK_API_VERSION_1_0, 75, 0xCCCC002);
-    env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_3 = env.get_test_icd(2).add_and_get_physical_device({"pd3"});
+    test_physical_device_3.set_pci_bus(1);
+    FillInRandomDeviceProps(test_physical_device_3.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC001);
+    test_physical_device_3.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_4 = env.get_test_icd(2).add_and_get_physical_device({"pd4"});
+    test_physical_device_4.set_pci_bus(4);
+    FillInRandomDeviceProps(test_physical_device_4.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_0, 75,
+                            0xCCCC002);
+    test_physical_device_4.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(3).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(3).physical_devices.push_back({"pd5"});
-    env.get_test_icd(3).physical_devices.back().set_pci_bus(0);
-    FillInRandomDeviceProps(env.get_test_icd(3).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU,
-                            VK_API_VERSION_1_1, 6940, 0xDDDD001);
-    env.get_test_icd(3).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_5 = env.get_test_icd(3).add_and_get_physical_device({"pd5"});
+    test_physical_device_5.set_pci_bus(0);
+    FillInRandomDeviceProps(test_physical_device_5.properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, VK_API_VERSION_1_1, 6940,
+                            0xDDDD001);
+    test_physical_device_5.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -3021,51 +3484,50 @@
 
 TEST(SortedPhysicalDevices, DevicesSortEnabled11) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(0).set_icd_api_version(VK_API_VERSION_1_1);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({"pd0"});
-    env.get_test_icd(0).physical_devices.back().set_pci_bus(7);
-    FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
-                            VK_API_VERSION_1_0, 888, 0xAAA001);
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    env.get_test_icd(0).physical_devices.push_back({"pd1"});
-    env.get_test_icd(0).physical_devices.back().set_pci_bus(3);
-    FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
-                            VK_API_VERSION_1_0, 888, 0xAAA002);
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_0 = env.get_test_icd(0).add_and_get_physical_device({"pd0"});
+    test_physical_device_0.set_pci_bus(7);
+    FillInRandomDeviceProps(test_physical_device_0.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_0, 888,
+                            0xAAA001);
+    test_physical_device_0.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_1 = env.get_test_icd(0).add_and_get_physical_device({"pd1"});
+    test_physical_device_1.set_pci_bus(3);
+    FillInRandomDeviceProps(test_physical_device_1.properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, VK_API_VERSION_1_0, 888,
+                            0xAAA002);
+    test_physical_device_1.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(1).set_icd_api_version(VK_API_VERSION_1_1);
     env.get_test_icd(1).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(1).physical_devices.push_back({"pd2"});
-    env.get_test_icd(1).physical_devices.back().set_pci_bus(0);
-    FillInRandomDeviceProps(env.get_test_icd(1).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_0,
-                            1, 0xBBBB001);
-    env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_2 = env.get_test_icd(1).add_and_get_physical_device({"pd2"});
+    test_physical_device_2.set_pci_bus(0);
+    FillInRandomDeviceProps(test_physical_device_2.properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_0, 1, 0xBBBB001);
+    test_physical_device_2.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(2).set_icd_api_version(VK_API_VERSION_1_1);
     env.get_test_icd(2).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(2).physical_devices.push_back({"pd3"});
-    env.get_test_icd(2).physical_devices.back().set_pci_bus(1);
-    FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
-                            VK_API_VERSION_1_1, 75, 0xCCCC001);
-    env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    env.get_test_icd(2).physical_devices.push_back({"pd4"});
-    env.get_test_icd(2).physical_devices.back().set_pci_bus(4);
-    FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
-                            VK_API_VERSION_1_1, 75, 0xCCCC002);
-    env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_3 = env.get_test_icd(2).add_and_get_physical_device({"pd3"});
+    test_physical_device_3.set_pci_bus(1);
+    FillInRandomDeviceProps(test_physical_device_3.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC001);
+    test_physical_device_3.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_4 = env.get_test_icd(2).add_and_get_physical_device({"pd4"});
+    test_physical_device_4.set_pci_bus(4);
+    FillInRandomDeviceProps(test_physical_device_4.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC002);
+    test_physical_device_4.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     env.get_test_icd(3).set_icd_api_version(VK_API_VERSION_1_1);
     env.get_test_icd(3).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(3).physical_devices.push_back({"pd5"});
-    env.get_test_icd(3).physical_devices.back().set_pci_bus(0);
-    FillInRandomDeviceProps(env.get_test_icd(3).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU,
-                            VK_API_VERSION_1_1, 6940, 0xDDDD001);
-    env.get_test_icd(3).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_5 = env.get_test_icd(3).add_and_get_physical_device({"pd5"});
+    test_physical_device_5.set_pci_bus(0);
+    FillInRandomDeviceProps(test_physical_device_5.properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, VK_API_VERSION_1_1, 6940,
+                            0xDDDD001);
+    test_physical_device_5.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -3150,41 +3612,40 @@
 
     EnvVarWrapper disable_select_env_var{"VK_LOADER_DISABLE_SELECT", "1"};
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(0).physical_devices.push_back({"pd0"});
-    FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
-                            VK_API_VERSION_1_0, 888, 0xAAA001);
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    env.get_test_icd(0).physical_devices.push_back({"pd1"});
-    FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
-                            VK_API_VERSION_1_0, 888, 0xAAA002);
-    env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_0 = env.get_test_icd(0).add_and_get_physical_device({"pd0"});
+    FillInRandomDeviceProps(test_physical_device_0.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_0, 888,
+                            0xAAA001);
+    test_physical_device_0.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_1 = env.get_test_icd(0).add_and_get_physical_device({"pd1"});
+    FillInRandomDeviceProps(test_physical_device_1.properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, VK_API_VERSION_1_0, 888,
+                            0xAAA002);
+    test_physical_device_1.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     env.get_test_icd(1).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(1).physical_devices.push_back({"pd2"});
-    FillInRandomDeviceProps(env.get_test_icd(1).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_0,
-                            1, 0xBBBB001);
-    env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_2 = env.get_test_icd(1).add_and_get_physical_device({"pd2"});
+    FillInRandomDeviceProps(test_physical_device_2.properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_0, 1, 0xBBBB001);
+    test_physical_device_2.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     env.get_test_icd(2).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(2).physical_devices.push_back({"pd3"});
-    FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
-                            VK_API_VERSION_1_0, 75, 0xCCCC001);
-    env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    env.get_test_icd(2).physical_devices.push_back({"pd4"});
-    FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
-                            VK_API_VERSION_1_0, 75, 0xCCCC002);
-    env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_3 = env.get_test_icd(2).add_and_get_physical_device({"pd3"});
+    FillInRandomDeviceProps(test_physical_device_3.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_0, 75,
+                            0xCCCC001);
+    test_physical_device_3.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_4 = env.get_test_icd(2).add_and_get_physical_device({"pd4"});
+    FillInRandomDeviceProps(test_physical_device_4.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_0, 75,
+                            0xCCCC002);
+    test_physical_device_4.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     env.get_test_icd(3).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
-    env.get_test_icd(3).physical_devices.push_back({"pd5"});
-    FillInRandomDeviceProps(env.get_test_icd(3).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU,
-                            VK_API_VERSION_1_0, 6940, 0xDDDD001);
-    env.get_test_icd(3).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    auto& test_physical_device_5 = env.get_test_icd(3).add_and_get_physical_device({"pd5"});
+    FillInRandomDeviceProps(test_physical_device_5.properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, VK_API_VERSION_1_0, 6940,
+                            0xDDDD001);
+    test_physical_device_5.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
 
     InstWrapper instance(env.vulkan_functions);
     instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
@@ -3251,71 +3712,66 @@
     //   Group 1: PhysDev 4
     // ICD 3: Vulkan 1.1
     //   PhysDev 7: pd7, Virtual, Vulkan 1.1, Bus 0
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     auto& cur_icd_0 = env.get_test_icd(0);
     cur_icd_0.set_icd_api_version(VK_API_VERSION_1_1);
-    cur_icd_0.physical_devices.push_back({"pd0"});
-    cur_icd_0.physical_devices.back().set_pci_bus(7);
-    cur_icd_0.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_0.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            888, 0xAAA001);
-    cur_icd_0.physical_devices.push_back({"pd1"});
-    cur_icd_0.physical_devices.back().set_pci_bus(3);
-    cur_icd_0.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_0.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
-                            VK_API_VERSION_1_1, 888, 0xAAA002);
-    cur_icd_0.physical_devices.push_back({"pd2"});
-    cur_icd_0.physical_devices.back().set_pci_bus(6);
-    cur_icd_0.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_0.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            888, 0xAAA003);
+    auto& test_physical_device_0 = cur_icd_0.add_and_get_physical_device({"pd0"});
+    test_physical_device_0.set_pci_bus(7);
+    test_physical_device_0.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_0.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA001);
+    auto& test_physical_device_1 = cur_icd_0.add_and_get_physical_device({"pd1"});
+    test_physical_device_1.set_pci_bus(3);
+    test_physical_device_1.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_1.properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA002);
+    auto& test_physical_device_2 = cur_icd_0.add_and_get_physical_device({"pd2"});
+    test_physical_device_2.set_pci_bus(6);
+    test_physical_device_2.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_2.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA003);
     cur_icd_0.physical_device_groups.push_back({});
-    cur_icd_0.physical_device_groups.back()
-        .use_physical_device(cur_icd_0.physical_devices[0])
-        .use_physical_device(cur_icd_0.physical_devices[2]);
-    cur_icd_0.physical_device_groups.push_back({cur_icd_0.physical_devices[1]});
+    cur_icd_0.physical_device_groups.back().use_physical_device(test_physical_device_0).use_physical_device(test_physical_device_2);
+    cur_icd_0.physical_device_groups.push_back({test_physical_device_1});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     auto& cur_icd_1 = env.get_test_icd(1);
     cur_icd_1.set_icd_api_version(VK_API_VERSION_1_1);
-    cur_icd_1.physical_devices.push_back({"pd3"});
-    cur_icd_1.physical_devices.back().set_pci_bus(0);
-    cur_icd_1.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_1.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_1, 1,
-                            0xBBBB001);
+    auto& test_physical_device_3 = cur_icd_1.add_and_get_physical_device({"pd3"});
+    test_physical_device_3.set_pci_bus(0);
+    test_physical_device_3.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_3.properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_1, 1, 0xBBBB001);
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     auto& cur_icd_2 = env.get_test_icd(2);
     cur_icd_2.set_icd_api_version(VK_API_VERSION_1_1);
-    cur_icd_2.physical_devices.push_back({"pd4"});
-    cur_icd_2.physical_devices.back().set_pci_bus(1);
-    cur_icd_2.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_2.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            75, 0xCCCC001);
-    cur_icd_2.physical_devices.push_back({"pd5"});
-    cur_icd_2.physical_devices.back().set_pci_bus(4);
-    cur_icd_2.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_2.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            75, 0xCCCC002);
-    cur_icd_2.physical_devices.push_back({"pd6"});
-    cur_icd_2.physical_devices.back().set_pci_bus(2);
-    cur_icd_2.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_2.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            75, 0xCCCC003);
+    auto& test_physical_device_4 = cur_icd_2.add_and_get_physical_device({"pd4"});
+    test_physical_device_4.set_pci_bus(1);
+    test_physical_device_4.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_4.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC001);
+    auto& test_physical_device_5 = cur_icd_2.add_and_get_physical_device({"pd5"});
+    test_physical_device_5.set_pci_bus(4);
+    test_physical_device_5.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_5.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC002);
+    auto& test_physical_device_6 = cur_icd_2.add_and_get_physical_device({"pd6"});
+    test_physical_device_6.set_pci_bus(2);
+    test_physical_device_6.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_6.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC003);
     cur_icd_2.physical_device_groups.push_back({});
-    cur_icd_2.physical_device_groups.back()
-        .use_physical_device(cur_icd_2.physical_devices[1])
-        .use_physical_device(cur_icd_2.physical_devices[2]);
-    cur_icd_2.physical_device_groups.push_back({cur_icd_2.physical_devices[0]});
+    cur_icd_2.physical_device_groups.back().use_physical_device(test_physical_device_5).use_physical_device(test_physical_device_6);
+    cur_icd_2.physical_device_groups.push_back({test_physical_device_4});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     auto& cur_icd_3 = env.get_test_icd(3);
     cur_icd_3.set_icd_api_version(VK_API_VERSION_1_1);
-    cur_icd_3.physical_devices.push_back({"pd7"});
-    cur_icd_3.physical_devices.back().set_pci_bus(0);
-    cur_icd_3.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_3.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, VK_API_VERSION_1_1,
-                            6940, 0xDDDD001);
+    auto& test_physical_device_7 = cur_icd_3.add_and_get_physical_device({"pd7"});
+    test_physical_device_7.set_pci_bus(0);
+    test_physical_device_7.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_7.properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, VK_API_VERSION_1_1, 6940,
+                            0xDDDD001);
 
     InstWrapper inst(env.vulkan_functions);
     inst.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -3444,63 +3900,58 @@
     //   Group 1: PhysDev 4
     // ICD 3: Vulkan 1.1
     //   PhysDev 7: pd7, Virtual, Vulkan 1.1, Bus 0
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     auto& cur_icd_0 = env.get_test_icd(0);
     cur_icd_0.set_icd_api_version(VK_API_VERSION_1_1);
-    cur_icd_0.physical_devices.push_back({"pd0"});
-    cur_icd_0.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_0.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            888, 0xAAA001);
-    cur_icd_0.physical_devices.push_back({"pd1"});
-    cur_icd_0.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_0.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
-                            VK_API_VERSION_1_1, 888, 0xAAA002);
-    cur_icd_0.physical_devices.push_back({"pd2"});
-    cur_icd_0.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_0.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            888, 0xAAA003);
+    auto& test_physical_device_0 = cur_icd_0.add_and_get_physical_device({"pd0"});
+    test_physical_device_0.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_0.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA001);
+    auto& test_physical_device_1 = cur_icd_0.add_and_get_physical_device({"pd1"});
+    test_physical_device_1.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_1.properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA002);
+    auto& test_physical_device_2 = cur_icd_0.add_and_get_physical_device({"pd2"});
+    test_physical_device_2.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_2.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 888,
+                            0xAAA003);
     cur_icd_0.physical_device_groups.push_back({});
-    cur_icd_0.physical_device_groups.back()
-        .use_physical_device(cur_icd_0.physical_devices[0])
-        .use_physical_device(cur_icd_0.physical_devices[2]);
-    cur_icd_0.physical_device_groups.push_back({cur_icd_0.physical_devices[1]});
+    cur_icd_0.physical_device_groups.back().use_physical_device(test_physical_device_0).use_physical_device(test_physical_device_2);
+    cur_icd_0.physical_device_groups.push_back({test_physical_device_1});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     auto& cur_icd_1 = env.get_test_icd(1);
     cur_icd_1.set_icd_api_version(VK_API_VERSION_1_1);
-    cur_icd_1.physical_devices.push_back({"pd3"});
-    cur_icd_1.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_1.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_1, 1,
-                            0xBBBB001);
+    auto& test_physical_device_3 = cur_icd_1.add_and_get_physical_device({"pd3"});
+    test_physical_device_3.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_3.properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_1, 1, 0xBBBB001);
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     auto& cur_icd_2 = env.get_test_icd(2);
     cur_icd_2.set_icd_api_version(VK_API_VERSION_1_1);
-    cur_icd_2.physical_devices.push_back({"pd4"});
-    cur_icd_2.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_2.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            75, 0xCCCC001);
-    cur_icd_2.physical_devices.push_back({"pd5"});
-    cur_icd_2.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_2.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            75, 0xCCCC002);
-    cur_icd_2.physical_devices.push_back({"pd6"});
-    cur_icd_2.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_2.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1,
-                            75, 0xCCCC003);
+    auto& test_physical_device_4 = cur_icd_2.add_and_get_physical_device({"pd4"});
+    test_physical_device_4.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_4.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC001);
+    auto& test_physical_device_5 = cur_icd_2.add_and_get_physical_device({"pd5"});
+    test_physical_device_5.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_5.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC002);
+    auto& test_physical_device_6 = cur_icd_2.add_and_get_physical_device({"pd6"});
+    test_physical_device_6.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_6.properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_API_VERSION_1_1, 75,
+                            0xCCCC003);
     cur_icd_2.physical_device_groups.push_back({});
-    cur_icd_2.physical_device_groups.back()
-        .use_physical_device(cur_icd_2.physical_devices[1])
-        .use_physical_device(cur_icd_2.physical_devices[2]);
-    cur_icd_2.physical_device_groups.push_back({cur_icd_2.physical_devices[0]});
+    cur_icd_2.physical_device_groups.back().use_physical_device(test_physical_device_5).use_physical_device(test_physical_device_6);
+    cur_icd_2.physical_device_groups.push_back({test_physical_device_4});
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
     auto& cur_icd_3 = env.get_test_icd(3);
     cur_icd_3.set_icd_api_version(VK_API_VERSION_1_1);
-    cur_icd_3.physical_devices.push_back({"pd7"});
-    cur_icd_3.physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
-    FillInRandomDeviceProps(cur_icd_3.physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, VK_API_VERSION_1_1,
-                            6940, 0xDDDD001);
+    auto& test_physical_device_7 = cur_icd_3.add_and_get_physical_device({"pd7"});
+    test_physical_device_7.extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
+    FillInRandomDeviceProps(test_physical_device_7.properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, VK_API_VERSION_1_1, 6940,
+                            0xDDDD001);
 
     InstWrapper inst(env.vulkan_functions);
     inst.create_info.set_api_version(VK_API_VERSION_1_1);
@@ -3594,8 +4045,7 @@
 
 TEST(PortabilityICDConfiguration, PortabilityICDOnly) {
     FrameworkEnvironment env{};
-    env.add_icd(
-           TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_is_portability_driver(true)))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_is_portability_driver(true))
         .add_physical_device("physical_device_0")
         .set_max_icd_interface_version(1);
     {  // enable portability extension and flag
@@ -3647,17 +4097,16 @@
 
 TEST(PortabilityICDConfiguration, PortabilityAndRegularICD) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)));
-    env.add_icd(
-        TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_is_portability_driver(true)));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_is_portability_driver(true));
 
     auto& driver0 = env.get_test_icd(0);
     auto& driver1 = env.get_test_icd(1);
 
-    driver0.physical_devices.emplace_back("physical_device_0");
+    driver0.add_and_get_physical_device("physical_device_0");
     driver0.max_icd_interface_version = 1;
 
-    driver1.physical_devices.emplace_back("portability_physical_device_1");
+    driver1.add_and_get_physical_device("portability_physical_device_1");
     driver1.max_icd_interface_version = 1;
     {  // enable portability extension and flag
         InstWrapper inst{env.vulkan_functions};
@@ -3729,16 +4178,16 @@
 // Check that the portability enumeration flag bit doesn't get passed down
 TEST(PortabilityICDConfiguration, PortabilityAndRegularICDCheckFlagsPassedIntoICD) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2)));
-    env.add_icd(TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2).set_is_portability_driver(true)));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_is_portability_driver(true));
 
     auto& driver0 = env.get_test_icd(0);
     auto& driver1 = env.get_test_icd(1);
 
-    driver0.physical_devices.emplace_back("physical_device_0");
+    driver0.add_and_get_physical_device("physical_device_0");
     driver0.max_icd_interface_version = 1;
 
-    driver1.physical_devices.emplace_back("portability_physical_device_1");
+    driver1.add_and_get_physical_device("portability_physical_device_1");
     driver1.add_instance_extension("VK_KHR_portability_enumeration");
     driver1.max_icd_interface_version = 1;
 
@@ -3760,12 +4209,11 @@
     FrameworkEnvironment env{};
     Extension first_ext{"VK_EXT_validation_features"};  // known instance extensions
     Extension second_ext{"VK_EXT_headless_surface"};
-    env.add_icd(TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)
         .add_physical_device("physical_device_0")
         .set_max_icd_interface_version(1)
         .add_instance_extensions({first_ext, second_ext});
-    env.add_icd(
-           TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_is_portability_driver(true)))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_is_portability_driver(true))
         .add_physical_device("portability_physical_device_1")
         .set_max_icd_interface_version(1);
     {
@@ -3781,9 +4229,8 @@
 
     const char* layer_name = "TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.add_layer(layer_name);
@@ -3805,7 +4252,7 @@
 #if defined(_WIN32)
 TEST(AppPackageDiscovery, AppPackageDrivers) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2}.set_discovery_type(ManifestDiscoveryType::windows_app_package))
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::windows_app_package))
         .add_physical_device({});
 
     InstWrapper inst{env.vulkan_functions};
@@ -3813,27 +4260,41 @@
 }
 TEST(AppPackageDiscovery, AppPackageLayers) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2)));
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
-    const char* layer_name = "test_package_layer";
-    env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(layer_name)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("DISABLE_ME")),
-                                            "test_package_layer.json")
-                               .set_discovery_type(ManifestDiscoveryType::windows_app_package));
+    const char* layer_name = "VK_LAYER_test_package_layer";
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::windows_app_package),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("DISABLE_ME")));
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
 
-    {
-        VkLayerProperties layer_props{};
-        uint32_t layer_count = 0;
-        ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, NULL));
-        ASSERT_EQ(layer_count, 1);
-        ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, &layer_props));
-        ASSERT_TRUE(string_eq(layer_name, layer_props.layerName));
-    }
+    auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1U);
+    ASSERT_EQ(layers.size(), 1);
+    ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name));
+}
+
+TEST(AppPackageDiscovery, AppPackageICDAndLayers) {
+    FrameworkEnvironment env{};
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::windows_app_package))
+        .add_physical_device({});
+
+    const char* layer_name = "VK_LAYER_test_package_layer";
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::windows_app_package),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_name(layer_name)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                         .set_disable_environment("DISABLE_ME")));
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+
+    auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1U);
+    ASSERT_EQ(layers.size(), 1);
+    ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name));
 }
 
 // Make sure that stale layer manifests (path to nonexistant file) which have the same name as real manifests don't cause the real
@@ -3841,17 +4302,16 @@
 // when the corresponding manifest is removed from the file system.
 TEST(DuplicateRegistryEntries, Layers) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2)));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     auto null_path = env.get_folder(ManifestLocation::null).location() / "test_layer.json";
 
-    env.platform_shim->add_manifest(ManifestCategory::explicit_layer, null_path);
+    env.platform_shim->add_manifest_to_registry(ManifestCategory::explicit_layer, null_path);
 
     const char* layer_name = "TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.add_layer(layer_name);
@@ -3863,9 +4323,9 @@
 TEST(DuplicateRegistryEntries, Drivers) {
     FrameworkEnvironment env{};
     auto null_path = env.get_folder(ManifestLocation::null).location() / "test_icd_0.json";
-    env.platform_shim->add_manifest(ManifestCategory::icd, null_path);
+    env.platform_shim->add_manifest_to_registry(ManifestCategory::icd, null_path);
 
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA}.set_discovery_type(ManifestDiscoveryType::null_dir))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::null_dir))
         .add_physical_device("physical_device_0")
         .set_adapterLUID(_LUID{10, 1000});
     env.platform_shim->add_d3dkmt_adapter(D3DKMT_Adapter{0, _LUID{10, 1000}}.add_driver_manifest_path(env.get_icd_manifest_path()));
@@ -3881,20 +4341,18 @@
 
 TEST(LibraryLoading, SystemLocations) {
     FrameworkEnvironment env{};
-    EnvVarWrapper ld_library_path("LD_LIBRARY_PATH", env.get_folder(ManifestLocation::driver).location().string());
-    ld_library_path.add_to_list(env.get_folder(ManifestLocation::explicit_layer).location());
 
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).set_library_path_type(LibraryPathType::default_search_paths))
-                       .add_physical_device({});
+    auto& test_physical_device =
+        env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_library_path_type(LibraryPathType::default_search_paths))
+            .add_and_get_physical_device({});
     const char* fake_ext_name = "VK_FAKE_extension";
-    driver.physical_devices.back().add_extension(fake_ext_name);
+    test_physical_device.add_extension(fake_ext_name);
 
     const char* layer_name = "TestLayer";
     env.add_explicit_layer(
-        TestLayerDetails{ManifestLayer{}.add_layer(
-                             ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                         "test_layer.json"}
-            .set_library_path_type(LibraryPathType::default_search_paths));
+        ManifestOptions{}.set_library_path_type(LibraryPathType::default_search_paths),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     auto props = env.GetLayerProperties(1);
     ASSERT_TRUE(string_eq(props.at(0).layerName, layer_name));
@@ -3914,18 +4372,14 @@
 }
 
 #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-// Check that valid symlinks do not cause the loader to crash when directly in an XDG env-var
-TEST(ManifestDiscovery, ValidSymlinkInXDGEnvVar) {
-    FrameworkEnvironment env{FrameworkSettings{}.set_enable_default_search_paths(false)};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::override_folder))
+// Check that valid symlinks do not cause the loader to crash when found in an unsecure location
+TEST(ManifestDiscovery, ValidSymlinkInUnsecureLocation) {
+    FrameworkEnvironment env;
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA,
+                ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder))
         .add_physical_device({});
-    auto driver_path = env.get_icd_manifest_path(0);
-    std::string symlink_name = "symlink_to_driver.json";
-    std::filesystem::path symlink_path = env.get_folder(ManifestLocation::driver_env_var).location() / symlink_name;
-    env.get_folder(ManifestLocation::driver_env_var).add_existing_file(symlink_name);
-    int res = symlink(driver_path.c_str(), symlink_path.c_str());
-    ASSERT_EQ(res, 0);
-    EnvVarWrapper xdg_config_dirs_env_var{"XDG_CONFIG_DIRS", symlink_path};
+
+    env.add_symlink(ManifestLocation::unsecured_driver, env.get_icd_manifest_path(0), "symlink_to_driver.json");
 
     InstWrapper inst{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
@@ -3934,35 +4388,24 @@
 
 // Check that valid symlinks do not cause the loader to crash
 TEST(ManifestDiscovery, ValidSymlink) {
-    FrameworkEnvironment env{FrameworkSettings{}.set_enable_default_search_paths(false)};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::override_folder))
+    FrameworkEnvironment env{FrameworkSettings{}};
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA,
+                ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder))
         .add_physical_device({});
 
-    auto driver_path = env.get_icd_manifest_path(0);
-    std::string symlink_name = "symlink_to_driver.json";
-    std::filesystem::path symlink_path = env.get_folder(ManifestLocation::driver_env_var).location() / symlink_name;
-    env.get_folder(ManifestLocation::driver_env_var).add_existing_file(symlink_name);
-    int res = symlink(driver_path.c_str(), symlink_path.c_str());
-    ASSERT_EQ(res, 0);
-
-    env.platform_shim->set_fake_path(ManifestCategory::icd, env.get_folder(ManifestLocation::driver_env_var).location());
+    env.add_symlink(ManifestLocation::driver, env.get_icd_manifest_path(0), "symlink_to_driver.json");
 
     InstWrapper inst{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
     inst.CheckCreate();
 }
 
-// Check that invalid symlinks do not cause the loader to crash when directly in an XDG env-var
-TEST(ManifestDiscovery, InvalidSymlinkXDGEnvVar) {
-    FrameworkEnvironment env{FrameworkSettings{}.set_enable_default_search_paths(false)};
-    std::string symlink_name = "symlink_to_nothing.json";
-    std::filesystem::path symlink_path = env.get_folder(ManifestLocation::driver_env_var).location() / symlink_name;
-    std::filesystem::path invalid_driver_path = env.get_folder(ManifestLocation::driver).location() / "nothing_here.json";
-    int res = symlink(invalid_driver_path.c_str(), symlink_path.c_str());
-    ASSERT_EQ(res, 0);
-    env.get_folder(ManifestLocation::driver_env_var).add_existing_file(symlink_name);
+// Check that invalid symlinks do not cause the loader to crash when found in an unsecure location
+TEST(ManifestDiscovery, InvalidSymlinkInUnsecureLocation) {
+    FrameworkEnvironment env;
 
-    EnvVarWrapper xdg_config_dirs_env_var{symlink_path};
+    env.add_symlink(ManifestLocation::unsecured_driver, env.get_folder(ManifestLocation::driver).location() / "nothing_here.json",
+                    "symlink_to_nothing.json");
 
     InstWrapper inst{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
@@ -3971,15 +4414,10 @@
 
 // Check that invalid symlinks do not cause the loader to crash
 TEST(ManifestDiscovery, InvalidSymlink) {
-    FrameworkEnvironment env{FrameworkSettings{}.set_enable_default_search_paths(false)};
-    std::string symlink_name = "symlink_to_nothing.json";
-    std::filesystem::path symlink_path = env.get_folder(ManifestLocation::driver).location() / symlink_name;
-    std::filesystem::path invalid_driver_path = env.get_folder(ManifestLocation::driver_env_var).location() / "nothing_here.json";
-    int res = symlink(invalid_driver_path.c_str(), symlink_path.c_str());
-    ASSERT_EQ(res, 0);
-    env.get_folder(ManifestLocation::driver).add_existing_file(symlink_name);
+    FrameworkEnvironment env;
 
-    env.platform_shim->set_fake_path(ManifestCategory::icd, env.get_folder(ManifestLocation::driver_env_var).location());
+    env.add_symlink(ManifestLocation::driver, env.get_folder(ManifestLocation::driver).location() / "nothing_here.json",
+                    "symlink_to_nothing.json");
 
     InstWrapper inst{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
@@ -3992,34 +4430,40 @@
 TEST(ManifestDiscovery, AppleBundles) {
     FrameworkEnvironment env{};
     env.setup_macos_bundle();
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::macos_bundle));
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.at(0).properties.deviceID = 1337;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    env.get_test_icd(1).physical_devices.push_back({});
-    env.get_test_icd(1).physical_devices.at(0).properties.deviceID = 9999;
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA,
+                ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::macos_bundle));
+    auto& test_physical_device_0 = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device_0.properties.deviceID = 1337;
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    auto& test_physical_device_1 = env.get_test_icd(1).add_and_get_physical_device({});
+    test_physical_device_1.properties.deviceID = 9999;
 
     InstWrapper inst{env.vulkan_functions};
     ASSERT_NO_FATAL_FAILURE(inst.CheckCreate());
     auto physical_devices = inst.GetPhysDevs();
-    ASSERT_EQ(1, physical_devices.size());
+    ASSERT_EQ(2, physical_devices.size());
 
-    // Verify that this is the 'right' GPU, aka the one from the bundle
+    // Should get both GPUs, in reverse order to driver enumeration (due to enumerating the last driver first)
     VkPhysicalDeviceProperties props{};
     inst->vkGetPhysicalDeviceProperties(physical_devices[0], &props);
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.at(0).properties.deviceID, props.deviceID);
+    ASSERT_EQ(test_physical_device_1.properties.deviceID, props.deviceID);
+    inst->vkGetPhysicalDeviceProperties(physical_devices[1], &props);
+    ASSERT_EQ(test_physical_device_0.properties.deviceID, props.deviceID);
 }
 
 // Add two drivers, one to the bundle and one using the driver env-var
 TEST(ManifestDiscovery, AppleBundlesEnvVarActive) {
     FrameworkEnvironment env{};
     env.setup_macos_bundle();
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::macos_bundle));
-    env.get_test_icd(0).physical_devices.push_back({});
-    env.get_test_icd(0).physical_devices.at(0).properties.deviceID = 1337;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::env_var));
-    env.get_test_icd(1).physical_devices.push_back({});
-    env.get_test_icd(1).physical_devices.at(0).properties.deviceID = 9999;
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA,
+                ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::macos_bundle));
+
+    auto& test_physical_device_0 = env.get_test_icd(0).add_and_get_physical_device({});
+    test_physical_device_0.properties.deviceID = 1337;
+
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var));
+    auto& test_physical_device_1 = env.get_test_icd(1).add_and_get_physical_device({});
+    test_physical_device_1.properties.deviceID = 9999;
 
     InstWrapper inst{env.vulkan_functions};
     ASSERT_NO_FATAL_FAILURE(inst.CheckCreate());
@@ -4029,27 +4473,25 @@
     // Verify that this is the 'right' GPU, aka the one from the env-var
     VkPhysicalDeviceProperties props{};
     inst->vkGetPhysicalDeviceProperties(physical_devices[0], &props);
-    ASSERT_EQ(env.get_test_icd(1).physical_devices.at(0).properties.deviceID, props.deviceID);
+    ASSERT_EQ(test_physical_device_1.properties.deviceID, props.deviceID);
 }
 #endif
 
 TEST(LayerCreatesDevice, Basic) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     env.get_test_layer().set_call_create_device_while_create_device_is_called(true);
     env.get_test_layer().set_physical_device_index_to_use_during_create_device(0);
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name2")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_test_layer2.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name2")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -4060,24 +4502,20 @@
 
 TEST(LayerCreatesDevice, DifferentPhysicalDevice) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
-    env.get_test_icd(0).physical_devices.emplace_back("Device0");
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
-    env.get_test_icd(1).physical_devices.emplace_back("Device1");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("Device0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("Device1");
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     env.get_test_layer().set_call_create_device_while_create_device_is_called(true);
     env.get_test_layer().set_physical_device_index_to_use_during_create_device(1);
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name2")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_test_layer2.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name2")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -4090,13 +4528,12 @@
 
 TEST(Layer, pfnNextGetInstanceProcAddr_should_not_return_layers_own_functions) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     env.get_test_layer(0).set_check_if_EnumDevExtProps_is_same_as_queried_function(true);
 
     InstWrapper inst{env.vulkan_functions};
@@ -4110,13 +4547,12 @@
 
 TEST(Layer, LLP_LAYER_21) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     env.get_test_layer(0).set_clobber_pInstance(true);
 
     InstWrapper inst{env.vulkan_functions};
@@ -4146,13 +4582,12 @@
 
 TEST(Layer, LLP_LAYER_22) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("implicit_layer_name")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("implicit_layer_name")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     env.get_test_layer(0).set_clobber_pDevice(true);
 
     InstWrapper inst{env.vulkan_functions};
@@ -4188,7 +4623,7 @@
 
 TEST(InvalidManifest, ICD) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     std::vector<std::string> invalid_jsons;
     invalid_jsons.push_back(",");
@@ -4203,7 +4638,9 @@
     for (size_t i = 0; i < invalid_jsons.size(); i++) {
         auto file_name = std::string("invalid_driver_") + std::to_string(i) + ".json";
         std::filesystem::path new_path = env.get_folder(ManifestLocation::driver).write_manifest(file_name, invalid_jsons[i]);
-        env.platform_shim->add_manifest(ManifestCategory::icd, new_path);
+#if defined(WIN32)
+        env.platform_shim->add_manifest_to_registry(ManifestCategory::icd, new_path);
+#endif
     }
 
     InstWrapper inst{env.vulkan_functions};
@@ -4212,7 +4649,7 @@
 
 TEST(InvalidManifest, Layer) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     std::vector<std::string> invalid_jsons;
     invalid_jsons.push_back(",");
@@ -4228,21 +4665,22 @@
         auto file_name = std::string("invalid_implicit_layer_") + std::to_string(i) + ".json";
         std::filesystem::path new_path =
             env.get_folder(ManifestLocation::implicit_layer).write_manifest(file_name, invalid_jsons[i]);
-        env.platform_shim->add_manifest(ManifestCategory::implicit_layer, new_path);
+#if defined(WIN32)
+        env.platform_shim->add_manifest_to_registry(ManifestCategory::implicit_layer, new_path);
+#endif
     }
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
 }
 #if defined(WIN32)
-void add_dxgi_adapter(FrameworkEnvironment& env, std::filesystem::path const& name, LUID luid, uint32_t vendor_id) {
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6).set_discovery_type(ManifestDiscoveryType::null_dir));
+VkPhysicalDevice add_dxgi_adapter(FrameworkEnvironment& env, std::filesystem::path const& name, LUID luid, uint32_t vendor_id) {
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_6, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::null_dir));
     driver.set_min_icd_interface_version(5);
     driver.set_max_icd_interface_version(6);
     driver.setup_WSI();
     driver.set_icd_api_version(VK_API_VERSION_1_1);
-    driver.physical_devices.emplace_back(name.string());
-    auto& pd0 = driver.physical_devices.back();
+    auto& pd0 = driver.add_and_get_physical_device(name.string());
     pd0.properties.apiVersion = VK_API_VERSION_1_1;
     driver.set_adapterLUID(luid);
 
@@ -4269,6 +4707,7 @@
     } else {
         pAdapter->add_driver_manifest_path(env.get_icd_manifest_path(env.icds.size() - 1));
     }
+    return pd0.vk_physical_device.handle;
 }
 
 TEST(EnumerateAdapterPhysicalDevices, SameAdapterLUID_reordered) {
@@ -4281,7 +4720,7 @@
     // b) then in the reverse order to the drivers insertion into the test framework
     add_dxgi_adapter(env, "physical_device_2", LUID{10, 100}, 2);
     add_dxgi_adapter(env, "physical_device_1", LUID{20, 200}, 1);
-    add_dxgi_adapter(env, "physical_device_0", LUID{10, 100}, 2);
+    auto phys_dev_handle = add_dxgi_adapter(env, "physical_device_0", LUID{10, 100}, 2);
 
     {
         uint32_t returned_physical_count = 0;
@@ -4325,7 +4764,8 @@
     }
     // Set the first physical device that is enumerated to be a 'layered' driver so it should be swapped with the first physical
     // device
-    env.get_test_icd(2).physical_devices.back().layered_driver_underlying_api = VK_LAYERED_DRIVER_UNDERLYING_API_D3D12_MSFT;
+    env.get_test_icd(2).physical_devices.at(phys_dev_handle).layered_driver_underlying_api =
+        VK_LAYERED_DRIVER_UNDERLYING_API_D3D12_MSFT;
     {
         uint32_t returned_physical_count = 0;
         InstWrapper inst{env.vulkan_functions};
@@ -4377,12 +4817,13 @@
     // Physical devices are enumerated:
     // a) first in the order of LUIDs showing up in DXGIAdapter list
     // b) then in the reverse order to the drivers insertion into the test framework
-    add_dxgi_adapter(env, "physical_device_2", LUID{10, 100}, 2);
+    auto d3d12_physical_device = add_dxgi_adapter(env, "physical_device_2", LUID{10, 100}, 2);
     add_dxgi_adapter(env, "physical_device_1", LUID{20, 200}, 1);
     add_dxgi_adapter(env, "physical_device_0", LUID{10, 100}, 2);
 
-    // Set the last physical device that is enumerated last to be a 'layered'  physical device - no swapping should occur
-    env.get_test_icd(0).physical_devices.back().layered_driver_underlying_api = VK_LAYERED_DRIVER_UNDERLYING_API_D3D12_MSFT;
+    // Set the physical device that is enumerated last to be a 'layered'  physical device - no swapping should occur
+    env.get_test_icd(0).physical_devices.at(d3d12_physical_device).layered_driver_underlying_api =
+        VK_LAYERED_DRIVER_UNDERLYING_API_D3D12_MSFT;
 
     uint32_t returned_physical_count = 0;
     InstWrapper inst{env.vulkan_functions};
@@ -4537,7 +4978,7 @@
 }
 
 void add_driver_for_unloading_testing(FrameworkEnvironment& env) {
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
         .add_instance_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)
         .setup_WSI()
         .add_physical_device(PhysicalDevice{}
@@ -4547,7 +4988,7 @@
 }
 
 void add_empty_driver_for_unloading_testing(FrameworkEnvironment& env) {
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_instance_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME).setup_WSI();
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_instance_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME).setup_WSI();
 }
 
 TEST(DriverUnloadingFromZeroPhysDevs, InterspersedThroughout) {
@@ -4578,15 +5019,16 @@
     VkDebugReportCallbackCreateInfoEXT debug_report_create_info{};
     ASSERT_EQ(VK_SUCCESS, create_debug_callback(inst, debug_report_create_info, debug_callback));
     WrappedHandle<VkDebugReportCallbackEXT, VkInstance, PFN_vkDestroyDebugReportCallbackEXT>
-        pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst, env.vulkan_functions.vkDestroyDebugReportCallbackEXT};
+        pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst,
+                                                 inst.instance_functions.vkDestroyDebugReportCallbackEXT};
 
     auto phys_devs = inst.GetPhysDevs();
     std::vector<WrappedHandle<VkDebugUtilsMessengerEXT, VkInstance, PFN_vkDestroyDebugUtilsMessengerEXT>> messengers;
     std::vector<WrappedHandle<VkSurfaceKHR, VkInstance, PFN_vkDestroySurfaceKHR>> surfaces;
     for (uint32_t i = 0; i < 35; i++) {
         VkDebugUtilsMessengerEXT messenger;
-        ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger));
-        messengers.emplace_back(messenger, inst.inst, env.vulkan_functions.vkDestroyDebugUtilsMessengerEXT);
+        ASSERT_EQ(VK_SUCCESS, inst.instance_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger));
+        messengers.emplace_back(messenger, inst.inst, inst.instance_functions.vkDestroyDebugUtilsMessengerEXT);
 
         VkSurfaceKHR surface{};
         ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface));
@@ -4626,15 +5068,16 @@
     VkDebugReportCallbackCreateInfoEXT debug_report_create_info{};
     ASSERT_EQ(VK_SUCCESS, create_debug_callback(inst, debug_report_create_info, debug_callback));
     WrappedHandle<VkDebugReportCallbackEXT, VkInstance, PFN_vkDestroyDebugReportCallbackEXT>
-        pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst, env.vulkan_functions.vkDestroyDebugReportCallbackEXT};
+        pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst,
+                                                 inst.instance_functions.vkDestroyDebugReportCallbackEXT};
 
     auto phys_devs = inst.GetPhysDevs();
     std::vector<WrappedHandle<VkDebugUtilsMessengerEXT, VkInstance, PFN_vkDestroyDebugUtilsMessengerEXT>> messengers;
     std::vector<WrappedHandle<VkSurfaceKHR, VkInstance, PFN_vkDestroySurfaceKHR>> surfaces;
     for (uint32_t i = 0; i < 35; i++) {
         VkDebugUtilsMessengerEXT messenger;
-        ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger));
-        messengers.emplace_back(messenger, inst.inst, env.vulkan_functions.vkDestroyDebugUtilsMessengerEXT);
+        ASSERT_EQ(VK_SUCCESS, inst.instance_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger));
+        messengers.emplace_back(messenger, inst.inst, inst.instance_functions.vkDestroyDebugUtilsMessengerEXT);
 
         VkSurfaceKHR surface{};
         ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface));
@@ -4677,15 +5120,16 @@
     VkDebugReportCallbackCreateInfoEXT debug_report_create_info{};
     ASSERT_EQ(VK_SUCCESS, create_debug_callback(inst, debug_report_create_info, debug_callback));
     WrappedHandle<VkDebugReportCallbackEXT, VkInstance, PFN_vkDestroyDebugReportCallbackEXT>
-        pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst, env.vulkan_functions.vkDestroyDebugReportCallbackEXT};
+        pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst,
+                                                 inst.instance_functions.vkDestroyDebugReportCallbackEXT};
 
     auto phys_devs = inst.GetPhysDevs();
     std::vector<WrappedHandle<VkDebugUtilsMessengerEXT, VkInstance, PFN_vkDestroyDebugUtilsMessengerEXT>> messengers;
     std::vector<WrappedHandle<VkSurfaceKHR, VkInstance, PFN_vkDestroySurfaceKHR>> surfaces;
     for (uint32_t i = 0; i < 35; i++) {
         VkDebugUtilsMessengerEXT messenger;
-        ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger));
-        messengers.emplace_back(messenger, inst.inst, env.vulkan_functions.vkDestroyDebugUtilsMessengerEXT);
+        ASSERT_EQ(VK_SUCCESS, inst.instance_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger));
+        messengers.emplace_back(messenger, inst.inst, inst.instance_functions.vkDestroyDebugUtilsMessengerEXT);
 
         VkSurfaceKHR surface{};
         ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface));
@@ -4755,7 +5199,8 @@
     VkDebugReportCallbackCreateInfoEXT debug_report_create_info{};
     ASSERT_EQ(VK_SUCCESS, create_debug_callback(inst, debug_report_create_info, debug_callback));
     WrappedHandle<VkDebugReportCallbackEXT, VkInstance, PFN_vkDestroyDebugReportCallbackEXT>
-        pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst, env.vulkan_functions.vkDestroyDebugReportCallbackEXT};
+        pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst,
+                                                 inst.instance_functions.vkDestroyDebugReportCallbackEXT};
 
     // No physical devices == VK_ERROR_INITIALIZATION_FAILED
     inst.GetPhysDevs(VK_ERROR_INITIALIZATION_FAILED);
@@ -4764,8 +5209,8 @@
     std::vector<WrappedHandle<VkSurfaceKHR, VkInstance, PFN_vkDestroySurfaceKHR>> surfaces;
     for (uint32_t i = 0; i < 35; i++) {
         VkDebugUtilsMessengerEXT messenger;
-        ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger));
-        messengers.emplace_back(messenger, inst.inst, env.vulkan_functions.vkDestroyDebugUtilsMessengerEXT);
+        ASSERT_EQ(VK_SUCCESS, inst.instance_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger));
+        messengers.emplace_back(messenger, inst.inst, inst.instance_functions.vkDestroyDebugUtilsMessengerEXT);
 
         VkSurfaceKHR surface{};
         ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface));
@@ -4801,22 +5246,23 @@
     VkDebugReportCallbackCreateInfoEXT debug_report_create_info{};
     ASSERT_EQ(VK_SUCCESS, create_debug_callback(inst, debug_report_create_info, debug_callback));
     WrappedHandle<VkDebugReportCallbackEXT, VkInstance, PFN_vkDestroyDebugReportCallbackEXT>
-        pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst, env.vulkan_functions.vkDestroyDebugReportCallbackEXT};
+        pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst,
+                                                 inst.instance_functions.vkDestroyDebugReportCallbackEXT};
 
     auto phys_devs = inst.GetPhysDevs();
     std::vector<WrappedHandle<VkDebugUtilsMessengerEXT, VkInstance, PFN_vkDestroyDebugUtilsMessengerEXT>> messengers;
     std::vector<WrappedHandle<VkSurfaceKHR, VkInstance, PFN_vkDestroySurfaceKHR>> surfaces;
     for (uint32_t i = 0; i < 35; i++) {
         VkDebugUtilsMessengerEXT messenger;
-        ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger));
-        messengers.emplace_back(messenger, inst.inst, env.vulkan_functions.vkDestroyDebugUtilsMessengerEXT);
+        ASSERT_EQ(VK_SUCCESS, inst.instance_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger));
+        messengers.emplace_back(messenger, inst.inst, inst.instance_functions.vkDestroyDebugUtilsMessengerEXT);
 
         VkSurfaceKHR surface{};
         ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface));
         surfaces.emplace_back(surface, inst.inst, env.vulkan_functions.vkDestroySurfaceKHR);
     }
     // Remove some elements arbitrarily - remove 15 of each
-    // Do it backwards so the indexes are 'corect'
+    // Do it backwards so the indexes are 'correct'
     for (uint32_t i = 31; i > 2; i -= 2) {
         messengers.erase(messengers.begin() + i);
         surfaces.erase(surfaces.begin() + i);
@@ -4824,8 +5270,8 @@
     // Add in another 100
     for (uint32_t i = 0; i < 100; i++) {
         VkDebugUtilsMessengerEXT messenger;
-        ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger));
-        messengers.emplace_back(messenger, inst.inst, env.vulkan_functions.vkDestroyDebugUtilsMessengerEXT);
+        ASSERT_EQ(VK_SUCCESS, inst.instance_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger));
+        messengers.emplace_back(messenger, inst.inst, inst.instance_functions.vkDestroyDebugUtilsMessengerEXT);
 
         VkSurfaceKHR surface{};
         ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface));
diff --git a/tests/loader_settings_tests.cpp b/tests/loader_settings_tests.cpp
index 1c77c70..1c7f5ef 100644
--- a/tests/loader_settings_tests.cpp
+++ b/tests/loader_settings_tests.cpp
@@ -29,16 +29,32 @@
 
 #include <fstream>
 
-std::string get_settings_location_log_message([[maybe_unused]] FrameworkEnvironment const& env,
-                                              [[maybe_unused]] bool use_secure = false) {
+#include "util/get_executable_path.h"
+#include "util/json_writer.h"
+#include "util/test_defines.h"
+
+std::string get_settings_location_log_message([[maybe_unused]] FrameworkEnvironment const& env, bool use_secure = true) {
     std::string s = "Using layer configurations found in loader settings from ";
 #if defined(WIN32)
-    return s + (env.get_folder(ManifestLocation::settings_location).location() / "vk_loader_settings.json").string();
-#elif COMMON_UNIX_PLATFORMS
-    if (use_secure)
-        return s + "/etc/vulkan/loader_settings.d/vk_loader_settings.json";
-    else
-        return s + "/home/fake_home/.local/share/vulkan/loader_settings.d/vk_loader_settings.json";
+    ManifestLocation settings_location = use_secure ? ManifestLocation::settings_location : ManifestLocation::unsecured_settings;
+    return s + (env.get_folder(settings_location).location() / "vk_loader_settings.json").string();
+#elif TESTING_COMMON_UNIX_PLATFORMS
+    return s + (use_secure ? env.secure_manifest_base_location : env.unsecure_manifest_base_location) +
+           "/" TESTING_VULKAN_DIR "/loader_settings.d/vk_loader_settings.json";
+#endif
+}
+std::string get_unsecure_settings_location_log_message(FrameworkEnvironment const& env) {
+    return get_settings_location_log_message(env, false);
+}
+
+std::string get_settings_not_in_use_log_message([[maybe_unused]] FrameworkEnvironment const& env, bool use_secure) {
+    std::string s = "vk_loader_settings.json file found at \"";
+#if defined(WIN32)
+    ManifestLocation settings_location = use_secure ? ManifestLocation::settings_location : ManifestLocation::unsecured_settings;
+    return s + (env.get_folder(settings_location).location() / "vk_loader_settings.json").string();
+#elif TESTING_COMMON_UNIX_PLATFORMS
+    return s + (use_secure ? env.secure_manifest_base_location : env.unsecure_manifest_base_location) +
+           "/" TESTING_VULKAN_DIR "/loader_settings.d/vk_loader_settings.json\" but did not contain any valid settings.";
 #endif
 }
 enum class LayerType {
@@ -49,24 +65,24 @@
 const char* add_layer_and_settings(FrameworkEnvironment& env, const char* layer_name, LayerType layer_type, const char* control) {
     if (layer_type == LayerType::imp) {
         env.add_implicit_layer(
+            ManifestOptions{}.set_json_name(std::string(layer_name) + std::to_string(env.layers.size()) + ".json"),
             ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                           .set_name(layer_name)
                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                          .set_disable_environment("BADGER" + std::to_string(env.layers.size()))),
-            std::string(layer_name) + std::to_string(env.layers.size()) + ".json");
+                                          .set_disable_environment("BADGER" + std::to_string(env.layers.size()))));
     } else if (layer_type == LayerType::imp_with_enable_env) {
         env.add_implicit_layer(
+            ManifestOptions{}.set_json_name(std::string(layer_name) + std::to_string(env.layers.size()) + ".json"),
             ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
                                           .set_name(layer_name)
                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                                           .set_disable_environment("BADGER" + std::to_string(env.layers.size()))
-                                          .set_enable_environment("MUSHROOM" + std::to_string(env.layers.size()))),
-            std::string(layer_name) + std::to_string(env.layers.size()) + ".json");
+                                          .set_enable_environment("MUSHROOM" + std::to_string(env.layers.size()))));
     } else if (layer_type == LayerType::exp) {
-        env.add_explicit_layer(TestLayerDetails{
+        env.add_explicit_layer(
+            ManifestOptions{}.set_json_name(std::string(layer_name) + std::to_string(env.layers.size()) + ".json"),
             ManifestLayer{}.add_layer(
-                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-            std::string(layer_name) + std::to_string(env.layers.size()) + ".json"});
+                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     } else {
         abort();
     }
@@ -82,7 +98,7 @@
 // Make sure settings layer is found and that a layer defined in it is loaded
 TEST(SettingsFile, FileExist) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all"));
     const char* regular_layer_name = add_layer_and_settings(env, "VK_LAYER_TestLayer_0", LayerType::exp, "on");
     env.update_loader_settings(env.loader_settings);
@@ -103,103 +119,102 @@
 // Make sure that if the settings file is in a user local path, that it isn't used when running with elevated privileges
 TEST(SettingsFile, SettingsInUnsecuredLocation) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json"}
-                               .set_discovery_type(ManifestDiscoveryType::override_folder));
-    env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
-        AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(LoaderSettingsLayerConfiguration{}
-                                                                                       .set_name(regular_layer_name)
-                                                                                       .set_path(env.get_layer_manifest_path())
-                                                                                       .set_control("on"))));
-    {
-        auto layer_props = env.GetLayerProperties(1);
-        EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
+            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+    env.update_loader_settings(
+        env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+            AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(LoaderSettingsLayerConfiguration{}
+                                                                                           .set_name(regular_layer_name)
+                                                                                           .set_path(env.get_layer_manifest_path())
+                                                                                           .set_control("on"))),
+        false);
 
-        InstWrapper inst{env.vulkan_functions};
-        FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
-        inst.CheckCreate();
+    auto layer_props = env.GetLayerProperties(1);
+    EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
 
-        ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
-        env.debug_log.clear();
-        auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
-        ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
-    }
-    env.platform_shim->set_elevated_privilege(true);
-    {
-        ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
+    InstWrapper inst{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
 
-        InstWrapper inst{env.vulkan_functions};
-        FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
-        inst.CheckCreate();
+    ASSERT_TRUE(env.debug_log.find(get_unsecure_settings_location_log_message(env)));
+    env.debug_log.clear();
+    auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
+    ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
+}
 
-        ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
-        ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
-    }
+TEST(SettingsFile, SettingsInUnsecuredLocationRunningWithElevatedPrivileges) {
+    FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)};
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
+    const char* regular_layer_name = "VK_LAYER_TestLayer_0";
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+    env.update_loader_settings(
+        env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+            AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(LoaderSettingsLayerConfiguration{}
+                                                                                           .set_name(regular_layer_name)
+                                                                                           .set_path(env.get_layer_manifest_path())
+                                                                                           .set_control("on"))),
+        false);
+
+    ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
+
+    InstWrapper inst{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
+
+    ASSERT_FALSE(env.debug_log.find(get_unsecure_settings_location_log_message(env)));
+    ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
 }
 
 TEST(SettingsFile, SettingsInSecuredLocation) {
-    FrameworkEnvironment env{FrameworkSettings{}.set_secure_loader_settings(true)};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)};
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json"}
-                               .set_discovery_type(ManifestDiscoveryType::override_folder));
+            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(LoaderSettingsLayerConfiguration{}
                                                                                        .set_name(regular_layer_name)
                                                                                        .set_path(env.get_layer_manifest_path())
                                                                                        .set_control("on"))));
-    {
-        auto layer_props = env.GetLayerProperties(1);
-        EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
 
-        InstWrapper inst{env.vulkan_functions};
-        FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
-        inst.CheckCreate();
+    auto layer_props = env.GetLayerProperties(1);
+    EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
 
-        ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env, true)));
-        env.debug_log.clear();
-        auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
-        ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
-    }
-    env.platform_shim->set_elevated_privilege(true);
-    {
-        auto layer_props = env.GetLayerProperties(1);
-        EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
+    InstWrapper inst{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
 
-        InstWrapper inst{env.vulkan_functions};
-        FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
-        inst.CheckCreate();
-
-        ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env, true)));
-        env.debug_log.clear();
-        auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
-        ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
-    }
+    ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
+    env.debug_log.clear();
+    auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
+    ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
 }
 
 // Make sure settings file can have multiple sets of settings
 TEST(SettingsFile, SupportsMultipleSettingsSimultaneously) {
     FrameworkEnvironment env{};
     const char* app_specific_layer_name = "VK_LAYER_TestLayer_0";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(app_specific_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "VK_LAYER_app_specific.json"}
-                               .set_discovery_type(ManifestDiscoveryType::override_folder));
+            ManifestLayer::LayerDescription{}.set_name(app_specific_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
     const char* global_layer_name = "VK_LAYER_TestLayer_1";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(global_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "VK_LAYER_global.json"}
-                               .set_discovery_type(ManifestDiscoveryType::override_folder));
+            ManifestLayer::LayerDescription{}.set_name(global_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
     env.update_loader_settings(
         env.loader_settings
             // configuration that matches the current executable path - but dont set the app-key just yet
@@ -228,7 +243,7 @@
                     .set_name(global_layer_name)
                     .set_path(env.get_layer_manifest_path(1))
                     .set_control("on"))));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     {
         auto layer_props = env.GetLayerProperties(1);
         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, global_layer_name));
@@ -262,19 +277,18 @@
 TEST(SettingsFile, LayerAutoEnabledByEnvVars) {
     FrameworkEnvironment env{};
     env.loader_settings.set_file_format_version({1, 0, 0});
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* layer_name = "VK_LAYER_automatic";
     env.add_explicit_layer(
-        TestLayerDetails{ManifestLayer{}.add_layer(
-                             ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                         "layer_name.json"}
-            .set_discovery_type(ManifestDiscoveryType::override_folder));
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     env.update_loader_settings(
         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
             LoaderSettingsLayerConfiguration{}.set_name(layer_name).set_path(env.get_layer_manifest_path(0)).set_control("auto"))));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     {
         EnvVarWrapper instance_layers{"VK_INSTANCE_LAYERS", layer_name};
         auto layer_props = env.GetLayerProperties(1);
@@ -305,13 +319,12 @@
 // Make sure layers are disallowed from loading if the settings file says so
 TEST(SettingsFile, LayerDisablesImplicitLayer) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* implicit_layer_name = "VK_LAYER_Implicit_TestLayer";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("oof")),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("oof")));
 
     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
@@ -334,19 +347,17 @@
 // Implicit layers should be reordered by the settings file
 TEST(SettingsFile, ImplicitLayersDontInterfere) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name1)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("oof")),
-                           "implicit_test_layer1.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name1)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("oof")));
     const char* implicit_layer_name2 = "VK_LAYER_Implicit_TestLayer2";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name2)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("oof")),
-                           "implicit_test_layer2.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name2)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("oof")));
     // validate order when settings file is not present
     {
         auto layer_props = env.GetLayerProperties(2);
@@ -422,9 +433,9 @@
     // Now add an explicit layer into the middle and verify that is in the correct location
     const char* explicit_layer_name3 = "VK_LAYER_Explicit_TestLayer3";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer3.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
     env.loader_settings.app_specific_settings.at(0).layer_configurations.insert(
         env.loader_settings.app_specific_settings.at(0).layer_configurations.begin() + 1,
         LoaderSettingsLayerConfiguration{}
@@ -452,12 +463,11 @@
 // Make sure layers that are disabled can't be enabled by the application
 TEST(SettingsFile, ApplicationEnablesIgnored) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* explicit_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
@@ -473,50 +483,48 @@
     }
 }
 
+// If the layer list is empty, we want no layers found or loaded
 TEST(SettingsFile, LayerListIsEmpty) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* implicit_layer_name = "VK_LAYER_TestLayer";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("HeeHee")),
-                           "regular_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("HeeHee")));
 
     JsonWriter writer{};
     writer.StartObject();
     writer.AddKeyedString("file_format_version", "1.0.0");
     writer.StartKeyedObject("settings");
-    writer.StartKeyedObject("layers");
+    writer.StartKeyedArray("layers");
+    writer.EndArray();
     writer.EndObject();
     writer.EndObject();
-    writer.EndObject();
-    env.write_settings_file(writer.output);
+    env.write_settings_file(writer.output, true);
 
     ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
 
     InstWrapper inst{env.vulkan_functions};
     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
     inst.CheckCreate();
-    ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
+    ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env, true)));
     ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
 }
 
 // If a settings file exists but contains no valid settings - don't consider it
 TEST(SettingsFile, InvalidSettingsFile) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* explicit_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("foobarbaz")),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("foobarbaz")));
     auto check_integrity = [&env, explicit_layer_name, implicit_layer_name]() {
         auto layer_props = env.GetLayerProperties(2);
         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name));
@@ -536,7 +544,7 @@
         ASSERT_TRUE(fuzzer_output_json_file.is_open());
         std::stringstream fuzzer_output_json;
         fuzzer_output_json << fuzzer_output_json_file.rdbuf();
-        env.write_settings_file(fuzzer_output_json.str());
+        env.write_settings_file(fuzzer_output_json.str(), true);
 
         check_integrity();
     }
@@ -547,7 +555,7 @@
         writer.StartObject();
         writer.AddKeyedString("file_format_version", "0.0.0");
         writer.EndObject();
-        env.write_settings_file(writer.output);
+        env.write_settings_file(writer.output, true);
 
         check_integrity();
     }
@@ -561,7 +569,7 @@
         writer.StartKeyedObject("settings");
         writer.EndObject();
         writer.EndObject();
-        env.write_settings_file(writer.output);
+        env.write_settings_file(writer.output, true);
 
         check_integrity();
     }
@@ -578,7 +586,7 @@
             writer.EndObject();
         }
         writer.EndObject();
-        env.write_settings_file(writer.output);
+        env.write_settings_file(writer.output, true);
 
         check_integrity();
     }
@@ -587,29 +595,25 @@
 // Unknown layers are put in the correct location
 TEST(SettingsFile, UnknownLayersInRightPlace) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* explicit_layer_name1 = "VK_LAYER_TestLayer1";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer1.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     const char* implicit_layer_name1 = "VK_LAYER_ImplicitTestLayer1";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name1)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("foobarbaz")),
-                           "implicit_test_layer1.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name1)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("foobarbaz")));
     const char* explicit_layer_name2 = "VK_LAYER_TestLayer2";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer2.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
     const char* implicit_layer_name2 = "VK_LAYER_ImplicitTestLayer2";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name2)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("foobarbaz")),
-                           "implicit_test_layer2.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name2)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("foobarbaz")));
 
     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}
@@ -645,20 +649,18 @@
 // Settings file allows loading multiple layers with the same name - as long as the path is different
 TEST(SettingsFile, MultipleLayersWithSameName) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* explicit_layer_name = "VK_LAYER_TestLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(explicit_layer_name)
-                                                         .set_description("0000")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                           "regular_test_layer1.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(explicit_layer_name)
+                                                             .set_description("0000")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(explicit_layer_name)
-                                                         .set_description("1111")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                           "regular_test_layer2.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(explicit_layer_name)
+                                                             .set_description("1111")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}
@@ -690,13 +692,12 @@
 // Settings file shouldn't be able to cause the same layer from the same path twice
 TEST(SettingsFile, MultipleLayersWithSamePath) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* explicit_layer_name = "VK_LAYER_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer1.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}
@@ -725,21 +726,19 @@
 // file is removed
 TEST(SettingsFile, MismatchedLayerNameAndManifestPath) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* manifest_explicit_layer_name = "VK_LAYER_MANIFEST_TestLayer";
     const char* settings_explicit_layer_name = "VK_LAYER_Settings_TestLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(manifest_explicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                           "regular_test_layer1.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(manifest_explicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* implicit_layer_name = "VK_LAYER_Implicit_TestLayer";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("oof")),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("oof")));
 
     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
@@ -760,40 +759,37 @@
 // Settings file should take precedence over the meta layer, if present
 TEST(SettingsFile, ImplicitLayerWithEnableEnvironment) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* explicit_layer_1 = "VK_LAYER_Regular_TestLayer";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer1.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* implicit_layer_1 = "VK_LAYER_RegularImplicit_TestLayer";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_1)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("AndISaidHey")
-                                                         .set_enable_environment("WhatsGoingOn")),
-                           "implicit_layer1.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_1)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("AndISaidHey")
+                                                             .set_enable_environment("WhatsGoingOn")));
 
     const char* explicit_layer_2 = "VK_LAYER_Regular_TestLayer1";
-    env.add_explicit_layer(TestLayerDetails(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer2.json"));
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* implicit_layer_2 = "VK_LAYER_RegularImplicit_TestLayer2";
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(implicit_layer_2)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("HeyHeyHeyyaya")
-                                                                          .set_enable_environment("HeyHeyHeyhey")),
-                                            "implicit_layer2.json"));
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_2)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("HeyHeyHeyyaya")
+                                                             .set_enable_environment("HeyHeyHeyhey")));
+
     const char* explicit_layer_3 = "VK_LAYER_Regular_TestLayer3";
-    env.add_explicit_layer(TestLayerDetails(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer3.json"));
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}
             .add_stderr_log_filter("all")
@@ -877,51 +873,45 @@
 // Settings file should take precedence over the meta layer, if present
 TEST(SettingsFile, MetaLayerAlsoActivates) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* settings_explicit_layer_name = "VK_LAYER_Regular_TestLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(settings_explicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                           "explicit_test_layer.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(settings_explicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* settings_implicit_layer_name = "VK_LAYER_RegularImplicit_TestLayer";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(settings_implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("AndISaidHey")
-                                                         .set_enable_environment("WhatsGoingOn")),
-                           "implicit_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(settings_implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("AndISaidHey")
+                                                             .set_enable_environment("WhatsGoingOn")));
 
     const char* component_explicit_layer_name1 = "VK_LAYER_Component_TestLayer1";
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(component_explicit_layer_name1)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "component_test_layer1.json"));
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(component_explicit_layer_name1)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* component_explicit_layer_name2 = "VK_LAYER_Component_TestLayer2";
-    env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(component_explicit_layer_name2)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "component_test_layer2.json"));
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(component_explicit_layer_name2)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* meta_layer_name1 = "VK_LAYER_meta_layer1";
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(meta_layer_name1)
-                                                                         .add_component_layer(component_explicit_layer_name2)
-                                                                         .add_component_layer(component_explicit_layer_name1)
-                                                                         .set_disable_environment("NotGonnaWork")),
-        "meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(meta_layer_name1)
+                                                                             .add_component_layer(component_explicit_layer_name2)
+                                                                             .add_component_layer(component_explicit_layer_name1)
+                                                                             .set_disable_environment("NotGonnaWork")));
 
     const char* meta_layer_name2 = "VK_LAYER_meta_layer2";
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
-                                                                         .set_name(meta_layer_name2)
-                                                                         .add_component_layer(component_explicit_layer_name1)
-                                                                         .set_disable_environment("ILikeTrains")
-                                                                         .set_enable_environment("BakedBeans")),
-        "not_automatic_meta_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(meta_layer_name2)
+                                                                             .add_component_layer(component_explicit_layer_name1)
+                                                                             .set_disable_environment("ILikeTrains")
+                                                                             .set_enable_environment("BakedBeans")));
 
     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}
@@ -981,36 +971,78 @@
     }
 }
 
+TEST(SettingsFile, DuplicateMetaLayers) {
+    FrameworkEnvironment env{};
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
+
+    const char* explicit_layer_name = "VK_LAYER_Regular_TestLayer";
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+    // Add an implicit layer and a meta layer that share a name
+    const char* meta_layer_name = "VK_LAYER_meta_layer";
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(meta_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("NotGonnaWork")));
+    env.add_implicit_layer(
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
+                                                                             .set_name(meta_layer_name)
+                                                                             .add_component_layer(explicit_layer_name)
+                                                                             .set_disable_environment("NotGonnaWork")));
+
+    env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+        AppSpecificSettings{}
+            .add_stderr_log_filter("all")
+            .add_layer_configuration(LoaderSettingsLayerConfiguration{}
+                                         .set_name(explicit_layer_name)
+                                         .set_path(env.get_shimmed_layer_manifest_path(0))
+                                         .set_control("auto")
+                                         .set_treat_as_implicit_manifest(false))
+            .add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"))
+            .add_layer_configuration(
+                LoaderSettingsLayerConfiguration{}
+                    .set_name(meta_layer_name)
+                    .set_path(env.get_folder(ManifestLocation::implicit_layer).location() / "meta_test_layer.json")
+                    .set_control("auto")
+                    .set_treat_as_implicit_manifest(true))
+            .add_layer_configuration(LoaderSettingsLayerConfiguration{}
+                                         .set_name(meta_layer_name)
+                                         .set_path(env.get_shimmed_layer_manifest_path(1))
+                                         .set_control("auto")
+                                         .set_treat_as_implicit_manifest(true))
+
+            ));
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+}
+
 // Layers are correctly ordered by settings file.
 TEST(SettingsFile, LayerOrdering) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer1.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* explicit_layer_name2 = "VK_LAYER_Regular_TestLayer2";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer2.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name1)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("Domierigato")),
-                           "implicit_layer1.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name1)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("Domierigato")));
 
     const char* implicit_layer_name2 = "VK_LAYER_Implicit_TestLayer2";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name2)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("Mistehrobato")),
-                           "implicit_layer2.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name2)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("Mistehrobato")));
 
     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all"));
 
@@ -1064,26 +1096,24 @@
 
 TEST(SettingsFile, EnvVarsWork_VK_LAYER_PATH) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer1.json"}
-                               .set_discovery_type(ManifestDiscoveryType::env_var));
+            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name1)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("Domierigato")),
-                           "implicit_layer1.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name1)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("Domierigato")));
     const char* non_env_var_layer_name2 = "VK_LAYER_Regular_TestLayer2";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        {},
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(non_env_var_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer2.json"});
+            ManifestLayer::LayerDescription{}.set_name(non_env_var_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     {
         auto layer_props = env.GetLayerProperties(2);
@@ -1144,25 +1174,24 @@
 
 TEST(SettingsFile, EnvVarsWork_VK_ADD_LAYER_PATH) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name1)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("Domierigato")),
-                           "implicit_layer1.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name1)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("Domierigato")));
     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer1.json"}
-                               .set_discovery_type(ManifestDiscoveryType::add_env_var));
+            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
     const char* non_env_var_layer_name2 = "VK_LAYER_Regular_TestLayer2";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        {},
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(non_env_var_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer2.json"});
+            ManifestLayer::LayerDescription{}.set_name(non_env_var_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     {
         auto layer_props = env.GetLayerProperties(3);
@@ -1234,27 +1263,24 @@
 
 TEST(SettingsFile, EnvVarsWork_VK_IMPLICIT_LAYER_PATH) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer1.json"}
-                               .set_discovery_type(ManifestDiscoveryType::env_var));
+            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name1)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("Domierigato")),
-                           "implicit_layer1.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name1)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("Domierigato")));
     const char* settings_layer_path = "VK_LAYER_Regular_TestLayer2";
-    env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(settings_layer_path)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("Domierigato")),
-                                            "implicit_test_layer2.json"});
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(settings_layer_path)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("Domierigato")));
 
     {
         auto layer_props = env.GetLayerProperties(3);
@@ -1319,26 +1345,24 @@
 
 TEST(SettingsFile, EnvVarsWork_VK_ADD_IMPLICIT_LAYER_PATH) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name1)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("Domierigato")),
-                           "implicit_layer1.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name1)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("Domierigato")));
     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer1.json"}
-                               .set_discovery_type(ManifestDiscoveryType::add_env_var));
+            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
     const char* settings_layer_name = "VK_LAYER_Regular_TestLayer2";
-    env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(settings_layer_name)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                                          .set_disable_environment("gozaimasu")),
-                                            "implicit_test_layer2.json"});
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(settings_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("gozaimasu")));
 
     {
         auto layer_props = env.GetLayerProperties(3);
@@ -1413,19 +1437,17 @@
 
 TEST(SettingsFile, EnvVarsWork_VK_INSTANCE_LAYERS) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* filler_layer_name = "VK_LAYER_filler";
-    env.add_explicit_layer(TestLayerDetails{
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(filler_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "filler_layer.json"});
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(filler_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* explicit_layer_name = "VK_LAYER_Regular_TestLayer1";
-    env.add_explicit_layer(TestLayerDetails{
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer1.json"});
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     {
         EnvVarWrapper vk_instance_layers{"VK_INSTANCE_LAYERS", explicit_layer_name};
@@ -1502,25 +1524,22 @@
 
 TEST(SettingsFile, EnvVarsWork_VK_INSTANCE_LAYERS_multiple_layers) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
-    env.add_explicit_layer(TestLayerDetails{
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer1.json"});
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* explicit_layer_name2 = "VK_LAYER_Regular_TestLayer2";
-    env.add_explicit_layer(TestLayerDetails{
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer2.json"});
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* explicit_layer_name3 = "VK_LAYER_Regular_TestLayer3";
-    env.add_explicit_layer(TestLayerDetails{
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer3.json"});
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     EnvVarWrapper vk_instance_layers{"VK_INSTANCE_LAYERS"};
     vk_instance_layers.add_to_list(explicit_layer_name2);
@@ -1647,7 +1666,7 @@
 // Make sure that layers disabled by settings file aren't enabled by VK_LOADER_LAYERS_ENABLE
 TEST(SettingsFile, EnvVarsWork_VK_LOADER_LAYERS_ENABLE) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all"));
     const char* explicit_layer_name = add_layer_and_settings(env, "VK_LAYER_Regular_TestLayer1", LayerType::exp, "off");
@@ -1665,7 +1684,7 @@
 
 TEST(SettingsFile, settings_disable_layer_enabled_by_env_vars) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all"));
     std::vector<const char*> layer_names;
     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_alpha", LayerType::imp, "auto"));
@@ -1726,13 +1745,12 @@
 // Make sure that layers enabled by settings file aren't disabled by VK_LOADER_LAYERS_ENABLE
 TEST(SettingsFile, EnvVarsWork_VK_LOADER_LAYERS_DISABLE) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* explicit_layer_name = "VK_LAYER_Regular_TestLayer1";
-    env.add_explicit_layer(TestLayerDetails{
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer1.json"});
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     env.update_loader_settings(
         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
@@ -1756,22 +1774,24 @@
 #if defined(WIN32)
 TEST(SettingsFile, MultipleKeysInRegistryInUnsecureLocation) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
-    env.platform_shim->add_unsecured_manifest(ManifestCategory::settings, "jank_path");
-    env.platform_shim->add_unsecured_manifest(ManifestCategory::settings, "jank_path2");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
+    env.platform_shim->add_unsecured_manifest_to_registry(ManifestCategory::settings, "jank_path");
+    env.platform_shim->add_unsecured_manifest_to_registry(ManifestCategory::settings, "jank_path2");
 
     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json"}
-                               .set_discovery_type(ManifestDiscoveryType::override_folder));
-    env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
-        AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(LoaderSettingsLayerConfiguration{}
-                                                                                       .set_name(regular_layer_name)
-                                                                                       .set_path(env.get_layer_manifest_path())
-                                                                                       .set_control("on"))));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
+    env.update_loader_settings(
+        env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+            AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(LoaderSettingsLayerConfiguration{}
+                                                                                           .set_name(regular_layer_name)
+                                                                                           .set_path(env.get_layer_manifest_path())
+                                                                                           .set_control("on"))),
+        false);
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     auto layer_props = env.GetLayerProperties(1);
     EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
@@ -1780,33 +1800,32 @@
     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
     inst.CheckCreate();
 
-    ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
+    ASSERT_TRUE(env.debug_log.find(get_unsecure_settings_location_log_message(env)));
     auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
     ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
 }
 
 TEST(SettingsFile, MultipleKeysInRegistryInSecureLocation) {
-    FrameworkEnvironment env{FrameworkSettings{}.set_secure_loader_settings(true)};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
-    env.platform_shim->add_manifest(ManifestCategory::settings, "jank_path");
-    env.platform_shim->add_manifest(ManifestCategory::settings, "jank_path2");
+    FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)};
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
+    env.platform_shim->add_manifest_to_registry(ManifestCategory::settings, "jank_path");
+    env.platform_shim->add_manifest_to_registry(ManifestCategory::settings, "jank_path2");
 
     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_test_layer.json"}
-                               .set_discovery_type(ManifestDiscoveryType::override_folder));
+            ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(LoaderSettingsLayerConfiguration{}
                                                                                        .set_name(regular_layer_name)
                                                                                        .set_path(env.get_layer_manifest_path())
                                                                                        .set_control("on"))));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     // Make sure it works if the settings file is in the HKEY_LOCAL_MACHINE
-    env.platform_shim->set_elevated_privilege(true);
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     {
         auto layer_props = env.GetLayerProperties(1);
         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
@@ -1825,26 +1844,25 @@
 // Preinstance functions respect the settings file
 TEST(SettingsFile, PreInstanceFunctions) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(implicit_layer_name)
-                .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                .set_disable_environment("DISABLE_ME")
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceLayerProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceExtensionProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceVersion")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
-        "implicit_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(implicit_layer_name)
+                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                    .set_disable_environment("DISABLE_ME")
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceLayerProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceExtensionProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceVersion")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceVersion"))));
 
     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
         LoaderSettingsLayerConfiguration{}
@@ -1943,21 +1961,19 @@
 // activated.
 TEST(SettingsFile, ImplicitLayerDisableEnvironmentVariableOverriden) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* filler_layer_name = "VK_LAYER_filler";
     env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(filler_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer.json");
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(filler_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")
-                                                         .set_enable_environment("ENABLE_ME")),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")
+                                                             .set_enable_environment("ENABLE_ME")));
     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configurations(
         {LoaderSettingsLayerConfiguration{}
              .set_name(filler_layer_name)
@@ -2085,7 +2101,7 @@
 
 TEST(SettingsFile, ImplicitLayersNotAccidentallyEnabled) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all"));
     std::vector<const char*> layer_names;
 
@@ -2147,19 +2163,18 @@
 
 TEST(SettingsFile, ImplicitLayersPreInstanceEnumInstLayerProps) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(implicit_layer_name)
-                .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                .set_disable_environment("DISABLE_ME")
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceLayerProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))),
-        "implicit_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(implicit_layer_name)
+                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                    .set_disable_environment("DISABLE_ME")
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceLayerProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))));
 
     env.update_loader_settings(
         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
@@ -2180,20 +2195,19 @@
 
 TEST(SettingsFile, EnableEnvironmentImplicitLayersPreInstanceEnumInstLayerProps) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(implicit_layer_name)
-                .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                .set_disable_environment("DISABLE_ME")
-                .set_enable_environment("ENABLE_ME")
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceLayerProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))),
-        "implicit_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(implicit_layer_name)
+                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                    .set_disable_environment("DISABLE_ME")
+                    .set_enable_environment("ENABLE_ME")
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceLayerProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))));
 
     env.update_loader_settings(
         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
@@ -2218,19 +2232,18 @@
 
 TEST(SettingsFile, ImplicitLayersPreInstanceEnumInstExtProps) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(implicit_layer_name)
-                .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                .set_disable_environment("DISABLE_ME")
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceExtensionProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))),
-        "implicit_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(implicit_layer_name)
+                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                    .set_disable_environment("DISABLE_ME")
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceExtensionProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))));
 
     env.update_loader_settings(
         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
@@ -2251,20 +2264,19 @@
 
 TEST(SettingsFile, EnableEnvironmentImplicitLayersPreInstanceEnumInstExtProps) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
 
     env.add_implicit_layer(
-        ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
-            ManifestLayer::LayerDescription{}
-                .set_name(implicit_layer_name)
-                .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                .set_disable_environment("DISABLE_ME")
-                .set_enable_environment("ENABLE_ME")
-                .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
-                                               .set_vk_func("vkEnumerateInstanceExtensionProperties")
-                                               .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))),
-        "implicit_test_layer.json");
+        {}, ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+                ManifestLayer::LayerDescription{}
+                    .set_name(implicit_layer_name)
+                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                    .set_disable_environment("DISABLE_ME")
+                    .set_enable_environment("ENABLE_ME")
+                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
+                                                   .set_vk_func("vkEnumerateInstanceExtensionProperties")
+                                                   .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))));
 
     env.update_loader_settings(
         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
@@ -2287,13 +2299,14 @@
 
 TEST(SettingsFile, ImplicitLayersPreInstanceVersion) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)
         .add_physical_device({})
         .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3));
 
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
 
-    env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+    env.add_implicit_layer({},
+                           ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
                                ManifestLayer::LayerDescription{}
                                    .set_name(implicit_layer_name)
                                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
@@ -2301,8 +2314,7 @@
                                    .set_disable_environment("DISABLE_ME")
                                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
                                                                   .set_vk_func("vkEnumerateInstanceVersion")
-                                                                  .set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
-                           "implicit_test_layer.json");
+                                                                  .set_override_name("test_preinst_vkEnumerateInstanceVersion"))));
 
     env.update_loader_settings(
         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
@@ -2323,13 +2335,14 @@
 
 TEST(SettingsFile, EnableEnvironmentImplicitLayersPreInstanceVersion) {
     FrameworkEnvironment env;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)
         .add_physical_device({})
         .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3));
 
     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
 
-    env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
+    env.add_implicit_layer({},
+                           ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
                                ManifestLayer::LayerDescription{}
                                    .set_name(implicit_layer_name)
                                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
@@ -2338,8 +2351,7 @@
                                    .set_enable_environment("ENABLE_ME")
                                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
                                                                   .set_vk_func("vkEnumerateInstanceVersion")
-                                                                  .set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
-                           "implicit_test_layer.json");
+                                                                  .set_override_name("test_preinst_vkEnumerateInstanceVersion"))));
 
     env.update_loader_settings(
         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
@@ -2361,12 +2373,12 @@
 // Settings can say which filters to use - make sure those are propagated & treated correctly
 TEST(SettingsFile, StderrLogFilters) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* explicit_layer_name = "Regular_TestLayer1";
-    env.add_explicit_layer(TestLayerDetails{
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer1.json"});
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}
             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
@@ -2377,25 +2389,27 @@
                 LoaderSettingsLayerConfiguration{}.set_name("VK_LAYER_missing").set_path("/road/to/nowhere").set_control("on"))));
 
     std::string expected_output_verbose;
-    expected_output_verbose += "DEBUG:             Layer Configurations count = 2\n";
-    expected_output_verbose += "DEBUG:             ---- Layer Configuration [0] ----\n";
-    expected_output_verbose += std::string("DEBUG:             Name: ") + explicit_layer_name + "\n";
-    expected_output_verbose += "DEBUG:             Path: " + env.get_shimmed_layer_manifest_path().string() + "\n";
-    expected_output_verbose += "DEBUG:             Layer Type: Explicit\n";
-    expected_output_verbose += "DEBUG:             Control: on\n";
-    expected_output_verbose += "DEBUG:             ---- Layer Configuration [1] ----\n";
-    expected_output_verbose += "DEBUG:             Name: VK_LAYER_missing\n";
-    expected_output_verbose += "DEBUG:             Path: /road/to/nowhere\n";
-    expected_output_verbose += "DEBUG:             Layer Type: Explicit\n";
-    expected_output_verbose += "DEBUG:             Control: on\n";
-    expected_output_verbose += "DEBUG:             ---------------------------------\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Layer Configurations count = 2\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          ---- Layer Configuration [0] ----\n";
+    expected_output_verbose += std::string("[Vulkan Loader] DEBUG:          Name: ") + explicit_layer_name + "\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Path: " + env.get_shimmed_layer_manifest_path().string() + "\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Layer Type: Explicit\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Control: on\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          ---- Layer Configuration [1] ----\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Name: VK_LAYER_missing\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Path: /road/to/nowhere\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Layer Type: Explicit\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Control: on\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          ---------------------------------\n";
 
-    std::string expected_output_info = std::string("INFO:              ") + get_settings_location_log_message(env) + "\n";
+    std::string expected_output_info =
+        std::string("[Vulkan Loader] INFO:           ") + get_settings_location_log_message(env) + "\n";
 
-    std::string expected_output_warning = "WARNING:           Layer name " + std::string(explicit_layer_name) +
+    std::string expected_output_warning = "[Vulkan Loader] WARNING:        Layer name " + std::string(explicit_layer_name) +
                                           " does not conform to naming standard (Policy #LLP_LAYER_3)\n";
 
-    std::string expected_output_error = "ERROR:             loader_get_json: Failed to open JSON file /road/to/nowhere\n";
+    std::string expected_output_error =
+        "[Vulkan Loader] ERROR:          loader_get_json: Failed to open JSON file /road/to/nowhere\n";
 
     env.loader_settings.app_specific_settings.at(0).stderr_log = {"all"};
     env.update_loader_settings(env.loader_settings);
@@ -2403,9 +2417,9 @@
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
 
-        ASSERT_TRUE(
-            env.platform_shim->find_in_log("DEBUG:             Loader Settings Filters for Logging to Standard Error: ERROR | "
-                                           "WARNING | INFO | DEBUG | PERF | DRIVER | LAYER\n"));
+        ASSERT_TRUE(env.platform_shim->find_in_log(
+            "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error: ERROR | "
+            "WARNING | INFO | DEBUG | PERF | DRIVER | LAYER\n"));
         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_verbose));
         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_info));
         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_warning));
@@ -2420,8 +2434,9 @@
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
 
-        ASSERT_TRUE(env.platform_shim->find_in_log(
-            "DEBUG:             Loader Settings Filters for Logging to Standard Error: ERROR | WARNING | INFO | DEBUG\n"));
+        ASSERT_TRUE(
+            env.platform_shim->find_in_log("[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard "
+                                           "Error: ERROR | WARNING | INFO | DEBUG\n"));
         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_verbose));
         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_info));
         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_warning));
@@ -2437,7 +2452,7 @@
         inst.CheckCreate();
 
         ASSERT_TRUE(env.platform_shim->find_in_log(
-            "DEBUG:             Loader Settings Filters for Logging to Standard Error: WARNING | INFO | DEBUG\n"));
+            "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error: WARNING | INFO | DEBUG\n"));
         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_verbose));
         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_info));
         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_warning));
@@ -2452,8 +2467,8 @@
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
 
-        ASSERT_TRUE(
-            env.platform_shim->find_in_log("DEBUG:             Loader Settings Filters for Logging to Standard Error: DEBUG\n"));
+        ASSERT_TRUE(env.platform_shim->find_in_log(
+            "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error: DEBUG\n"));
         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_verbose));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_info));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_warning));
@@ -2468,8 +2483,8 @@
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
 
-        ASSERT_FALSE(
-            env.platform_shim->find_in_log("DEBUG:             Loader Settings Filters for Logging to Standard Error: INFO\n"));
+        ASSERT_FALSE(env.platform_shim->find_in_log(
+            "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error: INFO\n"));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_verbose));
         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_info));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_warning));
@@ -2484,8 +2499,8 @@
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
 
-        ASSERT_FALSE(
-            env.platform_shim->find_in_log("DEBUG:             Loader Settings Filters for Logging to Standard Error: WARNING\n"));
+        ASSERT_FALSE(env.platform_shim->find_in_log(
+            "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error: WARNING\n"));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_verbose));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_info));
         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_warning));
@@ -2500,8 +2515,8 @@
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
 
-        ASSERT_FALSE(
-            env.platform_shim->find_in_log("DEBUG:             Loader Settings Filters for Logging to Standard Error: ERROR\n"));
+        ASSERT_FALSE(env.platform_shim->find_in_log(
+            "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error: ERROR\n"));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_verbose));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_info));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_warning));
@@ -2516,7 +2531,8 @@
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
 
-        ASSERT_FALSE(env.platform_shim->find_in_log("DEBUG:             Loader Settings Filters for Logging to Standard Error:"));
+        ASSERT_FALSE(env.platform_shim->find_in_log(
+            "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error:"));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_verbose));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_info));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_warning));
@@ -2531,7 +2547,8 @@
         InstWrapper inst{env.vulkan_functions};
         inst.CheckCreate();
 
-        ASSERT_FALSE(env.platform_shim->find_in_log("DEBUG:             Loader Settings Filters for Logging to Standard Error:"));
+        ASSERT_FALSE(env.platform_shim->find_in_log(
+            "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error:"));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_verbose));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_info));
         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_warning));
@@ -2544,20 +2561,20 @@
 // Settings can say which filters to use - make sure the lack of this filter works correctly with VK_LOADER_DEBUG
 TEST(SettingsFile, StderrLog_NoOutput) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* explicit_layer_name = "Regular_TestLayer1";
-    env.add_explicit_layer(TestLayerDetails{
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer1.json"});
-    env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}
             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
                                          .set_name(explicit_layer_name)
                                          .set_path(env.get_shimmed_layer_manifest_path())
                                          .set_control("auto"))
             .add_layer_configuration(
-                LoaderSettingsLayerConfiguration{}.set_name("VK_LAYER_missing").set_path("/road/to/nowhere").set_control("auto"))));
+                LoaderSettingsLayerConfiguration{}.set_name("VK_LAYER_missing").set_path("/road/to/nowhere").set_control("auto")));
     env.loader_settings.app_specific_settings.at(0).stderr_log = {""};
     env.update_loader_settings(env.loader_settings);
 
@@ -2632,46 +2649,47 @@
 // Settings can say which filters to use - make sure the lack of this filter works correctly with VK_LOADER_DEBUG
 TEST(SettingsFile, NoStderr_log_but_VK_LOADER_DEBUG) {
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("all")};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
 
     const char* explicit_layer_name = "Regular_TestLayer1";
 
-    env.add_explicit_layer(TestLayerDetails{
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "explicit_test_layer1.json"});
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
-    env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}
             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
                                          .set_name(explicit_layer_name)
                                          .set_path(env.get_shimmed_layer_manifest_path())
                                          .set_control("auto"))
             .add_layer_configuration(
-                LoaderSettingsLayerConfiguration{}.set_name("VK_LAYER_missing").set_path("/road/to/nowhere").set_control("auto"))));
+                LoaderSettingsLayerConfiguration{}.set_name("VK_LAYER_missing").set_path("/road/to/nowhere").set_control("auto")));
     env.loader_settings.app_specific_settings.at(0).stderr_log = {};
     env.update_loader_settings(env.loader_settings);
 
     std::string expected_output_verbose;
-    expected_output_verbose += "DEBUG:             Layer Configurations count = 2\n";
-    expected_output_verbose += "DEBUG:             ---- Layer Configuration [0] ----\n";
-    expected_output_verbose += std::string("DEBUG:             Name: ") + explicit_layer_name + "\n";
-    expected_output_verbose += "DEBUG:             Path: " + env.get_shimmed_layer_manifest_path().string() + "\n";
-    expected_output_verbose += "DEBUG:             Layer Type: Explicit\n";
-    expected_output_verbose += "DEBUG:             Control: auto\n";
-    expected_output_verbose += "DEBUG:             ---- Layer Configuration [1] ----\n";
-    expected_output_verbose += "DEBUG:             Name: VK_LAYER_missing\n";
-    expected_output_verbose += "DEBUG:             Path: /road/to/nowhere\n";
-    expected_output_verbose += "DEBUG:             Layer Type: Explicit\n";
-    expected_output_verbose += "DEBUG:             Control: auto\n";
-    expected_output_verbose += "DEBUG:             ---------------------------------\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Layer Configurations count = 2\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          ---- Layer Configuration [0] ----\n";
+    expected_output_verbose += std::string("[Vulkan Loader] DEBUG:          Name: ") + explicit_layer_name + "\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Path: " + env.get_shimmed_layer_manifest_path().string() + "\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Layer Type: Explicit\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Control: auto\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          ---- Layer Configuration [1] ----\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Name: VK_LAYER_missing\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Path: /road/to/nowhere\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Layer Type: Explicit\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          Control: auto\n";
+    expected_output_verbose += "[Vulkan Loader] DEBUG:          ---------------------------------\n";
 
-    std::string expected_output_info = std::string("INFO:              ") + get_settings_location_log_message(env) + "\n";
+    std::string expected_output_info =
+        std::string("[Vulkan Loader] INFO:           ") + get_settings_location_log_message(env) + "\n";
 
     std::string expected_output_warning =
-        "WARNING:           Layer name Regular_TestLayer1 does not conform to naming standard (Policy #LLP_LAYER_3)\n";
+        "[Vulkan Loader] WARNING:        Layer name Regular_TestLayer1 does not conform to naming standard (Policy #LLP_LAYER_3)\n";
 
-    std::string expected_output_error = "ERROR:             loader_get_json: Failed to open JSON file /road/to/nowhere\n";
+    std::string expected_output_error =
+        "[Vulkan Loader] ERROR:          loader_get_json: Failed to open JSON file /road/to/nowhere\n";
 
     env.platform_shim->clear_logs();
     {
@@ -2688,32 +2706,22 @@
 }
 TEST(SettingsFile, ManyLayersEnabledInManyWays) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     const char* layer1 = "VK_LAYER_layer1";
-    env.add_explicit_layer(
-        TestLayerDetails{ManifestLayer{}.add_layer(
-                             ManifestLayer::LayerDescription{}.set_name(layer1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                         "explicit_layer1.json"});
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}.set_name(layer1).set_lib_path(
+                                   TEST_LAYER_PATH_EXPORT_VERSION_2)));
     const char* layer2 = "VK_LAYER_layer2";
-    env.add_explicit_layer(
-        TestLayerDetails{ManifestLayer{}.add_layer(
-                             ManifestLayer::LayerDescription{}.set_name(layer2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                         "explicit_layer2.json"});
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}.set_name(layer2).set_lib_path(
+                                   TEST_LAYER_PATH_EXPORT_VERSION_2)));
     const char* layer3 = "VK_LAYER_layer3";
-    env.add_explicit_layer(
-        TestLayerDetails{ManifestLayer{}.add_layer(
-                             ManifestLayer::LayerDescription{}.set_name(layer3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                         "explicit_layer3.json"});
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}.set_name(layer3).set_lib_path(
+                                   TEST_LAYER_PATH_EXPORT_VERSION_2)));
     const char* layer4 = "VK_LAYER_layer4";
-    env.add_explicit_layer(
-        TestLayerDetails{ManifestLayer{}.add_layer(
-                             ManifestLayer::LayerDescription{}.set_name(layer4).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                         "explicit_layer4.json"});
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}.set_name(layer4).set_lib_path(
+                                   TEST_LAYER_PATH_EXPORT_VERSION_2)));
     const char* layer5 = "VK_LAYER_layer5";
-    env.add_explicit_layer(
-        TestLayerDetails{ManifestLayer{}.add_layer(
-                             ManifestLayer::LayerDescription{}.set_name(layer5).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                         "explicit_layer5.json"});
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}.set_name(layer5).set_lib_path(
+                                   TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configurations(
@@ -2758,17 +2766,18 @@
 // Enough layers exist that arrays need to be resized - make sure that works
 TEST(SettingsFile, TooManyLayers) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
     env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
         AppSpecificSettings{}.add_stderr_log_filter("all"));
     std::string layer_name = "VK_LAYER_regular_layer_name_";
     uint32_t layer_count = 40;
     for (uint32_t i = 0; i < layer_count; i++) {
-        env.add_explicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                              .set_name(layer_name + std::to_string(i))
-                                                                              .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                                layer_name + std::to_string(i) + ".json"}
-                                   .set_discovery_type(ManifestDiscoveryType::override_folder));
+        env.add_explicit_layer(ManifestOptions{}
+                                   .set_json_name(layer_name + std::to_string(i) + ".json")
+                                   .set_discovery_type(ManifestDiscoveryType::override_folder),
+                               ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(layer_name + std::to_string(i))
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
         env.loader_settings.app_specific_settings.at(0).add_layer_configuration(LoaderSettingsLayerConfiguration{}
                                                                                     .set_name(layer_name + std::to_string(i))
                                                                                     .set_path(env.get_layer_manifest_path(i))
@@ -2828,59 +2837,53 @@
 
 TEST(SettingsFile, EnvVarsWorkTogether) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device(PhysicalDevice{}.set_deviceName("regular").finish());
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).set_discovery_type(ManifestDiscoveryType::env_var))
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device(PhysicalDevice{}.set_deviceName("regular").finish());
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var))
         .add_physical_device(PhysicalDevice{}.set_deviceName("env_var").finish());
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).set_discovery_type(ManifestDiscoveryType::add_env_var))
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var))
         .add_physical_device(PhysicalDevice{}.set_deviceName("add_env_var").finish());
 
     const char* regular_explicit_layer = "VK_LAYER_regular_explicit_layer";
-    env.add_explicit_layer(TestLayerDetails{
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(regular_explicit_layer).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "regular_explicit_layer.json"});
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(regular_explicit_layer).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
     const char* regular_explicit_layer_settings_file_set_on = "VK_LAYER_regular_explicit_layer_settings_file_set_on";
-    env.add_explicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_name(regular_explicit_layer_settings_file_set_on)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "regular_explicit_layer_settings_file_set_on.json"});
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(regular_explicit_layer_settings_file_set_on)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* env_var_explicit_layer = "VK_LAYER_env_var_explicit_layer";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(env_var_explicit_layer).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "env_var_explicit_layer.json"}
-                               .set_discovery_type(ManifestDiscoveryType::env_var));
+            ManifestLayer::LayerDescription{}.set_name(env_var_explicit_layer).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* add_env_var_explicit_layer = "VK_LAYER_add_env_var_explicit_layer";
-    env.add_explicit_layer(TestLayerDetails{
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var),
         ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(add_env_var_explicit_layer).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "add_env_var_explicit_layer.json"}
-                               .set_discovery_type(ManifestDiscoveryType::add_env_var));
+            ManifestLayer::LayerDescription{}.set_name(add_env_var_explicit_layer).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* regular_implicit_layer = "VK_LAYER_regular_implicit_layer";
-    env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_disable_environment("A")
-                                                                          .set_name(regular_implicit_layer)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "regular_implicit_layer.json"});
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_disable_environment("A")
+                                                             .set_name(regular_implicit_layer)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* env_var_implicit_layer = "VK_LAYER_env_var_implicit_layer";
-    env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_disable_environment("B")
-                                                                          .set_name(env_var_implicit_layer)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "env_var_implicit_layer.json"}
-                               .set_discovery_type(ManifestDiscoveryType::env_var));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_disable_environment("B")
+                                                         .set_name(env_var_implicit_layer)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     const char* add_env_var_implicit_layer = "VK_LAYER_add_env_var_implicit_layer";
-    env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                                          .set_disable_environment("C")
-                                                                          .set_name(add_env_var_implicit_layer)
-                                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                                            "add_env_var_implicit_layer.json"}
-                               .set_discovery_type(ManifestDiscoveryType::add_env_var));
+    env.add_implicit_layer(ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var),
+                           ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                         .set_disable_environment("C")
+                                                         .set_name(add_env_var_implicit_layer)
+                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     // Settings file only contains the one layer it wants enabled
     env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
@@ -3011,3 +3014,626 @@
         EXPECT_TRUE(env.platform_shim->find_in_log("Insert instance layer \"VK_LAYER_add_env_var_implicit_layer\""));
     }
 }
+
+TEST(SettingsFile, DontAllowDuplicatesBetweenSettingsLayersAndDefaultLayers) {
+    FrameworkEnvironment env;
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device({});
+
+    const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
+    env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+        AppSpecificSettings{}
+            .add_stderr_log_filter("all")
+            .add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"))
+            .add_layer_configuration(LoaderSettingsLayerConfiguration{}
+                                         .set_name(explicit_layer_name1)
+                                         .set_path(env.get_shimmed_layer_manifest_path(1))
+                                         .set_control("on"))));
+
+    auto layer_props = env.GetLayerProperties(1);
+    ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name1));
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+
+    auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
+    ASSERT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name1));
+}
+
+// additional drivers being provided by settings file
+TEST(SettingsFile, AdditionalDrivers) {
+    FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")};
+    const char* regular_driver_name = "regular";
+    const char* settings_driver_name = "settings";
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device(PhysicalDevice{}.set_deviceName(regular_driver_name).finish());
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder))
+        .add_physical_device(PhysicalDevice{}.set_deviceName(settings_driver_name).finish());
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+        AppSpecificSettings{}.add_stderr_log_filter("all").add_driver_configuration(
+            LoaderSettingsDriverConfiguration{}.set_path(env.get_icd_manifest_path(1))));
+    env.update_loader_settings(env.loader_settings);
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+    auto pds = inst.GetPhysDevs();
+    ASSERT_EQ(pds.size(), 2U);
+    VkPhysicalDeviceProperties props1{}, props2{};
+    inst.functions->vkGetPhysicalDeviceProperties(pds.at(0), &props1);
+    inst.functions->vkGetPhysicalDeviceProperties(pds.at(1), &props2);
+    ASSERT_TRUE(string_eq(props1.deviceName, regular_driver_name));
+    ASSERT_TRUE(string_eq(props2.deviceName, settings_driver_name));
+}
+// settings file provided drivers replacing system found drivers
+TEST(SettingsFile, ExclusiveAdditionalDrivers) {
+    FrameworkEnvironment env{};
+    const char* regular_driver_name = "regular";
+    const char* settings_driver_name = "settings";
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device(PhysicalDevice{}.set_deviceName(regular_driver_name).finish());
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder))
+        .add_physical_device(PhysicalDevice{}.set_deviceName(settings_driver_name).finish());
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+        AppSpecificSettings{}.set_additional_drivers_use_exclusively(true).add_driver_configuration(
+            LoaderSettingsDriverConfiguration{}.set_path(env.get_icd_manifest_path(1))));
+    env.update_loader_settings(env.loader_settings);
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+    auto pds = inst.GetPhysDevs();
+    ASSERT_EQ(pds.size(), 1U);
+    VkPhysicalDeviceProperties props1{};
+    inst.functions->vkGetPhysicalDeviceProperties(pds.at(0), &props1);
+    ASSERT_TRUE(string_eq(props1.deviceName, settings_driver_name));
+}
+// settings file provided drivers + VK_LOADER_DRIVERS_SELECT
+TEST(SettingsFile, AdditionalDriversReplacesVK_LOADER_DRIVERS_SELECT) {
+    FrameworkEnvironment env{};
+    const char* regular_driver_name = "regular";
+    const char* settings_driver_name = "settings";
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device(PhysicalDevice{}.set_deviceName(regular_driver_name).finish());
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder))
+        .add_physical_device(PhysicalDevice{}.set_deviceName(settings_driver_name).finish());
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+        AppSpecificSettings{}.add_driver_configuration(LoaderSettingsDriverConfiguration{}.set_path(env.get_icd_manifest_path(1))));
+    env.update_loader_settings(env.loader_settings);
+
+    {
+        EnvVarWrapper VK_LOADER_DRIVERS_SELECT{"VK_LOADER_DRIVERS_SELECT",
+                                               std::string("*") + env.get_icd_manifest_path(0).stem().string() + std::string("*")};
+        InstWrapper inst{env.vulkan_functions};
+        inst.CheckCreate();
+        auto pds = inst.GetPhysDevs();
+        ASSERT_EQ(pds.size(), 1U);
+        VkPhysicalDeviceProperties props1{};
+        inst.functions->vkGetPhysicalDeviceProperties(pds.at(0), &props1);
+        ASSERT_TRUE(string_eq(props1.deviceName, regular_driver_name));
+    }
+    {
+        EnvVarWrapper VK_LOADER_DRIVERS_SELECT{"VK_LOADER_DRIVERS_SELECT",
+                                               std::string("*") + env.get_icd_manifest_path(1).stem().string() + std::string("*")};
+        InstWrapper inst{env.vulkan_functions};
+        inst.CheckCreate();
+        auto pds = inst.GetPhysDevs();
+        ASSERT_EQ(pds.size(), 1U);
+        VkPhysicalDeviceProperties props1{};
+        inst.functions->vkGetPhysicalDeviceProperties(pds.at(0), &props1);
+        ASSERT_TRUE(string_eq(props1.deviceName, settings_driver_name));
+    }
+    env.loader_settings.app_specific_settings.at(0).set_additional_drivers_use_exclusively(true);
+    env.update_loader_settings(env.loader_settings);
+    {
+        EnvVarWrapper VK_LOADER_DRIVERS_SELECT{"VK_LOADER_DRIVERS_SELECT",
+                                               std::string("*") + env.get_icd_manifest_path(0).stem().string() + std::string("*")};
+        InstWrapper inst{env.vulkan_functions};
+        inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
+    }
+    {
+        EnvVarWrapper VK_LOADER_DRIVERS_SELECT{"VK_LOADER_DRIVERS_SELECT",
+                                               std::string("*") + env.get_icd_manifest_path(1).stem().string() + std::string("*")};
+        InstWrapper inst{env.vulkan_functions};
+        inst.CheckCreate();
+        auto pds = inst.GetPhysDevs();
+        ASSERT_EQ(pds.size(), 1U);
+        VkPhysicalDeviceProperties props1{};
+        inst.functions->vkGetPhysicalDeviceProperties(pds.at(0), &props1);
+        ASSERT_TRUE(string_eq(props1.deviceName, settings_driver_name));
+    }
+}
+
+// settings file provided drivers + VK_LOADER_DRIVERS_DISABLE
+TEST(SettingsFile, AdditionalDriversReplacesVK_LOADER_DRIVERS_DISABLE) {
+    // TODO
+}
+
+TEST(SettingsFile, InvalidAdditionalDriversField) {
+    FrameworkEnvironment env{};
+    const char* layer_name = "VK_LAYER_layer";
+    const char* driver_name = "driver";
+    const char* settings_driver_name = "settings_driver";
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder))
+        .add_physical_device(PhysicalDevice{}.set_deviceName(settings_driver_name).finish());
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device(PhysicalDevice{}.set_deviceName(driver_name).finish());
+
+    env.add_explicit_layer(
+        ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder),
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name("VK_LAYER_layer").set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
+    JsonWriter writer;
+    writer.StartObject();
+    writer.AddKeyedString("file_format_version", "1.0.0");
+
+    writer.StartKeyedObject("settings");
+    writer.StartKeyedArray("additional_drivers");
+    writer.AddString(env.get_shimmed_icd_manifest_path(0));
+    writer.EndArray();
+    writer.StartKeyedArray("layers");
+    writer.StartObject();
+    writer.AddKeyedString("name", layer_name);
+    writer.AddKeyedString("path", env.get_shimmed_layer_manifest_path(0));
+    writer.AddKeyedString("control", "on");
+    writer.EndObject();
+    writer.EndArray();
+    writer.EndObject();
+    writer.EndObject();
+    env.write_settings_file(writer.output, true);
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+    auto pd = inst.GetPhysDev();
+    VkPhysicalDeviceProperties props1{};
+    inst.functions->vkGetPhysicalDeviceProperties(pd, &props1);
+    ASSERT_TRUE(string_eq(props1.deviceName, driver_name));
+
+    auto active_layer_props = inst.GetActiveLayers(pd, 1);
+    EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, layer_name));
+}
+
+TEST(SettingsFile, DriverConfigurationsInSpecifiedOrder) {
+    FrameworkEnvironment env{};
+    std::vector<VulkanUUID> uuids{10, VulkanUUID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
+
+    // Mix up the uuid's so that they are all unique
+    int count = 1;
+    for (auto& uuid : uuids) {
+        std::rotate(uuid.begin(), uuid.begin() + count, uuid.end());
+        count++;
+    }
+
+    auto& icd = env.add_icd(TEST_ICD_PATH_VERSION_2).set_icd_api_version(VK_API_VERSION_1_1);
+    for (uint32_t i = 0; i < uuids.size(); i++) {
+        // add the physical devices in reverse order of UUID's
+        icd.add_physical_device(PhysicalDevice()
+                                    .set_deviceName("PhysicalDevice_" + std::to_string(uuids.size() - 1 - i))
+                                    .set_api_version(VK_API_VERSION_1_1)
+                                    .set_deviceUUID(uuids[uuids.size() - 1 - i])
+                                    .finish());
+    }
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(AppSpecificSettings{});
+    for (uint32_t i = 0; i < uuids.size(); i++) {
+        env.loader_settings.app_specific_settings.at(0).add_device_configuration(
+            LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[i]));
+    }
+    env.update_loader_settings(env.loader_settings);
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+    auto pds = inst.GetPhysDevs();
+    ASSERT_EQ(pds.size(), uuids.size());
+    for (uint32_t i = 0; i < uuids.size(); i++) {
+        VkPhysicalDeviceProperties props{};
+
+        inst->vkGetPhysicalDeviceProperties(pds.at(i), &props);
+        std::string s = "PhysicalDevice_" + std::to_string(i);
+        ASSERT_TRUE(string_eq(s.c_str(), props.deviceName));
+    }
+}
+
+TEST(SettingsFile, OnlyOneDriverConfiguration) {
+    FrameworkEnvironment env{};
+    std::vector<VulkanUUID> uuids{10, VulkanUUID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
+
+    // Mix up the uuid's so that they are all unique
+    int count = 1;
+    for (auto& uuid : uuids) {
+        std::rotate(uuid.begin(), uuid.begin() + count, uuid.end());
+        count++;
+    }
+
+    auto& icd = env.add_icd(TEST_ICD_PATH_VERSION_2).set_icd_api_version(VK_API_VERSION_1_1);
+    for (uint32_t i = 0; i < uuids.size(); i++) {
+        // add the physical devices in reverse order of UUID's
+        icd.add_physical_device(
+            PhysicalDevice().set_api_version(VK_API_VERSION_1_1).set_deviceUUID(uuids[uuids.size() - 1 - i]).finish());
+    }
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(AppSpecificSettings{});
+
+    for (uint32_t i = 0; i < uuids.size(); i++) {
+        env.loader_settings.app_specific_settings.at(0).device_configurations.clear();
+        env.loader_settings.app_specific_settings.at(0).add_device_configuration(
+            LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[i]));
+
+        env.update_loader_settings(env.loader_settings);
+
+        InstWrapper inst{env.vulkan_functions};
+        inst.create_info.set_api_version(VK_API_VERSION_1_1);
+        inst.CheckCreate();
+        auto pd = inst.GetPhysDev();
+
+        VkPhysicalDeviceVulkan11Properties vulkan_11_props{};
+        vulkan_11_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
+        VkPhysicalDeviceProperties2 props2{};
+        props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+        props2.pNext = &vulkan_11_props;
+        inst->vkGetPhysicalDeviceProperties2(pd, &props2);
+
+        ASSERT_TRUE(0 == memcmp(vulkan_11_props.deviceUUID, uuids[i].data(), VK_UUID_SIZE * sizeof(uint8_t)));
+    }
+}
+
+TEST(SettingsFile, MissingDriverConfiguration) {
+    FrameworkEnvironment env{};
+    std::vector<VulkanUUID> uuids{2, VulkanUUID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
+
+    // Mix up the uuid's so that they are all unique
+    int count = 1;
+    for (auto& uuid : uuids) {
+        std::rotate(uuid.begin(), uuid.begin() + count, uuid.end());
+        count++;
+    }
+
+    auto& icd = env.add_icd(TEST_ICD_PATH_VERSION_2).set_icd_api_version(VK_API_VERSION_1_1);
+    icd.add_physical_device(PhysicalDevice().set_api_version(VK_API_VERSION_1_1).set_deviceUUID(uuids[1]).finish());
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(AppSpecificSettings{});
+
+    env.loader_settings.app_specific_settings.at(0).device_configurations.clear();
+    env.loader_settings.app_specific_settings.at(0).add_device_configuration(
+        LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[0]));
+
+    env.update_loader_settings(env.loader_settings);
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+    inst.GetPhysDev(VK_ERROR_INITIALIZATION_FAILED);
+}
+
+TEST(SettingsFile, DeviceConfigurationWithSameDriver) {
+    FrameworkEnvironment env{};
+    VulkanUUID device_uuid = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+    VulkanUUID driver_uuid = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25};
+
+    auto& icd0 = env.add_icd(TEST_ICD_PATH_VERSION_2).set_icd_api_version(VK_API_VERSION_1_1);
+    auto& phys_dev_0 = icd0.add_and_get_physical_device(PhysicalDevice()
+                                                            .set_api_version(VK_API_VERSION_1_2)
+                                                            .set_deviceUUID(device_uuid)
+                                                            .set_driverUUID(driver_uuid)
+                                                            .set_deviceName("foobar")
+                                                            .finish());
+    phys_dev_0.properties.driverVersion = 1000;
+    std::string("Fake Driver XYZ").copy(phys_dev_0.driver_properties.driverName, VK_MAX_EXTENSION_NAME_SIZE);
+
+    auto& icd1 = env.add_icd(TEST_ICD_PATH_VERSION_2).set_icd_api_version(VK_API_VERSION_1_1);
+    auto& phys_dev_1 = icd1.add_and_get_physical_device(PhysicalDevice()
+                                                            .set_api_version(VK_API_VERSION_1_2)
+                                                            .set_deviceUUID(device_uuid)
+                                                            .set_driverUUID(driver_uuid)
+                                                            .set_deviceName("foobar")
+                                                            .finish());
+    phys_dev_1.properties.driverVersion = 30;
+    std::string("Fake Driver XYZ, but differently named").copy(phys_dev_1.driver_properties.driverName, VK_MAX_EXTENSION_NAME_SIZE);
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(AppSpecificSettings{});
+
+    env.loader_settings.app_specific_settings.at(0).device_configurations.clear();
+    env.loader_settings.app_specific_settings.at(0).add_device_configuration(
+        LoaderSettingsDeviceConfiguration{}
+            .set_deviceUUID(device_uuid)
+            .set_driverUUID(driver_uuid)
+            .set_driverVersion(phys_dev_1.properties.driverVersion));
+    env.loader_settings.app_specific_settings.at(0).add_device_configuration(
+        LoaderSettingsDeviceConfiguration{}
+            .set_deviceUUID(device_uuid)
+            .set_driverUUID(driver_uuid)
+            .set_driverVersion(phys_dev_0.properties.driverVersion));
+    env.update_loader_settings(env.loader_settings);
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+    auto phys_devs = inst.GetPhysDevs(2);
+    VkPhysicalDeviceProperties props1{};
+    VkPhysicalDeviceProperties props2{};
+    inst->vkGetPhysicalDeviceProperties(phys_devs.at(0), &props1);
+    inst->vkGetPhysicalDeviceProperties(phys_devs.at(1), &props2);
+    ASSERT_EQ(props1.driverVersion, phys_dev_1.properties.driverVersion);
+    ASSERT_EQ(props2.driverVersion, phys_dev_0.properties.driverVersion);
+}
+
+// Three drivers, second on has the matching UUID in the settings file.
+TEST(SettingsFile, DriverConfigurationIgnoresDriverEnvVars) {
+    FrameworkEnvironment env{};
+    std::vector<VulkanUUID> uuids{3, VulkanUUID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
+
+    // Mix up the uuid's so that they are all unique
+    int count = 1;
+    for (auto& uuid : uuids) {
+        std::rotate(uuid.begin(), uuid.begin() + count, uuid.end());
+        count++;
+    }
+
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
+        .add_physical_device(PhysicalDevice().set_deviceName("A").set_deviceUUID(uuids[0]).finish());
+
+    auto& icd = env.add_icd(TEST_ICD_PATH_VERSION_2).set_icd_api_version(VK_API_VERSION_1_1);
+    icd.add_physical_device(
+        PhysicalDevice().set_api_version(VK_API_VERSION_1_1).set_deviceName("B").set_deviceUUID(uuids[1]).finish());
+
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var))
+        .add_physical_device(PhysicalDevice().set_deviceName("C").set_deviceUUID(uuids[2]).finish());
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(AppSpecificSettings{});
+
+    env.loader_settings.app_specific_settings.at(0).device_configurations.clear();
+    env.loader_settings.app_specific_settings.at(0).add_device_configuration(
+        LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[1]));
+
+    env.update_loader_settings(env.loader_settings);
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.set_api_version(VK_API_VERSION_1_1);
+    inst.CheckCreate();
+    auto pd = inst.GetPhysDev();
+
+    VkPhysicalDeviceVulkan11Properties vulkan_11_props{};
+    vulkan_11_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
+    VkPhysicalDeviceProperties2 props2{};
+    props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+    props2.pNext = &vulkan_11_props;
+    inst->vkGetPhysicalDeviceProperties2(pd, &props2);
+
+    ASSERT_TRUE(0 == memcmp(vulkan_11_props.deviceUUID, uuids[1].data(), VK_UUID_SIZE * sizeof(uint8_t)));
+}
+
+TEST(SettingsFile, DriverConfigurationsAndAdditionalDrivers) {
+    FrameworkEnvironment env{};
+
+    std::vector<VulkanUUID> uuids{3, VulkanUUID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
+    // Mix up the uuid's so that they are all unique
+    int count = 1;
+    for (auto& uuid : uuids) {
+        std::rotate(uuid.begin(), uuid.begin() + count, uuid.end());
+        count++;
+    }
+
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder))
+        .add_physical_device(PhysicalDevice{}
+                                 .set_api_version(VK_API_VERSION_1_1)
+                                 .set_deviceName("additional_device")
+                                 .set_deviceUUID(uuids[0])
+                                 .finish());
+
+    auto& icd = env.add_icd(TEST_ICD_PATH_VERSION_2)
+                    .set_icd_api_version(VK_API_VERSION_1_1)
+                    .add_physical_device(PhysicalDevice()
+                                             .set_api_version(VK_API_VERSION_1_1)
+                                             .set_deviceName("device_configuration_device")
+                                             .set_deviceUUID(uuids[1])
+                                             .finish());
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(AppSpecificSettings{});
+    env.loader_settings.app_specific_settings.at(0).add_driver_configuration(
+        LoaderSettingsDriverConfiguration().set_path(env.get_icd_manifest_path(0)));
+    env.loader_settings.app_specific_settings.at(0).add_device_configuration(
+        LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[1]));
+    env.update_loader_settings(env.loader_settings);
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.set_api_version(VK_API_VERSION_1_1);
+    inst.CheckCreate();
+    auto pd = inst.GetPhysDev();
+    VkPhysicalDeviceProperties props{};
+    inst->vkGetPhysicalDeviceProperties(pd, &props);
+    ASSERT_TRUE(string_eq("device_configuration_device", props.deviceName));
+    VkPhysicalDeviceVulkan11Properties vulkan_11_props{};
+    vulkan_11_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
+    VkPhysicalDeviceProperties2 props2{};
+    props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+    props2.pNext = &vulkan_11_props;
+    inst->vkGetPhysicalDeviceProperties2(pd, &props2);
+
+    ASSERT_TRUE(0 == memcmp(vulkan_11_props.deviceUUID, uuids[1].data(), VK_UUID_SIZE * sizeof(uint8_t)));
+}
+
+TEST(SettingsFile, InvalidDriverConfigurations) {
+    FrameworkEnvironment env{};
+    std::vector<VulkanUUID> uuids{3, VulkanUUID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
+
+    // Mix up the uuid's so that they are all unique
+    int count = 1;
+    for (auto& uuid : uuids) {
+        std::rotate(uuid.begin(), uuid.begin() + count, uuid.end());
+        count++;
+    }
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
+        .set_icd_api_version(VK_API_VERSION_1_1)
+        .add_physical_device(PhysicalDevice{}
+                                 .set_api_version(VK_API_VERSION_1_1)
+                                 .set_deviceName("regular_driver")
+                                 .set_deviceUUID(uuids[0])
+                                 .finish());
+
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder))
+        .add_physical_device(PhysicalDevice{}
+                                 .set_api_version(VK_API_VERSION_1_1)
+                                 .set_deviceName("additional_device")
+                                 .set_deviceUUID(uuids[2])
+                                 .finish());
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+        AppSpecificSettings{}
+            .set_additional_drivers_use_exclusively(true)
+            .add_driver_configuration(LoaderSettingsDriverConfiguration{}.set_path(env.get_icd_manifest_path(1)))
+            .add_device_configuration(LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[1])));
+    env.update_loader_settings(env.loader_settings);
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+    auto pd = inst.GetPhysDev(VK_ERROR_INITIALIZATION_FAILED);
+}
+
+TEST(SettingsFile, DeviceConfigurationReordersAdditionalDrivers) {
+    FrameworkEnvironment env{};
+    std::vector<VulkanUUID> uuids{3, VulkanUUID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
+
+    // Mix up the uuid's so that they are all unique
+    int count = 1;
+    for (auto& uuid : uuids) {
+        std::rotate(uuid.begin(), uuid.begin() + count, uuid.end());
+        count++;
+    }
+
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
+        .set_icd_api_version(VK_API_VERSION_1_1)
+        .add_physical_device(PhysicalDevice{}
+                                 .set_api_version(VK_API_VERSION_1_1)
+                                 .set_deviceName("regular_driverA")
+                                 .set_deviceUUID(uuids[0])
+                                 .finish());
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
+        .set_icd_api_version(VK_API_VERSION_1_1)
+        .add_physical_device(PhysicalDevice{}
+                                 .set_api_version(VK_API_VERSION_1_1)
+                                 .set_deviceName("regular_driverB")
+                                 .set_deviceUUID(uuids[1])
+                                 .finish());
+
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder))
+        .set_icd_api_version(VK_API_VERSION_1_1)
+        .add_physical_device(PhysicalDevice{}
+                                 .set_api_version(VK_API_VERSION_1_1)
+                                 .set_deviceName("additional_device")
+                                 .set_deviceUUID(uuids[2])
+                                 .finish());
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+        AppSpecificSettings{}
+            .add_driver_configuration(LoaderSettingsDriverConfiguration{}.set_path(env.get_icd_manifest_path(2)))
+            .add_device_configuration(LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[2]))
+            .add_device_configuration(LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[0]))
+            .add_device_configuration(LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[1])));
+    env.update_loader_settings(env.loader_settings);
+    {
+        InstWrapper inst{env.vulkan_functions};
+        inst.CheckCreate();
+        auto pd = inst.GetPhysDevs(3).at(0);
+        VkPhysicalDeviceProperties props{};
+        env.vulkan_functions.vkGetPhysicalDeviceProperties(pd, &props);
+        ASSERT_TRUE(string_eq(props.deviceName, "additional_device"));
+    }
+    {  // do the same check but with 1.1 so we can check that the UUID matches
+        InstWrapper inst{env.vulkan_functions};
+        inst.create_info.set_api_version(VK_API_VERSION_1_1);
+        inst.CheckCreate();
+        auto pd = inst.GetPhysDevs(3).at(0);
+        VkPhysicalDeviceProperties props{};
+        env.vulkan_functions.vkGetPhysicalDeviceProperties(pd, &props);
+        ASSERT_TRUE(string_eq(props.deviceName, "additional_device"));
+
+        VkPhysicalDeviceVulkan11Properties vulkan_11_props{};
+        vulkan_11_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
+        VkPhysicalDeviceProperties2 props2{};
+        props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+        props2.pNext = &vulkan_11_props;
+        inst->vkGetPhysicalDeviceProperties2(pd, &props2);
+
+        ASSERT_TRUE(0 == memcmp(vulkan_11_props.deviceUUID, uuids[2].data(), VK_UUID_SIZE * sizeof(uint8_t)));
+    }
+}
+
+TEST(SettingsFile, DeviceConfigurationReordersExclusiveAdditionalDrivers) {
+    FrameworkEnvironment env{};
+    std::vector<VulkanUUID> uuids{3, VulkanUUID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
+
+    // Mix up the uuid's so that they are all unique
+    int count = 1;
+    for (auto& uuid : uuids) {
+        std::rotate(uuid.begin(), uuid.begin() + count, uuid.end());
+        count++;
+    }
+
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
+        .set_icd_api_version(VK_API_VERSION_1_1)
+        .add_physical_device(PhysicalDevice{}
+                                 .set_api_version(VK_API_VERSION_1_1)
+                                 .set_deviceName("regular_driverA")
+                                 .set_deviceUUID(uuids[0])
+                                 .finish());
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
+        .set_icd_api_version(VK_API_VERSION_1_1)
+        .add_physical_device(PhysicalDevice{}
+                                 .set_api_version(VK_API_VERSION_1_1)
+                                 .set_deviceName("regular_driverB")
+                                 .set_deviceUUID(uuids[1])
+                                 .finish());
+
+    env.add_icd(TEST_ICD_PATH_VERSION_2, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::override_folder))
+        .set_icd_api_version(VK_API_VERSION_1_1)
+        .add_physical_device(PhysicalDevice{}
+                                 .set_api_version(VK_API_VERSION_1_1)
+                                 .set_deviceName("additional_device")
+                                 .set_deviceUUID(uuids[2])
+                                 .finish());
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+        AppSpecificSettings{}
+            .set_additional_drivers_use_exclusively(true)
+            .add_driver_configuration(LoaderSettingsDriverConfiguration{}.set_path(env.get_icd_manifest_path(2)))
+            .add_device_configuration(LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[2])));
+    env.update_loader_settings(env.loader_settings);
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.set_api_version(VK_API_VERSION_1_1);
+    inst.CheckCreate();
+    auto pd = inst.GetPhysDev();
+    VkPhysicalDeviceProperties props{};
+    env.vulkan_functions.vkGetPhysicalDeviceProperties(pd, &props);
+    ASSERT_TRUE(string_eq(props.deviceName, "additional_device"));
+
+    VkPhysicalDeviceVulkan11Properties vulkan_11_props{};
+    vulkan_11_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
+    VkPhysicalDeviceProperties2 props2{};
+    props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+    props2.pNext = &vulkan_11_props;
+    inst->vkGetPhysicalDeviceProperties2(pd, &props2);
+
+    ASSERT_TRUE(0 == memcmp(vulkan_11_props.deviceUUID, uuids[2].data(), VK_UUID_SIZE * sizeof(uint8_t)));
+}
+TEST(SettingsFile, DeviceConfigurationPreservesLayerEnumeration) {
+    FrameworkEnvironment env{};
+    VulkanUUID uuid{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+
+    const char* layer_name = "VK_LAYER_layer";
+    env.add_explicit_layer(
+        {}, ManifestLayer{}.add_layer(
+                ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
+
+    env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
+        AppSpecificSettings{}
+            .add_driver_configuration(LoaderSettingsDriverConfiguration{}.set_path("Shouldn't matter"))
+            .add_device_configuration(LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuid)));
+    env.update_loader_settings(env.loader_settings);
+
+    auto layer_props = env.GetLayerProperties(1);
+    EXPECT_TRUE(string_eq(layer_props.at(0).layerName, layer_name));
+}
diff --git a/tests/loader_testing_main.cpp b/tests/loader_testing_main.cpp
index 20af4f5..263c1e3 100644
--- a/tests/loader_testing_main.cpp
+++ b/tests/loader_testing_main.cpp
@@ -27,6 +27,8 @@
 
 #include "test_environment.h"
 
+#include "util/test_defines.h"
+
 // Makes any failed assertion throw, allowing for graceful cleanup of resources instead of hard aborts
 class ThrowListener : public testing::EmptyTestEventListener {
     void OnTestPartResult(const testing::TestPartResult& result) override {
@@ -55,18 +57,6 @@
     _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
 #endif
 
-    // clean up folders from old test
-    fs::delete_folder(std::filesystem::path(FRAMEWORK_BUILD_DIRECTORY) / "null_dir");
-    fs::delete_folder(std::filesystem::path(FRAMEWORK_BUILD_DIRECTORY) / "icd_manifests");
-    fs::delete_folder(std::filesystem::path(FRAMEWORK_BUILD_DIRECTORY) / "icd_env_vars_manifests");
-    fs::delete_folder(std::filesystem::path(FRAMEWORK_BUILD_DIRECTORY) / "explicit_layer_manifests");
-    fs::delete_folder(std::filesystem::path(FRAMEWORK_BUILD_DIRECTORY) / "explicit_env_var_layer_folder");
-    fs::delete_folder(std::filesystem::path(FRAMEWORK_BUILD_DIRECTORY) / "explicit_add_env_var_layer_folder");
-    fs::delete_folder(std::filesystem::path(FRAMEWORK_BUILD_DIRECTORY) / "implicit_layer_manifests");
-    fs::delete_folder(std::filesystem::path(FRAMEWORK_BUILD_DIRECTORY) / "override_layer_manifests");
-    fs::delete_folder(std::filesystem::path(FRAMEWORK_BUILD_DIRECTORY) / "app_package_manifests");
-    fs::delete_folder(std::filesystem::path(FRAMEWORK_BUILD_DIRECTORY) / "macos_bundle");
-
     // make sure the tests don't find these env-vars if they were set on the system
     EnvVarWrapper vk_icd_filenames_env_var{"VK_ICD_FILENAMES"};
     EnvVarWrapper vk_driver_files_env_var{"VK_DRIVER_FILES"};
@@ -82,14 +72,16 @@
     EnvVarWrapper vk_loader_layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"};
     EnvVarWrapper vk_loader_debug_env_var{"VK_LOADER_DEBUG"};
     EnvVarWrapper vk_loader_disable_inst_ext_filter_env_var{"VK_LOADER_DISABLE_INST_EXT_FILTER"};
+    EnvVarWrapper vk_loader_disable_select_env_var{"VK_LOADER_DISABLE_SELECT"};
 
-#if COMMON_UNIX_PLATFORMS
+    // even though apple shouldn't have XDG env-vars set, the loader looks for them so we have to clear them
+#if TESTING_COMMON_UNIX_PLATFORMS
     // Set only one of the 4 XDG variables to /etc, let everything else be empty
-    EnvVarWrapper xdg_config_home_env_var{"XDG_CONFIG_HOME", ETC_DIR};
+    EnvVarWrapper xdg_config_home_env_var{"XDG_CONFIG_HOME"};
     EnvVarWrapper xdg_config_dirs_env_var{"XDG_CONFIG_DIRS"};
     EnvVarWrapper xdg_data_home_env_var{"XDG_DATA_HOME"};
     EnvVarWrapper xdg_data_dirs_env_var{"XDG_DATA_DIRS"};
-    EnvVarWrapper home_env_var{"HOME", HOME_DIR};
+    EnvVarWrapper home_env_var{"HOME", "/home/test_home_directory"};
 #endif
     ::testing::InitGoogleTest(&argc, argv);
     ::testing::UnitTest::GetInstance()->listeners().Append(new ThrowListener);
diff --git a/tests/loader_threading_tests.cpp b/tests/loader_threading_tests.cpp
index 482bd5f..4d4efa8 100644
--- a/tests/loader_threading_tests.cpp
+++ b/tests/loader_threading_tests.cpp
@@ -77,18 +77,18 @@
 VKAPI_ATTR void VKAPI_CALL test_vkCmdBindDescriptorSets(VkCommandBuffer, VkPipelineBindPoint, VkPipelineLayout, uint32_t, uint32_t,
                                                         const VkDescriptorSet*, uint32_t, const uint32_t*) {}
 VKAPI_ATTR void VKAPI_CALL test_vkCmdBindVertexBuffers(VkCommandBuffer, uint32_t, uint32_t, const VkBuffer*, const VkDeviceSize*) {}
-VKAPI_ATTR void VKAPI_CALL test_vkCmdBindIndexBuffer(VkCommandBuffer, uint32_t, uint32_t, const VkBuffer*, const VkDeviceSize*) {}
+VKAPI_ATTR void VKAPI_CALL test_vkCmdBindIndexBuffer(VkCommandBuffer, VkBuffer, VkDeviceSize, VkIndexType) {}
 VKAPI_ATTR void VKAPI_CALL test_vkCmdDraw(VkCommandBuffer, uint32_t, uint32_t, uint32_t, uint32_t) {}
 TEST(Threading, InstanceCreateDestroyLoop) {
     const auto processor_count = std::thread::hardware_concurrency();
 
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    uint32_t num_loops_create_destroy_instance = 500;
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    uint32_t num_loops_create_destroy_instance = 50;
     uint32_t num_loops_try_get_instance_proc_addr = 5;
-    uint32_t num_loops_try_get_device_proc_addr = 100;
+    uint32_t num_loops_try_get_device_proc_addr = 50;
 
-    driver.physical_devices.emplace_back("physical_device_0")
+    driver.add_and_get_physical_device("physical_device_0")
         .known_device_functions.push_back({"vkCmdBindPipeline", to_vkVoidFunction(test_vkCmdBindPipeline)});
 
     std::vector<std::thread> instance_creation_threads;
@@ -107,12 +107,12 @@
     const auto processor_count = std::thread::hardware_concurrency();
 
     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
 
-    uint32_t num_loops_create_destroy_device = 1000;
+    uint32_t num_loops_create_destroy_device = 100;
     uint32_t num_loops_try_get_device_proc_addr = 5;
 
-    driver.physical_devices.emplace_back("physical_device_0").known_device_functions = {
+    driver.add_and_get_physical_device("physical_device_0").known_device_functions = {
         {"vkCmdBindPipeline", to_vkVoidFunction(test_vkCmdBindPipeline)},
         {"vkCmdBindDescriptorSets", to_vkVoidFunction(test_vkCmdBindDescriptorSets)},
         {"vkCmdBindVertexBuffers", to_vkVoidFunction(test_vkCmdBindVertexBuffers)},
@@ -129,3 +129,46 @@
         device_creation_threads[i].join();
     }
 }
+
+void set_debug_utils_name_loop(FrameworkEnvironment* env, uint32_t num_loops, InstWrapper* inst,
+                               std::vector<VkPhysicalDevice>* phys_devs) {
+    auto load_function = [&inst](const char* func_name) { return inst->load(func_name); };
+
+    PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT = load_function("vkSetDebugUtilsObjectNameEXT");
+    PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT = load_function("vkSetDebugUtilsObjectTagEXT");
+
+    std::vector<DeviceWrapper> devices;
+    for (uint32_t i = 0; i < phys_devs->size(); i++) {
+        auto& device = devices.emplace_back(*inst);
+        device.CheckCreate(phys_devs->at(i));
+    }
+
+    for (uint32_t i = 0; i < num_loops; i++) {
+        for (uint32_t i = 0; i < phys_devs->size(); i++) {
+            VkDebugUtilsObjectNameInfoEXT info{};
+            info.pObjectName = "this string is not that interesting\n";
+            SetDebugUtilsObjectNameEXT(devices.at(i), &info);
+        }
+    }
+}
+TEST(Threading, SetDebugUtilsNameCreateDestroyLoop) {
+    const auto processor_count = std::thread::hardware_concurrency();
+    uint32_t num_loops = 1000;
+    FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")};
+    auto& driver1 = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
+    auto& driver2 = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
+
+    std::vector<std::thread> set_debug_name_threads;
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
+    inst.CheckCreate();
+
+    auto phys_devs = inst.GetPhysDevs();
+    for (uint32_t i = 0; i < processor_count; i++) {
+        set_debug_name_threads.emplace_back(set_debug_utils_name_loop, &env, num_loops, &inst, &phys_devs);
+    }
+    for (uint32_t i = 0; i < processor_count; i++) {
+        set_debug_name_threads[i].join();
+    }
+}
diff --git a/tests/loader_unknown_ext_tests.cpp b/tests/loader_unknown_ext_tests.cpp
index 7822756..a8aa884 100644
--- a/tests/loader_unknown_ext_tests.cpp
+++ b/tests/loader_unknown_ext_tests.cpp
@@ -27,6 +27,8 @@
 
 #include "test_environment.h"
 
+#include "framework/util/dispatchable_handle.h"
+
 enum class TestConfig {
     add_layer_implementation,
     add_layer_interception,
@@ -333,12 +335,12 @@
 
 TEST(UnknownFunction, PhysicalDeviceFunction) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    auto& test_physical_device = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_and_get_physical_device({});
     uint32_t function_count = MAX_NUM_UNKNOWN_EXTS;
     std::vector<std::string> function_names;
     add_function_names(function_names, function_count);
 
-    fill_implementation_functions(driver.physical_devices.at(0).custom_physical_device_functions, function_names,
+    fill_implementation_functions(test_physical_device.custom_physical_device_functions, function_names,
                                   custom_physical_device_functions{}, function_count);
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -350,20 +352,22 @@
 
 TEST(UnknownFunction, PhysicalDeviceFunctionMultipleDriverSupport) {
     FrameworkEnvironment env{};
-    auto& driver_0 = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    auto& driver_1 = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    auto& driver_0 = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    auto& driver_1 = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     uint32_t function_count = MAX_NUM_UNKNOWN_EXTS;
     std::vector<std::string> function_names;
     add_function_names(function_names, function_count);
 
     // used to identify the GPUs
-    driver_0.physical_devices.emplace_back("physical_device_0").properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
-    driver_1.physical_devices.emplace_back("physical_device_1").properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
+    auto& test_physical_driver_0 = driver_0.add_and_get_physical_device("physical_device_0");
+    test_physical_driver_0.properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
+    auto& test_physical_driver_1 = driver_1.add_and_get_physical_device("physical_device_1");
+    test_physical_driver_1.properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
 
     for (uint32_t i = 0; i < function_count / 10; i++) {
-        fill_implementation_functions(driver_0.physical_devices.at(0).custom_physical_device_functions, function_names,
+        fill_implementation_functions(test_physical_driver_0.custom_physical_device_functions, function_names,
                                       custom_physical_device_functions{}, 5, i * 10);
-        fill_implementation_functions(driver_1.physical_devices.at(0).custom_physical_device_functions, function_names,
+        fill_implementation_functions(test_physical_driver_1.custom_physical_device_functions, function_names,
                                       custom_physical_device_functions{}, 5, i * 10 + 5);
     }
     InstWrapper inst{env.vulkan_functions};
@@ -389,18 +393,20 @@
 // Add unknown functions to driver 0, and try to use them on driver 1.
 TEST(UnknownFunctionDeathTests, PhysicalDeviceFunctionErrorPath) {
     FrameworkEnvironment env{};
-    auto& driver_0 = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    auto& driver_1 = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    auto& driver_0 = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    auto& driver_1 = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     std::vector<std::string> function_names;
     add_function_names(function_names, 1);
 
     // used to identify the GPUs
-    driver_0.physical_devices.emplace_back("physical_device_0").properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
-    driver_1.physical_devices.emplace_back("physical_device_1").properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
+    auto& test_physical_driver_0 = driver_0.add_and_get_physical_device("physical_device_0");
+    test_physical_driver_0.properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
+    auto& test_physical_driver_1 = driver_1.add_and_get_physical_device("physical_device_1");
+    test_physical_driver_1.properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
     function_names.push_back(std::string("vkNotIntRealFuncTEST_0"));
 
     custom_physical_device_functions funcs{};
-    driver_0.physical_devices.at(0).custom_physical_device_functions.push_back(
+    test_physical_driver_0.custom_physical_device_functions.push_back(
         VulkanFunction{function_names.back(), to_vkVoidFunction(funcs.func_zero)});
 
     InstWrapper inst{env.vulkan_functions};
@@ -421,16 +427,15 @@
 
 TEST(UnknownFunction, PhysicalDeviceFunctionWithImplicitLayerImplementation) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
     uint32_t function_count = MAX_NUM_UNKNOWN_EXTS;
     std::vector<std::string> function_names;
     add_function_names(function_names, function_count);
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_implicit_layer_unknown_function_intercept")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_layer_unknown_function_intercept.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_implicit_layer_unknown_function_intercept")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     auto& layer = env.get_test_layer();
     fill_implementation_functions(layer.custom_physical_device_implementation_functions, function_names,
                                   layer_implementation_physical_device_functions{}, function_count);
@@ -445,27 +450,28 @@
 
 TEST(UnknownFunction, PhysicalDeviceFunctionMultipleDriverSupportWithImplicitLayerImplementation) {
     FrameworkEnvironment env{};
-    auto& driver_0 = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
-    auto& driver_1 = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    auto& driver_0 = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    auto& driver_1 = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     uint32_t function_count = MAX_NUM_UNKNOWN_EXTS;
     std::vector<std::string> function_names;
     add_function_names(function_names, function_count);
 
     // used to identify the GPUs
-    driver_0.physical_devices.emplace_back("physical_device_0").properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
-    driver_1.physical_devices.emplace_back("physical_device_1").properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
+    auto& test_physical_device_0 = driver_0.add_and_get_physical_device("physical_device_0");
+    test_physical_device_0.properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
+    auto& test_physical_device_1 = driver_1.add_and_get_physical_device("physical_device_1");
+    test_physical_device_1.properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
     for (uint32_t i = 0; i < function_count / 10; i++) {
-        fill_implementation_functions(driver_0.physical_devices.at(0).custom_physical_device_functions, function_names,
+        fill_implementation_functions(test_physical_device_0.custom_physical_device_functions, function_names,
                                       custom_physical_device_functions{}, 5, i * 10);
-        fill_implementation_functions(driver_1.physical_devices.at(0).custom_physical_device_functions, function_names,
+        fill_implementation_functions(test_physical_device_1.custom_physical_device_functions, function_names,
                                       custom_physical_device_functions{}, 5, i * 10 + 5);
     }
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_implicit_layer_unknown_function_intercept")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_layer_unknown_function_intercept.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_implicit_layer_unknown_function_intercept")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -489,17 +495,16 @@
 
 TEST(UnknownFunction, PhysicalDeviceFunctionWithImplicitLayerInterception) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
     uint32_t function_count = MAX_NUM_UNKNOWN_EXTS;
 
     std::vector<std::string> function_names;
     add_function_names(function_names, function_count);
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_implicit_layer_unknown_function_intercept")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_layer_unknown_function_intercept.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_implicit_layer_unknown_function_intercept")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     auto& layer = env.get_test_layer();
     fill_phys_dev_intercept_functions(layer, function_names, layer_intercept_physical_device_functions{}, function_count);
 
@@ -513,17 +518,16 @@
 
 TEST(UnknownFunction, PhysicalDeviceFunctionDriverSupportWithImplicitLayerInterception) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    auto& test_physical_device = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_and_get_physical_device({});
     uint32_t function_count = 100;
     std::vector<std::string> function_names;
     add_function_names(function_names, function_count);
-    fill_implementation_functions(driver.physical_devices.at(0).custom_physical_device_functions, function_names,
+    fill_implementation_functions(test_physical_device.custom_physical_device_functions, function_names,
                                   layer_implementation_physical_device_functions{}, function_count);
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_implicit_layer_unknown_function_intercept")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_layer_unknown_function_intercept.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_implicit_layer_unknown_function_intercept")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     auto& layer = env.get_test_layer();
     fill_phys_dev_intercept_functions(layer, function_names, layer_intercept_physical_device_functions{}, function_count);
 
@@ -537,28 +541,26 @@
 
 TEST(UnknownFunction, PhysicalDeviceFunctionWithMultipleImplicitLayersInterception) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
     std::vector<std::string> function_names;
     uint32_t function_count = MAX_NUM_UNKNOWN_EXTS;
     add_function_names(function_names, function_count);
-    driver.physical_devices.emplace_back("physical_device_0");
+    auto& test_physical_device = driver.add_and_get_physical_device("physical_device_0");
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_implicit_layer_unknown_function_intercept_0")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_layer_unknown_function_intercept_0.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_implicit_layer_unknown_function_intercept_0")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     auto& layer_0 = env.get_test_layer(0);
     layer_0.set_use_gipa_GetPhysicalDeviceProcAddr(true);
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_implicit_layer_unknown_function_intercept_1")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_layer_unknown_function_intercept_1.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_implicit_layer_unknown_function_intercept_1")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     auto& layer_1 = env.get_test_layer(1);
     layer_1.set_use_gipa_GetPhysicalDeviceProcAddr(false);
     for (uint32_t i = 0; i < function_count / 10; i++) {
-        fill_implementation_functions(driver.physical_devices.at(0).custom_physical_device_functions, function_names,
+        fill_implementation_functions(test_physical_device.custom_physical_device_functions, function_names,
                                       layer_implementation_physical_device_functions{}, 5, i * 10);
         fill_phys_dev_intercept_functions(layer_0, function_names, layer_intercept_physical_device_functions{}, 5, i * 10);
         fill_phys_dev_intercept_functions(layer_1, function_names, layer_intercept_physical_device_functions{}, 5, i * 10 + 5);
@@ -626,26 +628,25 @@
     using layer_intercept_functions_type = layer_intercept_functions<DispatchableHandleType>;
 
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    auto& pd = driver.add_and_get_physical_device({});
     uint32_t function_count = MAX_NUM_UNKNOWN_EXTS;
 
     std::vector<std::string> function_names;
     add_function_names(function_names, function_count);
 
     if (has_flag(flags, TestConfig::add_layer_interception)) {
-        fill_implementation_functions(driver.physical_devices.back().known_device_functions, function_names,
-                                      layer_implementation_functions_type{}, function_count);
+        fill_implementation_functions(pd.known_device_functions, function_names, layer_implementation_functions_type{},
+                                      function_count);
     } else {
-        fill_implementation_functions(driver.physical_devices.back().known_device_functions, function_names,
-                                      custom_functions_type{}, function_count);
+        fill_implementation_functions(pd.known_device_functions, function_names, custom_functions_type{}, function_count);
     }
     TestLayer* layer_ptr = nullptr;
     if (has_flag(flags, TestConfig::add_layer_implementation) || has_flag(flags, TestConfig::add_layer_interception)) {
-        env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                             .set_name("VK_LAYER_implicit_layer_unknown_function_intercept")
-                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                             .set_disable_environment("DISABLE_ME")),
-                               "implicit_layer_unknown_function_intercept.json");
+        env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                                 .set_name("VK_LAYER_implicit_layer_unknown_function_intercept")
+                                                                 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                                 .set_disable_environment("DISABLE_ME")));
         layer_ptr = &env.get_test_layer();
     }
     if (has_flag(flags, TestConfig::add_layer_implementation) && has_flag(flags, TestConfig::add_layer_interception)) {
@@ -1087,25 +1088,22 @@
 
 TEST(UnknownFunction, PhysicalDeviceFunctionTwoLayerInterception) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
-    PhysicalDevice& pd = driver.physical_devices.back();
+    PhysicalDevice& pd = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_and_get_physical_device({});
 
     UnknownFunction f{"vkFunc1"};
     Functions::three::physical_device::add_to_driver(f, pd);
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_implicit_layer_unknown_function_intercept")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_layer_unknown_function_intercept.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_implicit_layer_unknown_function_intercept")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     auto& layer0 = env.get_test_layer(0);
     Functions::three::physical_device::add_to_layer(f, layer0, D<0>{});
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_implicit_layer_unknown_function_intercept2")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_layer_unknown_function_intercept2.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_implicit_layer_unknown_function_intercept2")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     auto& layer1 = env.get_test_layer(1);
 
     Functions::three::physical_device::add_to_layer(f, layer1, D<1>{});
@@ -1120,8 +1118,7 @@
 
 TEST(UnknownFunction, ManyCombinations) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
-    PhysicalDevice& physical_device = driver.physical_devices.back();
+    PhysicalDevice& physical_device = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_and_get_physical_device({});
     std::vector<UnknownFunction> unknown_funcs;
 
     unknown_funcs.emplace_back("vkZero_uint32_uint32_0");
@@ -1138,20 +1135,18 @@
     unknown_funcs.emplace_back("vkOne_uint32_uint32_char_11");
     unknown_funcs.emplace_back("vkTwo_ptr_int_ptr_int_12");
 
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_implicit_layer_unknown_function_intercept_0")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")
-                                                         .add_device_extension(ManifestLayer::LayerDescription::Extension{
-                                                             "VK_EXT_for_the_laughs", 0, {"vkOne_uint32_uint32_char_11"}})),
-                           "implicit_layer_unknown_function_intercept_0.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_implicit_layer_unknown_function_intercept_0")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")
+                                                             .add_device_extension(ManifestLayer::LayerDescription::Extension{
+                                                                 "VK_EXT_for_the_laughs", 0, {"vkOne_uint32_uint32_char_11"}})));
     auto& layer_0 = env.get_test_layer(0);
     layer_0.set_use_gipa_GetPhysicalDeviceProcAddr(true);
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name("VK_LAYER_implicit_layer_unknown_function_intercept_1")
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_layer_unknown_function_intercept_1.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name("VK_LAYER_implicit_layer_unknown_function_intercept_1")
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
     auto& layer_1 = env.get_test_layer(1);
     layer_1.set_use_gipa_GetPhysicalDeviceProcAddr(false);
 
@@ -1264,37 +1259,35 @@
 
 TEST(UnknownFunction, PhysicalDeviceFunctionInLayer) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
-    env.add_implicit_layer(ManifestLayer{}
-                               .add_layer(ManifestLayer::LayerDescription{}
-                                              .set_name("VK_LAYER_implicit_layer_1")
-                                              .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_0)
-                                              .set_disable_environment("DISABLE_ME"))
-                               .set_file_format_version({1, 0, 0}),
-                           "implicit_layer_1.json");
+    env.add_implicit_layer({}, ManifestLayer{}
+                                   .add_layer(ManifestLayer::LayerDescription{}
+                                                  .set_name("VK_LAYER_implicit_layer_1")
+                                                  .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_0)
+                                                  .set_disable_environment("DISABLE_ME"))
+                                   .set_file_format_version({1, 0, 0}));
 
     UnknownFunction unknown_func{"vkPhysicalDeviceFunctionInLayer"};
     const char* ext_name = "VK_EXT_not_funny";
 
     const char* explicit_layer_unknown_function_implement = "VK_LAYER_implement_unknown_function";
     env.add_explicit_layer(
+        {},
         ManifestLayer{}
             .add_layer(ManifestLayer::LayerDescription{}
                            .set_name(explicit_layer_unknown_function_implement)
                            .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
                            .add_instance_extension(ManifestLayer::LayerDescription::Extension{ext_name, 0, {unknown_func.name}}))
-            .set_file_format_version({1, 1, 0}),
-        "implement_unknown_function.json");
+            .set_file_format_version({1, 1, 0}));
     auto& layer0 = env.get_test_layer(1);
 
     const char* explicit_layer_to_enable_1 = "VK_LAYER_explicit_layer_1";
-    env.add_explicit_layer(ManifestLayer{}
-                               .add_layer(ManifestLayer::LayerDescription{}
-                                              .set_name(explicit_layer_to_enable_1)
-                                              .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2))
-                               .set_file_format_version({1, 2, 0}),
-                           "explicit_layer_2.json");
+    env.add_explicit_layer({}, ManifestLayer{}
+                                   .add_layer(ManifestLayer::LayerDescription{}
+                                                  .set_name(explicit_layer_to_enable_1)
+                                                  .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2))
+                                   .set_file_format_version({1, 2, 0}));
 
     Functions::four::physical_device::add_implementation_to_layer(unknown_func, layer0);
 
diff --git a/tests/loader_version_tests.cpp b/tests/loader_version_tests.cpp
index c13c7f6..f578339 100644
--- a/tests/loader_version_tests.cpp
+++ b/tests/loader_version_tests.cpp
@@ -29,7 +29,7 @@
 
 TEST(ICDInterfaceVersion2Plus, vk_icdNegotiateLoaderICDInterfaceVersion) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2);
 
     for (uint32_t i = 0; i <= 6; i++) {
         for (uint32_t j = i; j <= 6; j++) {
@@ -42,7 +42,7 @@
 
 TEST(ICDInterfaceVersion2Plus, version_3) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
     {
         driver.set_min_icd_interface_version(2).set_enable_icd_wsi(true);
         InstWrapper inst{env.vulkan_functions};
@@ -68,7 +68,7 @@
 
 TEST(ICDInterfaceVersion2Plus, version_4) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
+    env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
 }
@@ -100,9 +100,9 @@
 // This test makes sure that EnumerateAdapterPhysicalDevices on drivers found in the Khronos/Vulkan/Drivers registry
 TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, version_6_in_drivers_registry) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES));
-    driver.physical_devices.emplace_back("physical_device_1");
-    driver.physical_devices.emplace_back("physical_device_0");
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES);
+    driver.add_and_get_physical_device("physical_device_1");
+    driver.add_and_get_physical_device("physical_device_0");
     uint32_t physical_count = static_cast<uint32_t>(driver.physical_devices.size());
     uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
     std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
@@ -127,13 +127,14 @@
 // Make the version_6 driver found through the D3DKMT driver discovery mechanism of the loader
 TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, version_6) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_6, VK_API_VERSION_1_3}.set_discovery_type(ManifestDiscoveryType::null_dir));
+    env.add_icd(TEST_ICD_PATH_VERSION_6, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::null_dir),
+                ManifestICD{}.set_api_version(VK_API_VERSION_1_3));
     // Version 6 provides a mechanism to allow the loader to sort physical devices.
     // The loader will only attempt to sort physical devices on an ICD if version 6 of the interface is supported.
     // This version provides the vk_icdEnumerateAdapterPhysicalDevices function.
     auto& driver = env.get_test_icd(0);
-    driver.physical_devices.emplace_back("physical_device_1");
-    driver.physical_devices.emplace_back("physical_device_0");
+    driver.add_and_get_physical_device("physical_device_1");
+    driver.add_and_get_physical_device("physical_device_0");
     uint32_t physical_count = 2;
     uint32_t returned_physical_count = physical_count;
     std::vector<VkPhysicalDevice> physical_device_handles{physical_count};
@@ -180,11 +181,11 @@
 // EnumerateAdapterPhysicalDevices
 TEST(ICDInterfaceVersion2, EnumAdapters2) {
     FrameworkEnvironment env{};
-    auto& driver =
-        env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA}.set_discovery_type(ManifestDiscoveryType::null_dir));
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA,
+                               ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::null_dir));
     InstWrapper inst{env.vulkan_functions};
-    driver.physical_devices.emplace_back("physical_device_1");
-    driver.physical_devices.emplace_back("physical_device_0");
+    driver.add_and_get_physical_device("physical_device_1");
+    driver.add_and_get_physical_device("physical_device_0");
     uint32_t physical_count = static_cast<uint32_t>(driver.physical_devices.size());
     uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
     std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
@@ -205,14 +206,14 @@
 // Verify that the handles are correct by calling vkGetPhysicalDeviceProperties with them
 TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyPhysDevResults) {
     FrameworkEnvironment env{};
-    auto& driver =
-        env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES, VK_API_VERSION_1_1}
-                        .set_discovery_type(ManifestDiscoveryType::null_dir))
-            .set_min_icd_interface_version(6)
-            .set_icd_api_version(VK_API_VERSION_1_1);
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES,
+                               ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::null_dir),
+                               ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
+                       .set_min_icd_interface_version(6)
+                       .set_icd_api_version(VK_API_VERSION_1_1);
     const std::vector<std::string> physical_device_names = {"physical_device_4", "physical_device_3", "physical_device_2",
                                                             "physical_device_1", "physical_device_0"};
-    for (const auto& dev_name : physical_device_names) driver.physical_devices.push_back(dev_name);
+    for (const auto& dev_name : physical_device_names) driver.add_physical_device(dev_name);
 
     auto& known_driver = known_driver_list.at(2);  // which drive this test pretends to be
     DXGI_ADAPTER_DESC1 desc1{};
@@ -249,20 +250,24 @@
 // Make sure physical device groups enumerated through EnumerateAdapterPhysicalDevices are properly found
 TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyGroupResults) {
     FrameworkEnvironment env{};
-    auto& driver =
-        env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES, VK_API_VERSION_1_1}
-                        .set_discovery_type(ManifestDiscoveryType::null_dir))
-            .set_min_icd_interface_version(6)
-            .set_icd_api_version(VK_API_VERSION_1_1);
+
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES,
+                               ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::null_dir),
+                               ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
+                       .set_min_icd_interface_version(6)
+                       .set_icd_api_version(VK_API_VERSION_1_1);
     const std::vector<std::string> physical_device_names = {"physical_device_4", "physical_device_3", "physical_device_2",
                                                             "physical_device_1", "physical_device_0"};
-    for (const auto& dev_name : physical_device_names) {
-        driver.physical_devices.push_back(dev_name);
-    }
 
-    driver.physical_device_groups.emplace_back(driver.physical_devices[0]).use_physical_device(driver.physical_devices[1]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[2]);
-    driver.physical_device_groups.emplace_back(driver.physical_devices[3]).use_physical_device(driver.physical_devices[4]);
+    auto& test_physical_device_0 = driver.add_and_get_physical_device(physical_device_names[0]);
+    auto& test_physical_device_1 = driver.add_and_get_physical_device(physical_device_names[1]);
+    auto& test_physical_device_2 = driver.add_and_get_physical_device(physical_device_names[2]);
+    auto& test_physical_device_3 = driver.add_and_get_physical_device(physical_device_names[3]);
+    auto& test_physical_device_4 = driver.add_and_get_physical_device(physical_device_names[4]);
+
+    driver.physical_device_groups.emplace_back(test_physical_device_0).use_physical_device(test_physical_device_1);
+    driver.physical_device_groups.emplace_back(test_physical_device_2);
+    driver.physical_device_groups.emplace_back(test_physical_device_3).use_physical_device(test_physical_device_4);
 
     auto& known_driver = known_driver_list.at(2);  // which driver this test pretends to be
     DXGI_ADAPTER_DESC1 desc1{};
@@ -306,7 +311,7 @@
 #endif  // defined(WIN32)
 TEST(ICDInterfaceVersion7, SingleDriver) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7)).add_physical_device({});
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_7).add_physical_device({});
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
     DeviceWrapper dev{inst};
@@ -316,7 +321,7 @@
 
 TEST(ICDInterfaceVersion7, SingleDriverWithoutExportedFunctions) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7_WIHTOUT_EXPORTS)).add_physical_device({});
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_7_WIHTOUT_EXPORTS).add_physical_device({});
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
     DeviceWrapper dev{inst};
@@ -326,21 +331,21 @@
 
 TEST(MultipleICDConfig, Basic) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
 
-    env.get_test_icd(0).physical_devices.emplace_back("physical_device_0");
-    env.get_test_icd(1).physical_devices.emplace_back("physical_device_1");
-    env.get_test_icd(2).physical_devices.emplace_back("physical_device_2");
+    auto& phys_dev_0 = env.get_test_icd(0).add_and_get_physical_device("physical_device_0");
+    auto& phys_dev_1 = env.get_test_icd(1).add_and_get_physical_device("physical_device_1");
+    auto& phys_dev_2 = env.get_test_icd(2).add_and_get_physical_device("physical_device_2");
 
-    env.get_test_icd(0).physical_devices.at(0).properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
-    env.get_test_icd(1).physical_devices.at(0).properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
-    env.get_test_icd(2).physical_devices.at(0).properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_CPU;
+    phys_dev_0.properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
+    phys_dev_1.properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
+    phys_dev_2.properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_CPU;
 
-    copy_string_to_char_array("dev0", env.get_test_icd(0).physical_devices.at(0).properties.deviceName, VK_MAX_EXTENSION_NAME_SIZE);
-    copy_string_to_char_array("dev1", env.get_test_icd(1).physical_devices.at(0).properties.deviceName, VK_MAX_EXTENSION_NAME_SIZE);
-    copy_string_to_char_array("dev2", env.get_test_icd(2).physical_devices.at(0).properties.deviceName, VK_MAX_EXTENSION_NAME_SIZE);
+    std::string("dev0").copy(phys_dev_0.properties.deviceName, VK_MAX_EXTENSION_NAME_SIZE);
+    std::string("dev1").copy(phys_dev_1.properties.deviceName, VK_MAX_EXTENSION_NAME_SIZE);
+    std::string("dev2").copy(phys_dev_2.properties.deviceName, VK_MAX_EXTENSION_NAME_SIZE);
 
     InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
@@ -349,23 +354,23 @@
     uint32_t phys_dev_count = 3;
     ASSERT_EQ(env.vulkan_functions.vkEnumeratePhysicalDevices(inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
     ASSERT_EQ(phys_dev_count, 3U);
-    ASSERT_EQ(env.get_test_icd(0).physical_devices.at(0).properties.deviceType, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
-    ASSERT_EQ(env.get_test_icd(1).physical_devices.at(0).properties.deviceType, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU);
-    ASSERT_EQ(env.get_test_icd(2).physical_devices.at(0).properties.deviceType, VK_PHYSICAL_DEVICE_TYPE_CPU);
+    ASSERT_EQ(phys_dev_0.properties.deviceType, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
+    ASSERT_EQ(phys_dev_1.properties.deviceType, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU);
+    ASSERT_EQ(phys_dev_2.properties.deviceType, VK_PHYSICAL_DEVICE_TYPE_CPU);
 }
 
 TEST(MultipleDriverConfig, DifferentICDInterfaceVersions) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_ICD_GIPA));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_EXPORT_ICD_GIPA);
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
 
     TestICD& icd0 = env.get_test_icd(0);
-    icd0.physical_devices.emplace_back("physical_device_0");
+    icd0.add_and_get_physical_device("physical_device_0");
     icd0.max_icd_interface_version = 1;
 
     TestICD& icd1 = env.get_test_icd(1);
-    icd1.physical_devices.emplace_back("physical_device_1");
+    icd1.add_and_get_physical_device("physical_device_1");
     icd1.min_icd_interface_version = 2;
     icd1.max_icd_interface_version = 5;
 
@@ -380,26 +385,26 @@
 
 TEST(MultipleDriverConfig, DifferentICDsWithDevices) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_ICD_GIPA));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_EXPORT_ICD_GIPA);
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
 
     // Make sure the loader returns all devices from all active ICDs.  Many of the other
     // tests add multiple devices to a single ICD, this just makes sure the loader combines
     // device info across multiple drivers properly.
     TestICD& icd0 = env.get_test_icd(0);
-    icd0.physical_devices.emplace_back("physical_device_0");
+    icd0.add_and_get_physical_device("physical_device_0");
     icd0.min_icd_interface_version = 5;
     icd0.max_icd_interface_version = 5;
 
     TestICD& icd1 = env.get_test_icd(1);
-    icd1.physical_devices.emplace_back("physical_device_1");
-    icd1.physical_devices.emplace_back("physical_device_2");
+    icd1.add_and_get_physical_device("physical_device_1");
+    icd1.add_and_get_physical_device("physical_device_2");
     icd1.min_icd_interface_version = 5;
     icd1.max_icd_interface_version = 5;
 
     TestICD& icd2 = env.get_test_icd(2);
-    icd2.physical_devices.emplace_back("physical_device_3");
+    icd2.add_and_get_physical_device("physical_device_3");
     icd2.min_icd_interface_version = 5;
     icd2.max_icd_interface_version = 5;
 
@@ -414,9 +419,9 @@
 
 TEST(MultipleDriverConfig, DifferentICDsWithDevicesAndGroups) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_ICD_GIPA));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+    env.add_icd(TEST_ICD_PATH_EXPORT_ICD_GIPA);
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1));
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
 
     // The loader has to be able to handle drivers that support device groups in combination
     // with drivers that don't support device groups.  When this is the case, the loader needs
@@ -426,26 +431,26 @@
 
     // ICD 0 :  No 1.1 support (so 1 device will become 1 group in loader)
     TestICD& icd0 = env.get_test_icd(0);
-    icd0.physical_devices.emplace_back("physical_device_0");
+    icd0.add_and_get_physical_device("physical_device_0");
     icd0.min_icd_interface_version = 5;
     icd0.max_icd_interface_version = 5;
     icd0.set_icd_api_version(VK_API_VERSION_1_0);
 
     // ICD 1 :  1.1 support (with 1 group with 2 devices)
     TestICD& icd1 = env.get_test_icd(1);
-    icd1.physical_devices.emplace_back("physical_device_1").set_api_version(VK_API_VERSION_1_1);
-    icd1.physical_devices.emplace_back("physical_device_2").set_api_version(VK_API_VERSION_1_1);
-    icd1.physical_device_groups.emplace_back(icd1.physical_devices[0]);
-    icd1.physical_device_groups.back().use_physical_device(icd1.physical_devices[1]);
+    auto& pd1 = icd1.add_and_get_physical_device("physical_device_1").set_api_version(VK_API_VERSION_1_1);
+    auto& pd2 = icd1.add_and_get_physical_device("physical_device_2").set_api_version(VK_API_VERSION_1_1);
+    icd1.physical_device_groups.emplace_back(pd1);
+    icd1.physical_device_groups.back().use_physical_device(pd2);
     icd1.min_icd_interface_version = 5;
     icd1.max_icd_interface_version = 5;
     icd1.set_icd_api_version(VK_API_VERSION_1_1);
 
     // ICD 2 :  No 1.1 support (so 3 devices will become 3 groups in loader)
     TestICD& icd2 = env.get_test_icd(2);
-    icd2.physical_devices.emplace_back("physical_device_3");
-    icd2.physical_devices.emplace_back("physical_device_4");
-    icd2.physical_devices.emplace_back("physical_device_5");
+    icd2.add_and_get_physical_device("physical_device_3");
+    icd2.add_and_get_physical_device("physical_device_4");
+    icd2.add_and_get_physical_device("physical_device_5");
     icd2.min_icd_interface_version = 5;
     icd2.max_icd_interface_version = 5;
     icd2.set_icd_api_version(VK_API_VERSION_1_0);
@@ -472,37 +477,31 @@
     FrameworkEnvironment env;
 
     const char* regular_layer_name = "VK_LAYER_TestLayer1";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(regular_layer_name)
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
-                                                         .set_disable_environment("DisableMeIfYouCan")),
-                           "regular_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(regular_layer_name)
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
+                                                             .set_disable_environment("DisableMeIfYouCan")));
 
     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
 
     uint32_t physical_count = 0;
     for (uint32_t i = 0; i < 3; i++) {
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES));
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+        env.add_icd((TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES));
+        env.add_icd(TEST_ICD_PATH_VERSION_2);
         auto& driver_5 = env.get_test_icd(i * 2 + 1);
         driver_5.set_max_icd_interface_version(5);
         driver_5.set_min_icd_interface_version(5);
         driver_5.setup_WSI();
-        driver_5.physical_devices.push_back({});
-        driver_5.physical_devices.back().queue_family_properties.push_back(family_props);
-        driver_5.physical_devices.push_back({});
-        driver_5.physical_devices.back().queue_family_properties.push_back(family_props);
-        driver_5.physical_devices.push_back({});
-        driver_5.physical_devices.back().queue_family_properties.push_back(family_props);
+        driver_5.add_and_get_physical_device({}).queue_family_properties.push_back(family_props);
+        driver_5.add_and_get_physical_device({}).queue_family_properties.push_back(family_props);
+        driver_5.add_and_get_physical_device({}).queue_family_properties.push_back(family_props);
         physical_count += static_cast<uint32_t>(driver_5.physical_devices.size());
 
         auto& driver_6 = env.get_test_icd(i * 2);
         driver_6.setup_WSI();
-        driver_6.physical_devices.emplace_back("physical_device_0");
-        driver_6.physical_devices.back().queue_family_properties.push_back(family_props);
-        driver_6.physical_devices.emplace_back("physical_device_1");
-        driver_6.physical_devices.back().queue_family_properties.push_back(family_props);
+        driver_6.add_and_get_physical_device("physical_device_0").queue_family_properties.push_back(family_props);
+        driver_6.add_and_get_physical_device("physical_device_1").queue_family_properties.push_back(family_props);
         physical_count += static_cast<uint32_t>(driver_6.physical_devices.size());
 
         driver_6.set_max_icd_interface_version(6);
@@ -589,8 +588,9 @@
 
 TEST(MinorVersionUpdate, Version1_3) {
     FrameworkEnvironment env{};
-    auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
-    driver.physical_devices.back().known_device_functions = {
+    auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
+    auto& pd = driver.add_and_get_physical_device({});
+    pd.known_device_functions = {
         VulkanFunction{"vkCmdBeginRendering", to_vkVoidFunction(test_vkCmdBeginRendering)},
         VulkanFunction{"vkCmdBindVertexBuffers2", to_vkVoidFunction(test_vkCmdBindVertexBuffers2)},
         VulkanFunction{"vkCmdBlitImage2", to_vkVoidFunction(test_vkCmdBlitImage2)},
@@ -629,7 +629,7 @@
         VulkanFunction{"vkQueueSubmit2", to_vkVoidFunction(test_vkQueueSubmit2)},
         VulkanFunction{"vkSetPrivateData", to_vkVoidFunction(test_vkSetPrivateData)},
     };
-    driver.physical_devices.back().add_extension({"VK_SOME_EXT_haha"});
+    pd.add_extension({"VK_SOME_EXT_haha"});
     InstWrapper inst{env.vulkan_functions};
     inst.create_info.set_api_version(1, 3, 0);
     inst.CheckCreate();
@@ -775,7 +775,7 @@
 
 TEST(ApplicationInfoVersion, NonVulkanVariant) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     DebugUtilsLogger log;
     InstWrapper inst{env.vulkan_functions};
@@ -789,7 +789,8 @@
 
 TEST(DriverManifest, NonVulkanVariant) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(1, 1, 0, 0))).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_MAKE_API_VERSION(1, 1, 0, 0)))
+        .add_physical_device({});
 
     DebugUtilsLogger log;
     InstWrapper inst{env.vulkan_functions};
@@ -803,15 +804,15 @@
 
 TEST(LayerManifest, ImplicitNonVulkanVariant) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 0, 0))).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0)))
+        .add_physical_device({});
 
     const char* implicit_layer_name = "ImplicitTestLayer";
-    env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(implicit_layer_name)
-                                                         .set_api_version(VK_MAKE_API_VERSION(1, 1, 0, 0))
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                                         .set_disable_environment("DISABLE_ME")),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(implicit_layer_name)
+                                                             .set_api_version(VK_MAKE_API_VERSION(1, 1, 0, 0))
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                             .set_disable_environment("DISABLE_ME")));
 
     DebugUtilsLogger log;
     InstWrapper inst{env.vulkan_functions};
@@ -824,14 +825,14 @@
 
 TEST(LayerManifest, ExplicitNonVulkanVariant) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 0, 0))).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0)))
+        .add_physical_device({});
 
     const char* explicit_layer_name = "ExplicitTestLayer";
-    env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
-                                                         .set_name(explicit_layer_name)
-                                                         .set_api_version(VK_MAKE_API_VERSION(1, 1, 0, 0))
-                                                         .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-                           "explicit_test_layer.json");
+    env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                             .set_name(explicit_layer_name)
+                                                             .set_api_version(VK_MAKE_API_VERSION(1, 1, 0, 0))
+                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));
 
     DebugUtilsLogger log;
     InstWrapper inst{env.vulkan_functions};
@@ -844,8 +845,8 @@
 
 TEST(DriverManifest, UnknownManifestVersion) {
     FrameworkEnvironment env{};
-    env.add_icd(
-           TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_file_format_version({3, 2, 1})))
+
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_file_format_version({3, 2, 1}))
         .add_physical_device({});
 
     DebugUtilsLogger log;
@@ -860,8 +861,7 @@
 
 TEST(DriverManifest, LargeUnknownManifestVersion) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(
-                    ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_file_format_version({100, 222, 111})))
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, {}, ManifestICD{}.set_file_format_version({100, 222, 111}))
         .add_physical_device({});
 
     DebugUtilsLogger log;
@@ -876,17 +876,16 @@
 
 TEST(LayerManifest, UnknownManifestVersion) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* implicit_layer_name = "ImplicitTestLayer";
-    env.add_implicit_layer(ManifestLayer{}
-                               .add_layer(ManifestLayer::LayerDescription{}
-                                              .set_name(implicit_layer_name)
-                                              .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
-                                              .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                              .set_disable_environment("DISABLE_ME"))
-                               .set_file_format_version({3, 2, 1}),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}
+                                   .add_layer(ManifestLayer::LayerDescription{}
+                                                  .set_name(implicit_layer_name)
+                                                  .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
+                                                  .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                  .set_disable_environment("DISABLE_ME"))
+                                   .set_file_format_version({3, 2, 1}));
 
     DebugUtilsLogger log;
     InstWrapper inst{env.vulkan_functions};
@@ -900,17 +899,16 @@
 
 TEST(LayerManifest, LargeUnknownManifestVersion) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).add_physical_device({});
 
     const char* implicit_layer_name = "ImplicitTestLayer";
-    env.add_implicit_layer(ManifestLayer{}
-                               .add_layer(ManifestLayer::LayerDescription{}
-                                              .set_name(implicit_layer_name)
-                                              .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
-                                              .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
-                                              .set_disable_environment("DISABLE_ME"))
-                               .set_file_format_version({100, 222, 111}),
-                           "implicit_test_layer.json");
+    env.add_implicit_layer({}, ManifestLayer{}
+                                   .add_layer(ManifestLayer::LayerDescription{}
+                                                  .set_name(implicit_layer_name)
+                                                  .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
+                                                  .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+                                                  .set_disable_environment("DISABLE_ME"))
+                                   .set_file_format_version({100, 222, 111}));
 
     DebugUtilsLogger log;
     InstWrapper inst{env.vulkan_functions};
@@ -923,9 +921,11 @@
 }
 
 struct DriverInfo {
-    DriverInfo(TestICDDetails icd_details, uint32_t driver_version, bool expect_to_find) noexcept
-        : icd_details(icd_details), driver_version(driver_version), expect_to_find(expect_to_find) {}
-    TestICDDetails icd_details;
+    DriverInfo(std::filesystem::path const& path, ManifestOptions creation_args, uint32_t driver_version,
+               bool expect_to_find) noexcept
+        : path(path), creation_args(creation_args), driver_version(driver_version), expect_to_find(expect_to_find) {}
+    std::filesystem::path path;
+    ManifestOptions creation_args;
     uint32_t driver_version = 0;
     bool expect_to_find = false;
 };
@@ -936,12 +936,11 @@
     uint32_t expected_driver_count = 0;
 
     for (auto const& driver : direct_drivers) {
-        auto& direct_driver_icd = env.add_icd(driver.icd_details);
-        direct_driver_icd.physical_devices.push_back({});
-        direct_driver_icd.physical_devices.at(0).properties.driverVersion = driver.driver_version;
+        auto& direct_driver_icd = env.add_icd(driver.path, driver.creation_args);
+        direct_driver_icd.add_and_get_physical_device({}).properties.driverVersion = driver.driver_version;
         VkDirectDriverLoadingInfoLUNARG ddl_info{};
         ddl_info.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
-        ddl_info.pfnGetInstanceProcAddr = env.icds.back().icd_library.get_symbol("vk_icdGetInstanceProcAddr");
+        ddl_info.pfnGetInstanceProcAddr = env.icds.back().library.get_symbol("vk_icdGetInstanceProcAddr");
         ddl_infos.push_back(ddl_info);
         if (driver.expect_to_find) {
             expected_driver_count++;
@@ -949,9 +948,8 @@
     }
 
     for (auto const& driver : normal_drivers) {
-        auto& direct_driver_icd = env.add_icd(driver.icd_details);
-        direct_driver_icd.physical_devices.push_back({});
-        direct_driver_icd.physical_devices.at(0).properties.driverVersion = driver.driver_version;
+        auto& direct_driver_icd = env.add_icd(driver.path, driver.creation_args);
+        direct_driver_icd.add_and_get_physical_device({}).properties.driverVersion = driver.driver_version;
         if (!exclusive && driver.expect_to_find) {
             expected_driver_count++;
         }
@@ -1019,7 +1017,8 @@
     FrameworkEnvironment env{};
     std::vector<DriverInfo> normal_drivers;
     std::vector<DriverInfo> direct_drivers;
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 10, true);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 10,
+                                true);
 
     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, false));
 }
@@ -1029,8 +1028,10 @@
     FrameworkEnvironment env{};
     std::vector<DriverInfo> normal_drivers;
     std::vector<DriverInfo> direct_drivers;
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 13, true);
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 7, true);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 13,
+                                true);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 7,
+                                true);
     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, false));
 }
 
@@ -1039,9 +1040,11 @@
     FrameworkEnvironment env{};
     std::vector<DriverInfo> normal_drivers;
     std::vector<DriverInfo> direct_drivers;
-    normal_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA), 90, true);
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 80, true);
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 70, true);
+    normal_drivers.emplace_back(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, ManifestOptions{}, 90, true);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 80,
+                                true);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 70,
+                                true);
     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, false));
 }
 
@@ -1050,8 +1053,9 @@
     FrameworkEnvironment env{};
     std::vector<DriverInfo> normal_drivers;
     std::vector<DriverInfo> direct_drivers;
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 33, true);
-    normal_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_2), 44, false);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 33,
+                                true);
+    normal_drivers.emplace_back(TEST_ICD_PATH_VERSION_2, ManifestOptions{}, 44, false);
     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, true));
 }
 
@@ -1059,9 +1063,10 @@
     FrameworkEnvironment env{};
     std::vector<DriverInfo> normal_drivers;
     std::vector<DriverInfo> direct_drivers;
-    normal_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_2), 55, true);
-    normal_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_2), 66, true);
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 77, true);
+    normal_drivers.emplace_back(TEST_ICD_PATH_VERSION_2, ManifestOptions{}, 55, true);
+    normal_drivers.emplace_back(TEST_ICD_PATH_VERSION_2, ManifestOptions{}, 66, true);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 77,
+                                true);
     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, true));
 }
 
@@ -1069,9 +1074,10 @@
     FrameworkEnvironment env{};
     std::vector<DriverInfo> normal_drivers;
     std::vector<DriverInfo> direct_drivers;
-    normal_drivers.emplace_back(
-        TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::env_var), 4, false);
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 5, true);
+    normal_drivers.emplace_back(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA,
+                                ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::env_var), 4, false);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 5,
+                                true);
     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, true));
 }
 
@@ -1080,9 +1086,10 @@
     std::vector<DriverInfo> normal_drivers;
     std::vector<DriverInfo> direct_drivers;
 
-    normal_drivers.emplace_back(
-        TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::add_env_var), 6, false);
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 7, true);
+    normal_drivers.emplace_back(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA,
+                                ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::add_env_var), 6, false);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 7,
+                                true);
     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, true));
 }
 
@@ -1093,9 +1100,10 @@
 
     EnvVarWrapper driver_filter_select_env_var{"VK_LOADER_DRIVERS_SELECT", "normal_driver.json"};
 
-    normal_drivers.emplace_back(
-        TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_disable_icd_inc(true).set_json_name("normal_driver"), 8, true);
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 9, true);
+    normal_drivers.emplace_back(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, ManifestOptions{}.set_json_name("normal_driver.json"), 8,
+                                true);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 9,
+                                true);
 
     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, false));
 }
@@ -1107,10 +1115,10 @@
 
     EnvVarWrapper driver_filter_select_env_var{"VK_LOADER_DRIVERS_SELECT", "normal_driver.json"};
 
-    normal_drivers.emplace_back(
-        TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_disable_icd_inc(true).set_json_name("normal_driver"), 10,
-        false);
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 11, true);
+    normal_drivers.emplace_back(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, ManifestOptions{}.set_json_name("normal_driver.json"), 10,
+                                false);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 11,
+                                true);
 
     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, true));
 }
@@ -1122,10 +1130,10 @@
 
     EnvVarWrapper driver_filter_disable_env_var{"VK_LOADER_DRIVERS_DISABLE", "normal_driver.json"};
 
-    normal_drivers.emplace_back(
-        TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_disable_icd_inc(true).set_json_name("normal_driver"), 12,
-        false);
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 13, true);
+    normal_drivers.emplace_back(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, ManifestOptions{}.set_json_name("normal_driver.json"), 12,
+                                false);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 13,
+                                true);
     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, false));
 }
 
@@ -1136,10 +1144,10 @@
 
     EnvVarWrapper driver_filter_disable_env_var{"VK_LOADER_DRIVERS_DISABLE", "normal_driver.json"};
 
-    normal_drivers.emplace_back(
-        TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_disable_icd_inc(true).set_json_name("normal_driver"), 14,
-        false);
-    direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 15, true);
+    normal_drivers.emplace_back(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, ManifestOptions{}.set_json_name("normal_driver.json"), 14,
+                                false);
+    direct_drivers.emplace_back(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none), 15,
+                                true);
     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, true));
 }
 
@@ -1147,12 +1155,13 @@
 TEST(DirectDriverLoading, ExtensionNotEnabled) {
     FrameworkEnvironment env{};
 
-    auto& direct_driver_icd = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none));
-    direct_driver_icd.physical_devices.push_back({});
+    auto& direct_driver_icd =
+        env.add_icd(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none));
+    direct_driver_icd.add_physical_device({});
 
     VkDirectDriverLoadingInfoLUNARG ddl_info{};
     ddl_info.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
-    ddl_info.pfnGetInstanceProcAddr = env.icds.back().icd_library.get_symbol("vk_icdGetInstanceProcAddr");
+    ddl_info.pfnGetInstanceProcAddr = env.icds.back().library.get_symbol("vk_icdGetInstanceProcAddr");
 
     VkDirectDriverLoadingListLUNARG ddl_list{};
     ddl_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
@@ -1177,7 +1186,7 @@
 TEST(DirectDriverLoading, DriverListNotInPnextChain) {
     FrameworkEnvironment env{};
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none)).add_physical_device({});
 
     DebugUtilsLogger log;
     InstWrapper inst{env.vulkan_functions};
@@ -1196,7 +1205,7 @@
 TEST(DirectDriverLoading, DriverListHasNullDriverPointer) {
     FrameworkEnvironment env{};
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none)).add_physical_device({});
 
     VkDirectDriverLoadingListLUNARG ddl_list{};
     ddl_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
@@ -1221,11 +1230,11 @@
 TEST(DirectDriverLoading, DriverListHasZeroInfoCount) {
     FrameworkEnvironment env{};
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none)).add_physical_device({});
 
     VkDirectDriverLoadingInfoLUNARG ddl_info{};
     ddl_info.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
-    ddl_info.pfnGetInstanceProcAddr = env.icds.back().icd_library.get_symbol("vk_icdGetInstanceProcAddr");
+    ddl_info.pfnGetInstanceProcAddr = env.icds.back().library.get_symbol("vk_icdGetInstanceProcAddr");
 
     VkDirectDriverLoadingListLUNARG ddl_list{};
     ddl_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
@@ -1251,7 +1260,7 @@
 TEST(DirectDriverLoading, DriverInfoMissingGetInstanceProcAddr) {
     FrameworkEnvironment env{};
 
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none)).add_physical_device({});
+    env.add_icd(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none)).add_physical_device({});
 
     std::array<VkDirectDriverLoadingInfoLUNARG, 2> ddl_infos{};
     ddl_infos[0].sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
@@ -1286,7 +1295,7 @@
 TEST(DirectDriverLoading, DriverDoesNotExportNegotiateFunction) {
     FrameworkEnvironment env{};
 
-    auto& direct_driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none))
+    auto& direct_driver = env.add_icd(TEST_ICD_PATH_VERSION_7, ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::none))
                               .add_physical_device({})
                               .set_exposes_vk_icdNegotiateLoaderICDInterfaceVersion(false)
                               .set_exposes_vkCreateInstance(false)
@@ -1294,7 +1303,7 @@
 
     VkDirectDriverLoadingInfoLUNARG ddl_info{};
     ddl_info.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
-    ddl_info.pfnGetInstanceProcAddr = env.icds.back().icd_library.get_symbol("vk_icdGetInstanceProcAddr");
+    ddl_info.pfnGetInstanceProcAddr = env.icds.back().library.get_symbol("vk_icdGetInstanceProcAddr");
 
     VkDirectDriverLoadingListLUNARG ddl_list{};
     ddl_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
@@ -1371,7 +1380,7 @@
 
 TEST(DriverManifest, VersionMismatchWithEnumerateInstanceVersion) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
         .set_icd_api_version(VK_API_VERSION_1_0)
         .add_physical_device({});
 
@@ -1388,7 +1397,7 @@
 
 TEST(DriverManifest, EnumerateInstanceVersionNotSupported) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
+    env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1))
         .set_icd_api_version(VK_API_VERSION_1_0)
         .set_can_query_vkEnumerateInstanceVersion(false)
         .add_physical_device({});
diff --git a/tests/loader_wsi_tests.cpp b/tests/loader_wsi_tests.cpp
index a33bee1..c77ffba 100644
--- a/tests/loader_wsi_tests.cpp
+++ b/tests/loader_wsi_tests.cpp
@@ -34,7 +34,7 @@
 // When ICD doesn't support the extension, create instance should fail
 TEST(WsiTests, CreateSurfaceWin32NoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
 
@@ -51,7 +51,7 @@
 // When ICD doesn't support the surface creation, the loader should handle it
 TEST(WsiTests, CreateSurfaceWin32NoICDCreateSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
@@ -73,7 +73,7 @@
 // When ICD does support the surface creation, the loader should  delegat handle it to the ICD
 TEST(WsiTests, CreateSurfaceWin32ICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
@@ -98,7 +98,7 @@
     for (uint32_t icd = 0; icd < 3; ++icd) {
         Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
         Extension second_ext{VK_KHR_WIN32_SURFACE_EXTENSION_NAME};
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+        env.add_icd(TEST_ICD_PATH_VERSION_2);
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.add_instance_extensions({first_ext, second_ext});
@@ -122,12 +122,12 @@
 
 TEST(WsiTests, GetPhysicalDeviceWin32PresentNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
     cur_icd.add_instance_extension({VK_KHR_WIN32_SURFACE_EXTENSION_NAME});
-    cur_icd.physical_devices.emplace_back("physical_device_0");
+    cur_icd.add_and_get_physical_device("physical_device_0");
     cur_icd.enable_icd_wsi = false;
 
     InstWrapper inst{env.vulkan_functions};
@@ -149,12 +149,12 @@
 
 TEST(WsiTests, GetPhysicalDeviceWin32PresentICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
     cur_icd.add_instance_extension({VK_KHR_WIN32_SURFACE_EXTENSION_NAME});
-    cur_icd.physical_devices.emplace_back("physical_device_0");
+    cur_icd.add_and_get_physical_device("physical_device_0");
     cur_icd.enable_icd_wsi = true;
 
     InstWrapper inst{env.vulkan_functions};
@@ -175,14 +175,14 @@
     for (uint32_t icd = 0; icd < max_device_count; ++icd) {
         Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
         Extension second_ext{VK_KHR_WIN32_SURFACE_EXTENSION_NAME};
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+        env.add_icd(TEST_ICD_PATH_VERSION_2);
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.set_min_icd_interface_version(5);
         cur_icd.add_instance_extensions({first_ext, second_ext});
         std::string dev_name = "phys_dev_" + std::to_string(icd);
-        cur_icd.physical_devices.emplace_back(dev_name.c_str());
-        cur_icd.physical_devices.back().add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true});
+        cur_icd.add_and_get_physical_device(dev_name.c_str())
+            .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true});
         cur_icd.enable_icd_wsi = true;
     }
 
@@ -203,6 +203,7 @@
     for (uint32_t pd = 0; pd < max_device_count; ++pd) {
         VkBool32 supported = VK_FALSE;
         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(phys_devs[pd], 0, surface, &supported));
+        ASSERT_EQ(VK_TRUE, supported);
     }
 
     env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
@@ -213,7 +214,7 @@
 // When ICD doesn't support the extension, create instance should fail
 TEST(WsiTests, CreateSurfaceXCBNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.enable_icd_wsi = false;
@@ -231,7 +232,7 @@
 // When ICD doesn't support the surface creation, the loader should handle it
 TEST(WsiTests, CreateSurfaceXCBNoICDCreateSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
@@ -254,7 +255,7 @@
 // When ICD does support the surface creation, the loader should  delegat handle it to the ICD
 TEST(WsiTests, CreateSurfaceXCBICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
@@ -280,7 +281,7 @@
     for (uint32_t icd = 0; icd < 3; ++icd) {
         Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
         Extension second_ext{VK_KHR_XCB_SURFACE_EXTENSION_NAME};
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+        env.add_icd(TEST_ICD_PATH_VERSION_2);
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.add_instance_extensions({first_ext, second_ext});
@@ -305,12 +306,12 @@
 
 TEST(WsiTests, GetPhysicalDeviceXcbPresentNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
     cur_icd.add_instance_extension({VK_KHR_XCB_SURFACE_EXTENSION_NAME});
-    cur_icd.physical_devices.emplace_back("physical_device_0");
+    cur_icd.add_and_get_physical_device("physical_device_0");
     cur_icd.enable_icd_wsi = false;
 
     InstWrapper inst{env.vulkan_functions};
@@ -332,12 +333,12 @@
 
 TEST(WsiTests, GetPhysicalDeviceXcbPresentICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
     cur_icd.add_instance_extension({VK_KHR_XCB_SURFACE_EXTENSION_NAME});
-    cur_icd.physical_devices.emplace_back("physical_device_0");
+    cur_icd.add_and_get_physical_device("physical_device_0");
     cur_icd.enable_icd_wsi = true;
 
     InstWrapper inst{env.vulkan_functions};
@@ -358,14 +359,14 @@
     for (uint32_t icd = 0; icd < max_device_count; ++icd) {
         Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
         Extension second_ext{VK_KHR_XCB_SURFACE_EXTENSION_NAME};
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+        env.add_icd(TEST_ICD_PATH_VERSION_2);
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.set_min_icd_interface_version(5);
         cur_icd.add_instance_extensions({first_ext, second_ext});
         std::string dev_name = "phys_dev_" + std::to_string(icd);
-        cur_icd.physical_devices.emplace_back(dev_name.c_str());
-        cur_icd.physical_devices.back().add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true});
+        cur_icd.add_and_get_physical_device(dev_name.c_str())
+            .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true});
         cur_icd.enable_icd_wsi = true;
     }
 
@@ -386,6 +387,7 @@
     for (uint32_t pd = 0; pd < max_device_count; ++pd) {
         VkBool32 supported = VK_FALSE;
         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(phys_devs[pd], 0, surface, &supported));
+        ASSERT_EQ(VK_TRUE, supported);
     }
 
     env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
@@ -396,7 +398,7 @@
 // When ICD doesn't support the extension, create instance should fail
 TEST(WsiTests, CreateSurfaceXLIBNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.enable_icd_wsi = false;
@@ -414,7 +416,7 @@
 // When ICD doesn't support the surface creation, the loader should handle it
 TEST(WsiTests, CreateSurfaceXLIBNoICDCreateSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
@@ -437,7 +439,7 @@
 // When ICD does support the surface creation, the loader should  delegat handle it to the ICD
 TEST(WsiTests, CreateSurfaceXLIBICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
@@ -463,7 +465,7 @@
     for (uint32_t icd = 0; icd < 3; ++icd) {
         Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
         Extension second_ext{VK_KHR_XLIB_SURFACE_EXTENSION_NAME};
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+        env.add_icd(TEST_ICD_PATH_VERSION_2);
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.add_instance_extensions({first_ext, second_ext});
@@ -488,12 +490,12 @@
 
 TEST(WsiTests, GetPhysicalDeviceXlibPresentNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
     cur_icd.add_instance_extension({VK_KHR_XLIB_SURFACE_EXTENSION_NAME});
-    cur_icd.physical_devices.emplace_back("physical_device_0");
+    cur_icd.add_and_get_physical_device("physical_device_0");
     cur_icd.enable_icd_wsi = false;
 
     InstWrapper inst{env.vulkan_functions};
@@ -515,12 +517,12 @@
 
 TEST(WsiTests, GetPhysicalDeviceXlibPresentICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
     cur_icd.add_instance_extension({VK_KHR_XLIB_SURFACE_EXTENSION_NAME});
-    cur_icd.physical_devices.emplace_back("physical_device_0");
+    cur_icd.add_and_get_physical_device("physical_device_0");
     cur_icd.enable_icd_wsi = true;
 
     InstWrapper inst{env.vulkan_functions};
@@ -541,14 +543,14 @@
     for (uint32_t icd = 0; icd < max_device_count; ++icd) {
         Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
         Extension second_ext{VK_KHR_XLIB_SURFACE_EXTENSION_NAME};
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+        env.add_icd(TEST_ICD_PATH_VERSION_2);
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.set_min_icd_interface_version(5);
         cur_icd.add_instance_extensions({first_ext, second_ext});
         std::string dev_name = "phys_dev_" + std::to_string(icd);
-        cur_icd.physical_devices.emplace_back(dev_name.c_str());
-        cur_icd.physical_devices.back().add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true});
+        cur_icd.add_and_get_physical_device(dev_name.c_str())
+            .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true});
         cur_icd.enable_icd_wsi = true;
     }
 
@@ -569,6 +571,7 @@
     for (uint32_t pd = 0; pd < max_device_count; ++pd) {
         VkBool32 supported = VK_FALSE;
         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(phys_devs[pd], 0, surface, &supported));
+        ASSERT_EQ(VK_TRUE, supported);
     }
 
     env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
@@ -579,7 +582,7 @@
 // When ICD doesn't support the extension, create instance should fail
 TEST(WsiTests, CreateSurfaceWaylandNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.enable_icd_wsi = false;
@@ -597,7 +600,7 @@
 // When ICD doesn't support the surface creation, the loader should handle it
 TEST(WsiTests, CreateSurfaceWaylandNoICDCreateSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
@@ -620,7 +623,7 @@
 // When ICD does support the surface creation, the loader should  delegat handle it to the ICD
 TEST(WsiTests, CreateSurfaceWaylandICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
@@ -646,7 +649,7 @@
     for (uint32_t icd = 0; icd < 3; ++icd) {
         Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
         Extension second_ext{VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME};
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+        env.add_icd(TEST_ICD_PATH_VERSION_2);
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.add_instance_extensions({first_ext, second_ext});
@@ -671,12 +674,12 @@
 
 TEST(WsiTests, GetPhysicalDeviceWaylandPresentNoICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
     cur_icd.add_instance_extension({VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
-    cur_icd.physical_devices.emplace_back("physical_device_0");
+    cur_icd.add_and_get_physical_device("physical_device_0");
     cur_icd.enable_icd_wsi = false;
 
     InstWrapper inst{env.vulkan_functions};
@@ -698,12 +701,12 @@
 
 TEST(WsiTests, GetPhysicalDeviceWaylandPresentICDSupport) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+    env.add_icd(TEST_ICD_PATH_VERSION_2);
     auto& cur_icd = env.get_test_icd(0);
     cur_icd.set_min_icd_interface_version(5);
     cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
     cur_icd.add_instance_extension({VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
-    cur_icd.physical_devices.emplace_back("physical_device_0");
+    cur_icd.add_and_get_physical_device("physical_device_0");
     cur_icd.enable_icd_wsi = true;
 
     InstWrapper inst{env.vulkan_functions};
@@ -724,14 +727,14 @@
     for (uint32_t icd = 0; icd < max_device_count; ++icd) {
         Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
         Extension second_ext{VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME};
-        env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
+        env.add_icd(TEST_ICD_PATH_VERSION_2);
         auto& cur_icd = env.get_test_icd(icd);
         cur_icd.icd_api_version = VK_API_VERSION_1_0;
         cur_icd.set_min_icd_interface_version(5);
         cur_icd.add_instance_extensions({first_ext, second_ext});
         std::string dev_name = "phys_dev_" + std::to_string(icd);
-        cur_icd.physical_devices.emplace_back(dev_name.c_str());
-        cur_icd.physical_devices.back().add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true});
+        cur_icd.add_and_get_physical_device(dev_name.c_str())
+            .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true});
         cur_icd.enable_icd_wsi = true;
     }
 
@@ -752,15 +755,78 @@
     for (uint32_t pd = 0; pd < max_device_count; ++pd) {
         VkBool32 supported = VK_FALSE;
         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(phys_devs[pd], 0, surface, &supported));
+        ASSERT_EQ(VK_TRUE, supported);
     }
 
     env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
 }
 #endif
 
+TEST(WsiTests, GoogleSurfaceslessQuery) {
+    std::vector<VkPresentModeKHR> present_modes{VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR,
+                                                VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR};
+    VkSurfaceFormatKHR surface_format = {VK_FORMAT_R8G8B8A8_SRGB, VK_COLORSPACE_SRGB_NONLINEAR_KHR};
+    FrameworkEnvironment env{};
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
+        .setup_WSI()
+        .add_instance_extension("VK_GOOGLE_surfaceless_query")
+        .add_instance_extension("VK_KHR_get_surface_capabilities2")
+        .add_physical_device(PhysicalDevice{}
+                                 .add_extension("VK_KHR_swapchain")
+#if defined(WIN32)
+                                 .add_extension("VK_EXT_full_screen_exclusive")
+#endif
+                                 .add_surface_format(surface_format)
+                                 .add_surface_present_modes(present_modes)
+                                 .finish());
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.add_extension("VK_KHR_surface");
+    inst.create_info.add_extension("VK_GOOGLE_surfaceless_query");
+    ASSERT_NO_FATAL_FAILURE(inst.CheckCreate());
+
+    VkPhysicalDevice physical_device = inst.GetPhysDev();
+
+    uint32_t present_mode_count = 4;
+    std::vector<VkPresentModeKHR> queried_present_modes{present_mode_count};
+    inst->vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, VK_NULL_HANDLE, &present_mode_count,
+                                                    queried_present_modes.data());
+    ASSERT_EQ(present_modes, queried_present_modes);
+
+    uint32_t surface_format_count = 1;
+    std::vector<VkSurfaceFormatKHR> queried_surface_formats{surface_format_count};
+    inst->vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, VK_NULL_HANDLE, &surface_format_count,
+                                               queried_surface_formats.data());
+    ASSERT_EQ(std::vector<VkSurfaceFormatKHR>{surface_format}, queried_surface_formats);
+
+    uint32_t surface_format2_count = 1;
+    std::vector<VkSurfaceFormat2KHR> queried_surface_formats2{surface_format2_count};
+    VkPhysicalDeviceSurfaceInfo2KHR surface_info{};
+    surface_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR;
+    surface_info.surface = VK_NULL_HANDLE;
+    inst->vkGetPhysicalDeviceSurfaceFormats2KHR(physical_device, &surface_info, &surface_format_count,
+                                                queried_surface_formats2.data());
+    ASSERT_EQ(std::vector<VkSurfaceFormatKHR>{surface_format}, queried_surface_formats2);
+
+    VkSurfaceCapabilities2KHR surface_caps2{};
+    surface_caps2.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR;
+
+    ASSERT_EQ(VK_SUCCESS,
+              env.vulkan_functions.vkGetPhysicalDeviceSurfaceCapabilities2KHR(physical_device, &surface_info, &surface_caps2));
+
+#if defined(WIN32)
+    PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT pfn_vkGetPhysicalDeviceSurfacePresentModes2EXT =
+        inst.load("vkGetPhysicalDeviceSurfacePresentModes2EXT");
+    ASSERT_EQ(VK_SUCCESS, pfn_vkGetPhysicalDeviceSurfacePresentModes2EXT(physical_device, &surface_info, &present_mode_count,
+                                                                         queried_present_modes.data()));
+    ASSERT_EQ(present_modes, queried_present_modes);
+
+#endif
+}
+
 TEST(WsiTests, ForgetEnableSurfaceExtensions) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
         .setup_WSI()
         .add_physical_device(PhysicalDevice{}.add_extension("VK_KHR_swapchain").finish());
 
@@ -774,7 +840,7 @@
 
 TEST(WsiTests, SwapchainFunctional) {
     FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
         .setup_WSI()
         .add_physical_device(PhysicalDevice{}.add_extension("VK_KHR_swapchain").finish());
 
@@ -859,40 +925,41 @@
     VkSurfaceCapabilitiesKHR surface_caps{};
     surface_caps.maxImageExtent = VkExtent2D{300, 300};
     surface_caps.minImageExtent = VkExtent2D{100, 100};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
-        .setup_WSI()
-        .add_instance_extension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)
-        .add_physical_device(PhysicalDevice{}
-                                 .add_extension("VK_KHR_swapchain")
-                                 .set_deviceName("no")
-                                 .set_surface_capabilities(surface_caps)
-                                 .add_surface_present_modes(present_modes)
-                                 .finish());
+    auto& test_physical_device_0 = env.add_icd(TEST_ICD_PATH_VERSION_2)
+                                       .setup_WSI()
+                                       .add_instance_extension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)
+                                       .add_and_get_physical_device(PhysicalDevice{}
+                                                                        .add_extension("VK_KHR_swapchain")
+                                                                        .set_deviceName("no")
+                                                                        .set_surface_capabilities(surface_caps)
+                                                                        .add_surface_present_modes(present_modes)
+                                                                        .finish());
     VkSurfacePresentScalingCapabilitiesEXT scaling_capabilities{};
     scaling_capabilities.supportedPresentScaling = VK_PRESENT_SCALING_ONE_TO_ONE_BIT_EXT;
     scaling_capabilities.supportedPresentGravityX = VK_PRESENT_SCALING_ASPECT_RATIO_STRETCH_BIT_EXT;
     scaling_capabilities.supportedPresentGravityY = VK_PRESENT_SCALING_STRETCH_BIT_EXT;
     scaling_capabilities.minScaledImageExtent = {60, 60};
     scaling_capabilities.maxScaledImageExtent = {1000, 1000};
-    auto& icd2 = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    auto& icd2 = env.add_icd(TEST_ICD_PATH_VERSION_2)
                      .setup_WSI()
                      .add_instance_extension(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME)
-                     .add_instance_extension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)
-                     .add_physical_device(PhysicalDevice{}
-                                              .add_extension("VK_KHR_swapchain")
-                                              .set_deviceName("yes")
-                                              .set_surface_capabilities(surface_caps)
-                                              .add_surface_present_modes(present_modes)
-                                              .set_surface_present_scaling_capabilities(scaling_capabilities)
-                                              .finish());
+                     .add_instance_extension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
+    auto& test_physical_device_1 =
+        icd2.add_and_get_physical_device(PhysicalDevice{}
+                                             .add_extension("VK_KHR_swapchain")
+                                             .set_deviceName("yes")
+                                             .set_surface_capabilities(surface_caps)
+                                             .add_surface_present_modes(present_modes)
+                                             .set_surface_present_scaling_capabilities(scaling_capabilities)
+                                             .finish());
     std::vector<std::vector<VkPresentModeKHR>> compatible_present_modes{
         {VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR},
         {VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR},
         {VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR},
         {VK_PRESENT_MODE_FIFO_RELAXED_KHR, VK_PRESENT_MODE_FIFO_KHR},
     };
-    icd2.physical_devices[0].surface_present_mode_compatibility = compatible_present_modes;
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
+    test_physical_device_1.surface_present_mode_compatibility = compatible_present_modes;
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
         .setup_WSI()
         .add_physical_device(PhysicalDevice{}
                                  .add_extension("VK_KHR_swapchain")
@@ -974,3 +1041,113 @@
         }
     }
 }
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) && defined(VK_USE_PLATFORM_XCB_KHR)
+TEST(WsiTests, MultiPlatformGetPhysicalDeviceSurfaceSupportKHR) {
+    FrameworkEnvironment env{};
+
+    const char* xcb_device_name = "XCB";
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
+        .setup_WSI("VK_USE_PLATFORM_XCB_KHR")
+        .add_physical_device(PhysicalDevice{}
+                                 .set_deviceName(xcb_device_name)
+                                 .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true})
+                                 .finish());
+    const char* wayland_device_name = "WAYLAND";
+    env.add_icd(TEST_ICD_PATH_VERSION_2)
+        .setup_WSI("VK_USE_PLATFORM_WAYLAND_KHR")
+        .add_physical_device(PhysicalDevice{}
+                                 .set_deviceName(wayland_device_name)
+                                 .add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true})
+                                 .finish());
+
+    {
+        // Create instance with only XCB support
+        InstWrapper inst{env.vulkan_functions};
+        inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME});
+        inst.CheckCreate();
+
+        auto phys_devs = inst.GetPhysDevs();
+        // Physical devices are enumerated in reverse order to the ICD order
+        VkPhysicalDevice xcb_physical_device = phys_devs[1];
+        VkPhysicalDevice wayland_physical_device = phys_devs[0];
+        VkPhysicalDeviceProperties props0{};
+        inst->vkGetPhysicalDeviceProperties(wayland_physical_device, &props0);
+        ASSERT_TRUE(string_eq(props0.deviceName, wayland_device_name));
+
+        VkPhysicalDeviceProperties props1{};
+        inst->vkGetPhysicalDeviceProperties(xcb_physical_device, &props1);
+        ASSERT_TRUE(string_eq(props1.deviceName, xcb_device_name));
+
+        VkXcbSurfaceCreateInfoKHR xcb_createInfo{VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR};
+
+        VkSurfaceKHR surface0{VK_NULL_HANDLE};
+        ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateXcbSurfaceKHR(inst, &xcb_createInfo, nullptr, &surface0));
+        ASSERT_TRUE(surface0 != VK_NULL_HANDLE);
+        WrappedHandle<VkSurfaceKHR, VkInstance, PFN_vkDestroySurfaceKHR> wrapped_surface{surface0, inst.inst,
+                                                                                         env.vulkan_functions.vkDestroySurfaceKHR};
+
+        VkWaylandSurfaceCreateInfoKHR wayland_createInfo{VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR};
+
+        VkSurfaceKHR surface1{VK_NULL_HANDLE};
+        ASSERT_EQ(VK_ERROR_EXTENSION_NOT_PRESENT,
+                  env.vulkan_functions.vkCreateWaylandSurfaceKHR(inst, &wayland_createInfo, nullptr, &surface1));
+
+        // Use the successful surface
+
+        VkBool32 supported0 = VK_FALSE;
+        ASSERT_EQ(VK_SUCCESS,
+                  env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(xcb_physical_device, 0, surface0, &supported0));
+        ASSERT_EQ(VK_TRUE, supported0);
+
+        VkBool32 supported1 = VK_FALSE;
+        ASSERT_EQ(VK_SUCCESS,
+                  env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(wayland_physical_device, 0, surface0, &supported1));
+        ASSERT_EQ(VK_FALSE, supported1);
+    }
+
+    {
+        // Create instance with only WAYLAND support
+
+        InstWrapper inst{env.vulkan_functions};
+        inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
+        inst.CheckCreate();
+
+        auto phys_devs = inst.GetPhysDevs();
+        // Physical devices are enumerated in reverse order to the ICD order
+        VkPhysicalDevice xcb_physical_device = phys_devs[1];
+        VkPhysicalDevice wayland_physical_device = phys_devs[0];
+        VkPhysicalDeviceProperties props0{};
+        inst->vkGetPhysicalDeviceProperties(wayland_physical_device, &props0);
+        ASSERT_TRUE(string_eq(props0.deviceName, wayland_device_name));
+
+        VkPhysicalDeviceProperties props1{};
+        inst->vkGetPhysicalDeviceProperties(xcb_physical_device, &props1);
+        ASSERT_TRUE(string_eq(props1.deviceName, xcb_device_name));
+
+        VkXcbSurfaceCreateInfoKHR xcb_createInfo{VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR};
+
+        VkSurfaceKHR surface0{VK_NULL_HANDLE};
+        ASSERT_EQ(VK_ERROR_EXTENSION_NOT_PRESENT,
+                  env.vulkan_functions.vkCreateXcbSurfaceKHR(inst, &xcb_createInfo, nullptr, &surface0));
+
+        VkWaylandSurfaceCreateInfoKHR wayland_createInfo{VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR};
+
+        VkSurfaceKHR surface1{VK_NULL_HANDLE};
+        ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWaylandSurfaceKHR(inst, &wayland_createInfo, nullptr, &surface1));
+        ASSERT_TRUE(surface1 != VK_NULL_HANDLE);
+        WrappedHandle<VkSurfaceKHR, VkInstance, PFN_vkDestroySurfaceKHR> wrapped_surface{surface1, inst.inst,
+                                                                                         env.vulkan_functions.vkDestroySurfaceKHR};
+        // Use the successful surface
+
+        VkBool32 supported0 = VK_FALSE;
+        ASSERT_EQ(VK_SUCCESS,
+                  env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(xcb_physical_device, 0, surface1, &supported0));
+        ASSERT_EQ(VK_FALSE, supported0);
+
+        VkBool32 supported1 = VK_FALSE;
+        ASSERT_EQ(VK_SUCCESS,
+                  env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(wayland_physical_device, 0, surface1, &supported1));
+        ASSERT_EQ(VK_TRUE, supported1);
+    }
+}
+#endif  // defined(VK_USE_PLATFORM_WAYLAND_KHR) && defined(VK_USE_PLATFORM_XCB_KHR)