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 @@ 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/> + VK_LOADER_DEVICE_ID_FILTER=0x7460:0x747e,29827<br/> + <br/> + set<br/> + 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/> + VK_LOADER_VENDOR_ID_FILTER=65541<br/> + <br/> + set<br/> + 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/> + VK_LOADER_DRIVER_ID_FILTER=1-3:13<br/> + <br/> + set<br/> + 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 © 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, ®ular_instance_layers); + res = combine_settings_layers_with_regular_layers(inst, &settings_layers, ®ular_instance_layers, instance_layers); out: @@ -4134,6 +4510,9 @@ } } + // Make sure no layers have the same layerName + loader_remove_duplicate_layers(inst, ®ular_instance_layers); + res = combine_settings_layers_with_regular_layers(inst, &settings_layers, ®ular_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, ®ular_layers->list[i]) || - check_if_layer_is_in_list(settings_layers, ®ular_layers->list[i]); + bool regular_layer_is_ordered = check_if_layer_is_in_list(output_layers, ®ular_layers->list[i], false) || + check_if_layer_is_in_list(settings_layers, ®ular_layers->list[i], false); // If it isn't found, add it if (!regular_layer_is_ordered) { res = loader_append_layer_property(inst, output_layers, ®ular_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)