diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a364bb088..397e9e1fb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,14 +38,15 @@ jobs: 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-22.04, ubuntu-24.04 ] steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: '3.11' - name: Test CMake min @@ -75,16 +76,18 @@ jobs: codegen: runs-on: ubuntu-latest + timeout-minutes: 30 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - 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-24.04 + timeout-minutes: 30 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: sudo apt update - run: sudo apt install --yes --no-install-recommends libwayland-dev libxrandr-dev - run: | @@ -103,12 +106,13 @@ jobs: linux-32: needs: codegen 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@v5 + - uses: actions/setup-python@v6 with: python-version: '3.11' - uses: lukka/get-cmake@latest @@ -141,9 +145,10 @@ jobs: linux-32-no-asm: needs: codegen runs-on: ubuntu-24.04 + timeout-minutes: 30 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: '3.11' - uses: lukka/get-cmake@latest @@ -172,16 +177,43 @@ jobs: - run: cmake --build 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@v5 + - 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 + 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@v5 - run: | cmake -S. -B build ` -D BUILD_TESTS=ON ` @@ -197,11 +229,12 @@ jobs: # 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@v5 - run: | cmake -S. -B build ` -D BUILD_TESTS=ON ` @@ -216,14 +249,15 @@ jobs: # 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@v5 - uses: ilammy/msvc-dev-cmd@v1 - run: | cmake -S. -B build ` @@ -239,92 +273,96 @@ jobs: - run: cmake --install build --prefix build/install mingw: - # windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well - if: false # Disabled due to issues with msys2 making CMake unable to find a working compiler - 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' - - 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 + if: false # Disabled due to issues with msys2 making CMake unable to find a working compiler + runs-on: windows-2022 + timeout-minutes: 30 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v5 + - 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' - - 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@v5 + - 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' - # 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@v5 + - 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 - - 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@v5 + - 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 4cf0807a5..9c5a3e4e9 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -49,11 +49,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 + uses: github/codeql-action/init@16140ae1a102900babc80a33c44059580f687047 # 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,9 +68,9 @@ jobs: # 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@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 + uses: github/codeql-action/autobuild@16140ae1a102900babc80a33c44059580f687047 # v3.29.5 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 if: matrix.language == 'cpp' with: python-version: '3.11' @@ -92,6 +92,6 @@ jobs: run: cmake --build build - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 + uses: github/codeql-action/analyze@16140ae1a102900babc80a33c44059580f687047 # v3.29.5 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 0c6dc2cf7..b49674c9d 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -35,7 +35,7 @@ jobs: - 'loader' - 'tests' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Run clang-format uses: jidicula/clang-format-action@v4.15.0 with: diff --git a/BUILD.md b/BUILD.md index 50c676916..b4ef2463b 100644 --- a/BUILD.md +++ b/BUILD.md @@ -241,7 +241,7 @@ 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 occuring. +be issued but does not stop code generation from occurring. ### Build Options diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f06f846e..9ab168456 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,9 +22,9 @@ cmake_minimum_required(VERSION 3.22.1) set(VULKANSC ON CACHE BOOL "User defined variable for VULKANSC mode to be passed in through cmake command line e.g. -DVULKANSC=ON") if(VULKANSC) - project(VULKAN_LOADER VERSION 1.0.19 LANGUAGES C) + project(VULKAN_LOADER VERSION 1.0.19 LANGUAGES C) # vulkansc else() - project(VULKAN_LOADER VERSION 1.4.319 LANGUAGES C) + project(VULKAN_LOADER VERSION 1.4.330 LANGUAGES C) # vulkan endif() option(CODE_COVERAGE "Enable Code Coverage" OFF) @@ -65,7 +65,7 @@ if(WIN32) 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) include(GNUInstallDirs) @@ -123,7 +123,7 @@ elseif(APPLE) target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_MACOS_MVK) endif() endif() -elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|DragonFly|GNU") +elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|DragonFly|GNU|CYGWIN") if(VULKANSC) option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" OFF) option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" OFF) @@ -269,7 +269,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "MSVC" OR (CMAKE_C_COMPILER_ID STREQUAL "Clang" A # Prevent 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() @@ -280,7 +280,7 @@ endif() target_compile_definitions(loader_common_options INTERFACE $<$: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) @@ -293,7 +293,20 @@ if (NOT (WIN32 OR APPLE)) 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 d51746bd6..f33539600 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -78,7 +78,7 @@ current assignee. * 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/LoaderInterfaceArchitecture.md b/docs/LoaderInterfaceArchitecture.md index a1bf4c8fa..99615a0c0 100644 --- a/docs/LoaderInterfaceArchitecture.md +++ b/docs/LoaderInterfaceArchitecture.md @@ -888,9 +888,7 @@ discovery. Known layers are those which are found by the loader taking into account default search paths and other environment variables (like VK_LAYER_PATH). -
- This has replaced the older deprecated environment variable - VK_INSTANCE_LAYERS + This functionality is only available with Loaders built with version @@ -1045,8 +1043,7 @@ may be removed in a future loader release. ppEnabledLayerNames. - This has been deprecated by VK_LOADER_LAYERS_ENABLE. - It also overrides any layers disabled with + It overrides any layers disabled with VK_LOADER_LAYERS_DISABLE. diff --git a/docs/LoaderLayerInterface.md b/docs/LoaderLayerInterface.md index 1fb4a26f2..a71839b8f 100644 --- a/docs/LoaderLayerInterface.md +++ b/docs/LoaderLayerInterface.md @@ -599,7 +599,7 @@ i.e. they do not require any external context to be enabled, will be enabled. ##### `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 000000000..d73f41076 --- /dev/null +++ b/docs/LoaderSettingsFile.md @@ -0,0 +1,114 @@ + +[![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 + +[![Creative Commons][3]][4] + + + +[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 + +- [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 + + + + + + + + + + + + + +## Behavior diff --git a/docs/images/loader_layer_order.png b/docs/images/loader_layer_order.png index 46cdbd155..4f4efe8c1 100644 Binary files a/docs/images/loader_layer_order.png and b/docs/images/loader_layer_order.png differ diff --git a/docs/images/loader_layer_order_calls.png b/docs/images/loader_layer_order_calls.png index 01dc08ce2..18ca25c42 100644 Binary files a/docs/images/loader_layer_order_calls.png and b/docs/images/loader_layer_order_calls.png differ diff --git a/docs/images/svgs/loader_layer_order.svg b/docs/images/svgs/loader_layer_order.svg index e6cafac17..dd4eca2eb 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" /> + inkscape:pagecheckerboard="0" + inkscape:showpageshadow="2" + inkscape:deskcolor="#d1d1d1" /> @@ -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"> + + + + + + + + + + + + + transform="translate(141.49609,-63.082703)"> + 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" /> + ry="20.9611" /> EnabledEnabledExplicitLayers + + transform="translate(153.49609,-63.082664)"> ImplicitLayers - - - - - - - - - - - - diff --git a/docs/images/svgs/loader_layer_order_calls.svg b/docs/images/svgs/loader_layer_order_calls.svg index 51e2e8e03..098fe892a 100644 --- a/docs/images/svgs/loader_layer_order_calls.svg +++ b/docs/images/svgs/loader_layer_order_calls.svg @@ -1,11 +1,11 @@ - - - - - + gradientTransform="matrix(1.3793103,0,0,1.9195479,1067.8858,-1869.7148)" /> + inkscape:pagecheckerboard="0" + inkscape:showpageshadow="2" + inkscape:deskcolor="#d1d1d1" /> @@ -576,25 +542,25 @@ inkscape:label="Background" transform="translate(0.62160975,46.138115)"> Driver Driver Driver LoaderTerminator @@ -1077,7 +1043,7 @@ + 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" /> + height="139.37927" + x="640" + y="891.2583" + ry="22.649132" /> EnvironmentEnabledEnabledExplicitLayers ApplicationEnabledExplicitLayers - - - - OverrideLayer - - - - - - - - - - - - - - - - - - - - - - diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt index 7d3657ffe..574dcf9c4 100644 --- a/loader/CMakeLists.txt +++ b/loader/CMakeLists.txt @@ -316,7 +316,7 @@ elseif(UNIX OR MINGW OR (WIN32 AND USE_GAS)) # i.e.: Linux & Apple & MinGW & Win 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_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset GAS) else() @@ -401,6 +401,10 @@ if(WIN32) 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) diff --git a/loader/cJSON.h b/loader/cJSON.h index 457d669a5..0bba4995f 100644 --- a/loader/cJSON.h +++ b/loader/cJSON.h @@ -146,7 +146,7 @@ typedef int cJSON_bool; #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. */ diff --git a/loader/generated-vksc/vk_layer_dispatch_table.h b/loader/generated-vksc/vk_layer_dispatch_table.h index 70ead0861..42df608d4 100644 --- a/loader/generated-vksc/vk_layer_dispatch_table.h +++ b/loader/generated-vksc/vk_layer_dispatch_table.h @@ -180,25 +180,44 @@ typedef struct VkLayerDispatchTable_ { 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_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_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_vkCreatePipelineCache CreatePipelineCache; PFN_vkDestroyPipelineCache DestroyPipelineCache; - PFN_vkCreateGraphicsPipelines CreateGraphicsPipelines; PFN_vkCreateComputePipelines CreateComputePipelines; PFN_vkDestroyPipeline DestroyPipeline; PFN_vkCreatePipelineLayout CreatePipelineLayout; @@ -212,19 +231,21 @@ typedef struct VkLayerDispatchTable_ { 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_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; @@ -234,57 +255,30 @@ typedef struct VkLayerDispatchTable_ { 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; PFN_vkBindBufferMemory2 BindBufferMemory2; PFN_vkBindImageMemory2 BindImageMemory2; PFN_vkGetDeviceGroupPeerMemoryFeatures GetDeviceGroupPeerMemoryFeatures; PFN_vkCmdSetDeviceMask CmdSetDeviceMask; - PFN_vkCmdDispatchBase CmdDispatchBase; PFN_vkGetImageMemoryRequirements2 GetImageMemoryRequirements2; PFN_vkGetBufferMemoryRequirements2 GetBufferMemoryRequirements2; PFN_vkGetDeviceQueue2 GetDeviceQueue2; + PFN_vkCmdDispatchBase CmdDispatchBase; + PFN_vkGetDescriptorSetLayoutSupport GetDescriptorSetLayoutSupport; PFN_vkCreateSamplerYcbcrConversion CreateSamplerYcbcrConversion; PFN_vkDestroySamplerYcbcrConversion DestroySamplerYcbcrConversion; - PFN_vkGetDescriptorSetLayoutSupport GetDescriptorSetLayoutSupport; - 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; @@ -292,15 +286,18 @@ typedef struct VkLayerDispatchTable_ { 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; @@ -308,6 +305,12 @@ typedef struct VkLayerDispatchTable_ { 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; @@ -327,28 +330,25 @@ typedef struct VkLayerDispatchTable_ { 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_vkCmdSetRenderingAttachmentLocations CmdSetRenderingAttachmentLocations; - PFN_vkCmdSetRenderingInputAttachmentIndices CmdSetRenderingInputAttachmentIndices; - PFN_vkCmdBindDescriptorSets2 CmdBindDescriptorSets2; - PFN_vkCmdPushConstants2 CmdPushConstants2; - PFN_vkCmdPushDescriptorSet2 CmdPushDescriptorSet2; PFN_vkCopyMemoryToImage CopyMemoryToImage; PFN_vkCopyImageToMemory CopyImageToMemory; PFN_vkCopyImageToImage CopyImageToImage; PFN_vkTransitionImageLayout TransitionImageLayout; + PFN_vkCmdPushDescriptorSet CmdPushDescriptorSet; + PFN_vkCmdBindDescriptorSets2 CmdBindDescriptorSets2; + PFN_vkCmdPushConstants2 CmdPushConstants2; + PFN_vkCmdPushDescriptorSet2 CmdPushDescriptorSet2; + PFN_vkCmdSetLineStipple CmdSetLineStipple; + PFN_vkCmdBindIndexBuffer2 CmdBindIndexBuffer2; + PFN_vkGetRenderingAreaGranularity GetRenderingAreaGranularity; + PFN_vkCmdSetRenderingAttachmentLocations CmdSetRenderingAttachmentLocations; + PFN_vkCmdSetRenderingInputAttachmentIndices CmdSetRenderingInputAttachmentIndices; // ---- Core Vulkan SC 1.0 commands PFN_vkGetCommandPoolMemoryConsumption GetCommandPoolMemoryConsumption; diff --git a/loader/generated-vksc/vk_loader_extensions.c b/loader/generated-vksc/vk_loader_extensions.c index f8cbbf814..3d7325e73 100644 --- a/loader/generated-vksc/vk_loader_extensions.c +++ b/loader/generated-vksc/vk_loader_extensions.c @@ -208,25 +208,44 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_d 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->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->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->CreatePipelineCache = (PFN_vkCreatePipelineCache)gpa(dev, "vkCreatePipelineCache"); table->DestroyPipelineCache = (PFN_vkDestroyPipelineCache)gpa(dev, "vkDestroyPipelineCache"); - 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"); @@ -240,19 +259,21 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_d 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->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"); @@ -262,57 +283,30 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_d 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"); 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->GetDeviceQueue2 = (PFN_vkGetDeviceQueue2)gpa(dev, "vkGetDeviceQueue2"); + table->CmdDispatchBase = (PFN_vkCmdDispatchBase)gpa(dev, "vkCmdDispatchBase"); + table->GetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport)gpa(dev, "vkGetDescriptorSetLayoutSupport"); table->CreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)gpa(dev, "vkCreateSamplerYcbcrConversion"); table->DestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion)gpa(dev, "vkDestroySamplerYcbcrConversion"); - table->GetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport)gpa(dev, "vkGetDescriptorSetLayoutSupport"); - 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"); @@ -320,15 +314,18 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_d 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"); @@ -336,6 +333,12 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_d 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"); @@ -355,28 +358,25 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_d 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->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->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->CmdBindDescriptorSets2 = (PFN_vkCmdBindDescriptorSets2)gpa(dev, "vkCmdBindDescriptorSets2"); + table->CmdPushConstants2 = (PFN_vkCmdPushConstants2)gpa(dev, "vkCmdPushConstants2"); + table->CmdPushDescriptorSet2 = (PFN_vkCmdPushDescriptorSet2)gpa(dev, "vkCmdPushDescriptorSet2"); + 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"); // ---- Core Vulkan SC 1.0 commands table->GetCommandPoolMemoryConsumption = (PFN_vkGetCommandPoolMemoryConsumption)gpa(dev, "vkGetCommandPoolMemoryConsumption"); @@ -819,26 +819,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_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 < VKSC_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 < VKSC_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 < VKSC_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 < VKSC_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 < VKSC_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 < VKSC_API_VERSION_1_0) return NULL; return (void *)table->CreateQueryPool; @@ -855,14 +835,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_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 < VKSC_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 < VKSC_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 < VKSC_API_VERSION_1_0) return NULL; return (void *)table->CreateImage; @@ -883,185 +855,185 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; return (void *)table->DestroyImageView; } - if (!strcmp(name, "CreatePipelineCache")) { + if (!strcmp(name, "CreateCommandPool")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CreatePipelineCache; + return (void *)table->CreateCommandPool; } - if (!strcmp(name, "DestroyPipelineCache")) { + if (!strcmp(name, "ResetCommandPool")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->DestroyPipelineCache; + return (void *)table->ResetCommandPool; } - if (!strcmp(name, "CreateGraphicsPipelines")) { + if (!strcmp(name, "AllocateCommandBuffers")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CreateGraphicsPipelines; + return (void *)table->AllocateCommandBuffers; } - if (!strcmp(name, "CreateComputePipelines")) { + if (!strcmp(name, "FreeCommandBuffers")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CreateComputePipelines; + return (void *)table->FreeCommandBuffers; } - if (!strcmp(name, "DestroyPipeline")) { + if (!strcmp(name, "BeginCommandBuffer")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->DestroyPipeline; + return (void *)table->BeginCommandBuffer; } - if (!strcmp(name, "CreatePipelineLayout")) { + if (!strcmp(name, "EndCommandBuffer")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CreatePipelineLayout; + return (void *)table->EndCommandBuffer; } - if (!strcmp(name, "DestroyPipelineLayout")) { + if (!strcmp(name, "ResetCommandBuffer")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->DestroyPipelineLayout; + return (void *)table->ResetCommandBuffer; } - if (!strcmp(name, "CreateSampler")) { + if (!strcmp(name, "CmdCopyBuffer")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CreateSampler; + return (void *)table->CmdCopyBuffer; } - if (!strcmp(name, "DestroySampler")) { + if (!strcmp(name, "CmdCopyImage")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->DestroySampler; + return (void *)table->CmdCopyImage; } - if (!strcmp(name, "CreateDescriptorSetLayout")) { + if (!strcmp(name, "CmdCopyBufferToImage")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CreateDescriptorSetLayout; + return (void *)table->CmdCopyBufferToImage; } - if (!strcmp(name, "DestroyDescriptorSetLayout")) { + if (!strcmp(name, "CmdCopyImageToBuffer")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->DestroyDescriptorSetLayout; + return (void *)table->CmdCopyImageToBuffer; } - if (!strcmp(name, "CreateDescriptorPool")) { + if (!strcmp(name, "CmdUpdateBuffer")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CreateDescriptorPool; + return (void *)table->CmdUpdateBuffer; } - if (!strcmp(name, "ResetDescriptorPool")) { + if (!strcmp(name, "CmdFillBuffer")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->ResetDescriptorPool; + return (void *)table->CmdFillBuffer; } - if (!strcmp(name, "AllocateDescriptorSets")) { + if (!strcmp(name, "CmdPipelineBarrier")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->AllocateDescriptorSets; + return (void *)table->CmdPipelineBarrier; } - if (!strcmp(name, "FreeDescriptorSets")) { + if (!strcmp(name, "CmdBeginQuery")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->FreeDescriptorSets; + return (void *)table->CmdBeginQuery; } - if (!strcmp(name, "UpdateDescriptorSets")) { + if (!strcmp(name, "CmdEndQuery")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->UpdateDescriptorSets; + return (void *)table->CmdEndQuery; } - if (!strcmp(name, "CreateFramebuffer")) { + if (!strcmp(name, "CmdResetQueryPool")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CreateFramebuffer; + return (void *)table->CmdResetQueryPool; } - if (!strcmp(name, "DestroyFramebuffer")) { + if (!strcmp(name, "CmdWriteTimestamp")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->DestroyFramebuffer; + return (void *)table->CmdWriteTimestamp; } - if (!strcmp(name, "CreateRenderPass")) { + if (!strcmp(name, "CmdCopyQueryPoolResults")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CreateRenderPass; + return (void *)table->CmdCopyQueryPoolResults; } - if (!strcmp(name, "DestroyRenderPass")) { + if (!strcmp(name, "CmdExecuteCommands")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->DestroyRenderPass; + return (void *)table->CmdExecuteCommands; } - if (!strcmp(name, "GetRenderAreaGranularity")) { + if (!strcmp(name, "CreateEvent")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->GetRenderAreaGranularity; + return (void *)table->CreateEvent; } - if (!strcmp(name, "CreateCommandPool")) { + if (!strcmp(name, "DestroyEvent")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CreateCommandPool; + return (void *)table->DestroyEvent; } - if (!strcmp(name, "ResetCommandPool")) { + if (!strcmp(name, "GetEventStatus")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->ResetCommandPool; + return (void *)table->GetEventStatus; } - if (!strcmp(name, "AllocateCommandBuffers")) { + if (!strcmp(name, "SetEvent")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->AllocateCommandBuffers; + return (void *)table->SetEvent; } - if (!strcmp(name, "FreeCommandBuffers")) { + if (!strcmp(name, "ResetEvent")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->FreeCommandBuffers; + return (void *)table->ResetEvent; } - if (!strcmp(name, "BeginCommandBuffer")) { + if (!strcmp(name, "CreateBufferView")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->BeginCommandBuffer; + return (void *)table->CreateBufferView; } - if (!strcmp(name, "EndCommandBuffer")) { + if (!strcmp(name, "DestroyBufferView")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->EndCommandBuffer; + return (void *)table->DestroyBufferView; } - if (!strcmp(name, "ResetCommandBuffer")) { + if (!strcmp(name, "CreatePipelineCache")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->ResetCommandBuffer; + return (void *)table->CreatePipelineCache; } - if (!strcmp(name, "CmdBindPipeline")) { + if (!strcmp(name, "DestroyPipelineCache")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdBindPipeline; + return (void *)table->DestroyPipelineCache; } - if (!strcmp(name, "CmdSetViewport")) { + if (!strcmp(name, "CreateComputePipelines")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdSetViewport; + return (void *)table->CreateComputePipelines; } - if (!strcmp(name, "CmdSetScissor")) { + if (!strcmp(name, "DestroyPipeline")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdSetScissor; + return (void *)table->DestroyPipeline; } - if (!strcmp(name, "CmdSetLineWidth")) { + if (!strcmp(name, "CreatePipelineLayout")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdSetLineWidth; + return (void *)table->CreatePipelineLayout; } - if (!strcmp(name, "CmdSetDepthBias")) { + if (!strcmp(name, "DestroyPipelineLayout")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdSetDepthBias; + return (void *)table->DestroyPipelineLayout; } - if (!strcmp(name, "CmdSetBlendConstants")) { + if (!strcmp(name, "CreateSampler")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdSetBlendConstants; + return (void *)table->CreateSampler; } - if (!strcmp(name, "CmdSetDepthBounds")) { + if (!strcmp(name, "DestroySampler")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdSetDepthBounds; + return (void *)table->DestroySampler; } - if (!strcmp(name, "CmdSetStencilCompareMask")) { + if (!strcmp(name, "CreateDescriptorSetLayout")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdSetStencilCompareMask; + return (void *)table->CreateDescriptorSetLayout; } - if (!strcmp(name, "CmdSetStencilWriteMask")) { + if (!strcmp(name, "DestroyDescriptorSetLayout")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdSetStencilWriteMask; + return (void *)table->DestroyDescriptorSetLayout; } - if (!strcmp(name, "CmdSetStencilReference")) { + if (!strcmp(name, "CreateDescriptorPool")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdSetStencilReference; + return (void *)table->CreateDescriptorPool; } - if (!strcmp(name, "CmdBindDescriptorSets")) { + if (!strcmp(name, "ResetDescriptorPool")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdBindDescriptorSets; + return (void *)table->ResetDescriptorPool; } - if (!strcmp(name, "CmdBindIndexBuffer")) { + if (!strcmp(name, "AllocateDescriptorSets")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdBindIndexBuffer; + return (void *)table->AllocateDescriptorSets; } - if (!strcmp(name, "CmdBindVertexBuffers")) { + if (!strcmp(name, "FreeDescriptorSets")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdBindVertexBuffers; + return (void *)table->FreeDescriptorSets; } - if (!strcmp(name, "CmdDraw")) { + if (!strcmp(name, "UpdateDescriptorSets")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdDraw; + return (void *)table->UpdateDescriptorSets; } - if (!strcmp(name, "CmdDrawIndexed")) { + if (!strcmp(name, "CmdBindPipeline")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdDrawIndexed; + return (void *)table->CmdBindPipeline; } - if (!strcmp(name, "CmdDrawIndirect")) { + if (!strcmp(name, "CmdBindDescriptorSets")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdDrawIndirect; + return (void *)table->CmdBindDescriptorSets; } - if (!strcmp(name, "CmdDrawIndexedIndirect")) { + if (!strcmp(name, "CmdClearColorImage")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdDrawIndexedIndirect; + return (void *)table->CmdClearColorImage; } if (!strcmp(name, "CmdDispatch")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; @@ -1071,89 +1043,121 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; return (void *)table->CmdDispatchIndirect; } - if (!strcmp(name, "CmdCopyBuffer")) { + if (!strcmp(name, "CmdSetEvent")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdCopyBuffer; + return (void *)table->CmdSetEvent; } - if (!strcmp(name, "CmdCopyImage")) { + if (!strcmp(name, "CmdResetEvent")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdCopyImage; + return (void *)table->CmdResetEvent; } - if (!strcmp(name, "CmdBlitImage")) { + if (!strcmp(name, "CmdWaitEvents")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdBlitImage; + return (void *)table->CmdWaitEvents; } - if (!strcmp(name, "CmdCopyBufferToImage")) { + if (!strcmp(name, "CmdPushConstants")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdCopyBufferToImage; + return (void *)table->CmdPushConstants; } - if (!strcmp(name, "CmdCopyImageToBuffer")) { + if (!strcmp(name, "CreateGraphicsPipelines")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdCopyImageToBuffer; + return (void *)table->CreateGraphicsPipelines; } - if (!strcmp(name, "CmdUpdateBuffer")) { + if (!strcmp(name, "CreateFramebuffer")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdUpdateBuffer; + return (void *)table->CreateFramebuffer; } - if (!strcmp(name, "CmdFillBuffer")) { + if (!strcmp(name, "DestroyFramebuffer")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdFillBuffer; + return (void *)table->DestroyFramebuffer; } - if (!strcmp(name, "CmdClearColorImage")) { + if (!strcmp(name, "CreateRenderPass")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdClearColorImage; + return (void *)table->CreateRenderPass; } - if (!strcmp(name, "CmdClearDepthStencilImage")) { + if (!strcmp(name, "DestroyRenderPass")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdClearDepthStencilImage; + return (void *)table->DestroyRenderPass; } - if (!strcmp(name, "CmdClearAttachments")) { + if (!strcmp(name, "GetRenderAreaGranularity")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdClearAttachments; + return (void *)table->GetRenderAreaGranularity; } - if (!strcmp(name, "CmdResolveImage")) { + if (!strcmp(name, "CmdSetViewport")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdResolveImage; + return (void *)table->CmdSetViewport; } - if (!strcmp(name, "CmdSetEvent")) { + if (!strcmp(name, "CmdSetScissor")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdSetEvent; + return (void *)table->CmdSetScissor; } - if (!strcmp(name, "CmdResetEvent")) { + if (!strcmp(name, "CmdSetLineWidth")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdResetEvent; + return (void *)table->CmdSetLineWidth; } - if (!strcmp(name, "CmdWaitEvents")) { + if (!strcmp(name, "CmdSetDepthBias")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdWaitEvents; + return (void *)table->CmdSetDepthBias; } - if (!strcmp(name, "CmdPipelineBarrier")) { + if (!strcmp(name, "CmdSetBlendConstants")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdPipelineBarrier; + return (void *)table->CmdSetBlendConstants; } - if (!strcmp(name, "CmdBeginQuery")) { + if (!strcmp(name, "CmdSetDepthBounds")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdBeginQuery; + return (void *)table->CmdSetDepthBounds; } - if (!strcmp(name, "CmdEndQuery")) { + if (!strcmp(name, "CmdSetStencilCompareMask")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdEndQuery; + return (void *)table->CmdSetStencilCompareMask; } - if (!strcmp(name, "CmdResetQueryPool")) { + if (!strcmp(name, "CmdSetStencilWriteMask")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdResetQueryPool; + return (void *)table->CmdSetStencilWriteMask; } - if (!strcmp(name, "CmdWriteTimestamp")) { + if (!strcmp(name, "CmdSetStencilReference")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdWriteTimestamp; + return (void *)table->CmdSetStencilReference; } - if (!strcmp(name, "CmdCopyQueryPoolResults")) { + if (!strcmp(name, "CmdBindIndexBuffer")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdCopyQueryPoolResults; + return (void *)table->CmdBindIndexBuffer; } - if (!strcmp(name, "CmdPushConstants")) { + if (!strcmp(name, "CmdBindVertexBuffers")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdPushConstants; + return (void *)table->CmdBindVertexBuffers; + } + if (!strcmp(name, "CmdDraw")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdDraw; + } + if (!strcmp(name, "CmdDrawIndexed")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdDrawIndexed; + } + if (!strcmp(name, "CmdDrawIndirect")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdDrawIndirect; + } + if (!strcmp(name, "CmdDrawIndexedIndirect")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdDrawIndexedIndirect; + } + if (!strcmp(name, "CmdBlitImage")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdBlitImage; + } + if (!strcmp(name, "CmdClearDepthStencilImage")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdClearDepthStencilImage; + } + if (!strcmp(name, "CmdClearAttachments")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdClearAttachments; + } + if (!strcmp(name, "CmdResolveImage")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdResolveImage; } if (!strcmp(name, "CmdBeginRenderPass")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; @@ -1167,10 +1171,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_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 < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdExecuteCommands; - } if (!strcmp(name, "BindBufferMemory2")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; return (void *)table->BindBufferMemory2; @@ -1187,10 +1187,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; return (void *)table->CmdSetDeviceMask; } - if (!strcmp(name, "CmdDispatchBase")) { - if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdDispatchBase; - } if (!strcmp(name, "GetImageMemoryRequirements2")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; return (void *)table->GetImageMemoryRequirements2; @@ -1203,41 +1199,21 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; return (void *)table->GetDeviceQueue2; } - if (!strcmp(name, "CreateSamplerYcbcrConversion")) { - if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CreateSamplerYcbcrConversion; - } - if (!strcmp(name, "DestroySamplerYcbcrConversion")) { + if (!strcmp(name, "CmdDispatchBase")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->DestroySamplerYcbcrConversion; + return (void *)table->CmdDispatchBase; } if (!strcmp(name, "GetDescriptorSetLayoutSupport")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; return (void *)table->GetDescriptorSetLayoutSupport; } - if (!strcmp(name, "CmdDrawIndirectCount")) { - if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdDrawIndirectCount; - } - if (!strcmp(name, "CmdDrawIndexedIndirectCount")) { - if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdDrawIndexedIndirectCount; - } - if (!strcmp(name, "CreateRenderPass2")) { - if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CreateRenderPass2; - } - if (!strcmp(name, "CmdBeginRenderPass2")) { - if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdBeginRenderPass2; - } - if (!strcmp(name, "CmdNextSubpass2")) { + if (!strcmp(name, "CreateSamplerYcbcrConversion")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdNextSubpass2; + return (void *)table->CreateSamplerYcbcrConversion; } - if (!strcmp(name, "CmdEndRenderPass2")) { + if (!strcmp(name, "DestroySamplerYcbcrConversion")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; - return (void *)table->CmdEndRenderPass2; + return (void *)table->DestroySamplerYcbcrConversion; } if (!strcmp(name, "ResetQueryPool")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; @@ -1267,6 +1243,30 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; return (void *)table->GetDeviceMemoryOpaqueCaptureAddress; } + if (!strcmp(name, "CmdDrawIndirectCount")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdDrawIndirectCount; + } + if (!strcmp(name, "CmdDrawIndexedIndirectCount")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdDrawIndexedIndirectCount; + } + if (!strcmp(name, "CreateRenderPass2")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CreateRenderPass2; + } + if (!strcmp(name, "CmdBeginRenderPass2")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdBeginRenderPass2; + } + if (!strcmp(name, "CmdNextSubpass2")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdNextSubpass2; + } + if (!strcmp(name, "CmdEndRenderPass2")) { + if (dev->should_ignore_device_commands_from_newer_version && api_version < VKSC_API_VERSION_1_0) return NULL; + return (void *)table->CmdEndRenderPass2; + } // ---- Core Vulkan 1.3 commands if (!strcmp(name, "CreatePrivateDataSlot")) { @@ -1285,18 +1285,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -1325,6 +1313,30 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -1401,24 +1413,8 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -1427,14 +1423,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -1443,17 +1431,25 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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, "CmdPushDescriptorSet")) { + 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->CmdPushDescriptorSet; + return (void *)table->CopyMemoryToImage; } - if (!strcmp(name, "CmdSetRenderingAttachmentLocations")) { + 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->CmdSetRenderingAttachmentLocations; + return (void *)table->CopyImageToMemory; } - if (!strcmp(name, "CmdSetRenderingInputAttachmentIndices")) { + 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->CmdSetRenderingInputAttachmentIndices; + 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; } if (!strcmp(name, "CmdBindDescriptorSets2")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL; @@ -1467,21 +1463,25 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL; return (void *)table->CmdPushDescriptorSet2; } - 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; } // ---- Core Vulkan SC 1.0 commands diff --git a/loader/generated-vksc/vk_object_types.h b/loader/generated-vksc/vk_object_types.h index c600a0ec2..1796c1bfe 100644 --- a/loader/generated-vksc/vk_object_types.h +++ b/loader/generated-vksc/vk_object_types.h @@ -49,23 +49,23 @@ typedef enum VulkanObjectType { 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, + kVulkanObjectTypeQueryPool = 11, + kVulkanObjectTypeImageView = 12, + kVulkanObjectTypeCommandPool = 13, + kVulkanObjectTypeRenderPass = 14, + kVulkanObjectTypeFramebuffer = 15, + kVulkanObjectTypeEvent = 16, + kVulkanObjectTypeBufferView = 17, + kVulkanObjectTypeShaderModule = 18, + kVulkanObjectTypePipelineCache = 19, + kVulkanObjectTypePipelineLayout = 20, + kVulkanObjectTypePipeline = 21, + kVulkanObjectTypeDescriptorSetLayout = 22, + kVulkanObjectTypeSampler = 23, + kVulkanObjectTypeDescriptorSet = 24, + kVulkanObjectTypeDescriptorPool = 25, + kVulkanObjectTypeDescriptorUpdateTemplate = 26, + kVulkanObjectTypeSamplerYcbcrConversion = 27, kVulkanObjectTypePrivateDataSlot = 28, kVulkanObjectTypeSurfaceKHR = 29, kVulkanObjectTypeSwapchainKHR = 30, @@ -98,9 +98,9 @@ typedef enum VulkanObjectType { kVulkanObjectTypeIndirectExecutionSetEXT = 57, kVulkanObjectTypeIndirectCommandsLayoutEXT = 58, kVulkanObjectTypeMax = 59, - // Aliases for backwards compatibilty of "promoted" types - kVulkanObjectTypeSamplerYcbcrConversionKHR = kVulkanObjectTypeSamplerYcbcrConversion, + // Aliases for backwards compatibility of "promoted" types kVulkanObjectTypeDescriptorUpdateTemplateKHR = kVulkanObjectTypeDescriptorUpdateTemplate, + kVulkanObjectTypeSamplerYcbcrConversionKHR = kVulkanObjectTypeSamplerYcbcrConversion, kVulkanObjectTypePrivateDataSlotEXT = kVulkanObjectTypePrivateDataSlot, } VulkanObjectType; @@ -117,23 +117,23 @@ static const char * const object_string[kVulkanObjectTypeMax] = { "CommandBuffer", "Fence", "DeviceMemory", - "Event", "QueryPool", - "BufferView", "ImageView", + "CommandPool", + "RenderPass", + "Framebuffer", + "Event", + "BufferView", "ShaderModule", "PipelineCache", "PipelineLayout", "Pipeline", - "RenderPass", "DescriptorSetLayout", "Sampler", "DescriptorSet", "DescriptorPool", - "Framebuffer", - "CommandPool", - "SamplerYcbcrConversion", "DescriptorUpdateTemplate", + "SamplerYcbcrConversion", "PrivateDataSlot", "SurfaceKHR", "SwapchainKHR", @@ -180,23 +180,23 @@ const VkDebugReportObjectTypeEXT get_debug_report_enum[] = { 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_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_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 @@ -243,23 +243,23 @@ const VkObjectType get_object_type_enum[] = { 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_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_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 @@ -349,10 +349,10 @@ static inline VkObjectType convertDebugReportObjectToCoreObject(VkDebugReportObj 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) { @@ -439,10 +439,10 @@ static inline VkDebugReportObjectTypeEXT convertCoreObjectToDebugReportObject(Vk 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) { diff --git a/loader/generated/vk_layer_dispatch_table.h b/loader/generated/vk_layer_dispatch_table.h index ce2a6ddeb..2b86d9880 100644 --- a/loader/generated/vk_layer_dispatch_table.h +++ b/loader/generated/vk_layer_dispatch_table.h @@ -343,30 +343,50 @@ typedef struct VkLayerDispatchTable_ { 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; @@ -381,20 +401,21 @@ typedef struct VkLayerDispatchTable_ { 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; @@ -404,66 +425,39 @@ typedef struct VkLayerDispatchTable_ { 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; @@ -471,15 +465,18 @@ typedef struct VkLayerDispatchTable_ { 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; @@ -487,6 +484,12 @@ typedef struct VkLayerDispatchTable_ { 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; @@ -506,30 +509,27 @@ typedef struct VkLayerDispatchTable_ { 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_vkCopyMemoryToImage CopyMemoryToImage; + PFN_vkCopyImageToMemory CopyImageToMemory; + PFN_vkCopyImageToImage CopyImageToImage; + PFN_vkTransitionImageLayout TransitionImageLayout; 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_vkCmdSetLineStipple CmdSetLineStipple; + PFN_vkCmdBindIndexBuffer2 CmdBindIndexBuffer2; + PFN_vkGetRenderingAreaGranularity GetRenderingAreaGranularity; + PFN_vkCmdSetRenderingAttachmentLocations CmdSetRenderingAttachmentLocations; + PFN_vkCmdSetRenderingInputAttachmentIndices CmdSetRenderingInputAttachmentIndices; // ---- VK_KHR_swapchain extension commands PFN_vkCreateSwapchainKHR CreateSwapchainKHR; @@ -729,6 +729,9 @@ typedef struct VkLayerDispatchTable_ { PFN_vkGetPipelineBinaryDataKHR GetPipelineBinaryDataKHR; PFN_vkReleaseCapturedPipelineDataKHR ReleaseCapturedPipelineDataKHR; + // ---- VK_KHR_swapchain_maintenance1 extension commands + PFN_vkReleaseSwapchainImagesKHR ReleaseSwapchainImagesKHR; + // ---- VK_KHR_line_rasterization extension commands PFN_vkCmdSetLineStippleKHR CmdSetLineStippleKHR; @@ -743,6 +746,13 @@ typedef struct VkLayerDispatchTable_ { PFN_vkCmdSetDescriptorBufferOffsets2EXT CmdSetDescriptorBufferOffsets2EXT; PFN_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT CmdBindDescriptorBufferEmbeddedSamplers2EXT; + // ---- VK_KHR_copy_memory_indirect extension commands + PFN_vkCmdCopyMemoryIndirectKHR CmdCopyMemoryIndirectKHR; + PFN_vkCmdCopyMemoryToImageIndirectKHR CmdCopyMemoryToImageIndirectKHR; + + // ---- VK_KHR_maintenance10 extension commands + PFN_vkCmdEndRendering2KHR CmdEndRendering2KHR; + // ---- VK_EXT_debug_marker extension commands PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT; PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT; @@ -1237,6 +1247,10 @@ typedef struct VkLayerDispatchTable_ { // ---- 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; @@ -1261,6 +1275,17 @@ typedef struct VkLayerDispatchTable_ { PFN_vkUpdateIndirectExecutionSetPipelineEXT UpdateIndirectExecutionSetPipelineEXT; PFN_vkUpdateIndirectExecutionSetShaderEXT UpdateIndirectExecutionSetShaderEXT; + // ---- VK_OHOS_native_buffer extension commands +#if defined(VK_USE_PLATFORM_OHOS) + PFN_vkGetSwapchainGrallocUsageOHOS GetSwapchainGrallocUsageOHOS; +#endif // VK_USE_PLATFORM_OHOS +#if defined(VK_USE_PLATFORM_OHOS) + PFN_vkAcquireImageOHOS AcquireImageOHOS; +#endif // VK_USE_PLATFORM_OHOS +#if defined(VK_USE_PLATFORM_OHOS) + PFN_vkQueueSignalReleaseImageOHOS QueueSignalReleaseImageOHOS; +#endif // VK_USE_PLATFORM_OHOS + // ---- VK_EXT_external_memory_metal extension commands #if defined(VK_USE_PLATFORM_METAL_EXT) PFN_vkGetMemoryMetalHandleEXT GetMemoryMetalHandleEXT; diff --git a/loader/generated/vk_loader_extensions.c b/loader/generated/vk_loader_extensions.c index 1afd2efa9..bd9c9bfbf 100644 --- a/loader/generated/vk_loader_extensions.c +++ b/loader/generated/vk_loader_extensions.c @@ -371,30 +371,50 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_d 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"); @@ -409,20 +429,21 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_d 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"); @@ -432,66 +453,39 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_d 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"); @@ -499,15 +493,18 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_d 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"); @@ -515,6 +512,12 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_d 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"); @@ -534,30 +537,27 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_d 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->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->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->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 @@ -767,6 +767,9 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_extension_dispatch_table(struct lo 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"); @@ -781,6 +784,13 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_extension_dispatch_table(struct lo 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_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"); @@ -1275,6 +1285,10 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_extension_dispatch_table(struct lo // ---- 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"); @@ -1299,6 +1313,17 @@ VKAPI_ATTR void VKAPI_CALL loader_init_device_extension_dispatch_table(struct lo table->UpdateIndirectExecutionSetPipelineEXT = (PFN_vkUpdateIndirectExecutionSetPipelineEXT)gdpa(dev, "vkUpdateIndirectExecutionSetPipelineEXT"); table->UpdateIndirectExecutionSetShaderEXT = (PFN_vkUpdateIndirectExecutionSetShaderEXT)gdpa(dev, "vkUpdateIndirectExecutionSetShaderEXT"); + // ---- VK_OHOS_native_buffer extension commands +#if defined(VK_USE_PLATFORM_OHOS) + table->GetSwapchainGrallocUsageOHOS = (PFN_vkGetSwapchainGrallocUsageOHOS)gdpa(dev, "vkGetSwapchainGrallocUsageOHOS"); +#endif // VK_USE_PLATFORM_OHOS +#if defined(VK_USE_PLATFORM_OHOS) + table->AcquireImageOHOS = (PFN_vkAcquireImageOHOS)gdpa(dev, "vkAcquireImageOHOS"); +#endif // VK_USE_PLATFORM_OHOS +#if defined(VK_USE_PLATFORM_OHOS) + table->QueueSignalReleaseImageOHOS = (PFN_vkQueueSignalReleaseImageOHOS)gdpa(dev, "vkQueueSignalReleaseImageOHOS"); +#endif // VK_USE_PLATFORM_OHOS + // ---- VK_EXT_external_memory_metal extension commands #if defined(VK_USE_PLATFORM_METAL_EXT) table->GetMemoryMetalHandleEXT = (PFN_vkGetMemoryMetalHandleEXT)gdpa(dev, "vkGetMemoryMetalHandleEXT"); @@ -1627,7 +1652,7 @@ void init_extension_device_proc_terminator_dispatch(struct loader_device *dev) { // ---- 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 @@ -1660,7 +1685,7 @@ void init_extension_device_proc_terminator_dispatch(struct loader_device *dev) { #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 } @@ -1803,26 +1828,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -1843,14 +1848,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -1871,6 +1868,118 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -1895,10 +2004,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -1955,61 +2060,65 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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, "CreateFramebuffer")) { + 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->CreateFramebuffer; + return (void *)table->CmdBindPipeline; } - if (!strcmp(name, "DestroyFramebuffer")) { + 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->DestroyFramebuffer; + return (void *)table->CmdBindDescriptorSets; } - if (!strcmp(name, "CreateRenderPass")) { + 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->CreateRenderPass; + return (void *)table->CmdClearColorImage; } - if (!strcmp(name, "DestroyRenderPass")) { + 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->DestroyRenderPass; + return (void *)table->CmdDispatch; } - if (!strcmp(name, "GetRenderAreaGranularity")) { + 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->GetRenderAreaGranularity; + return (void *)table->CmdDispatchIndirect; } - if (!strcmp(name, "CreateCommandPool")) { + 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->CreateCommandPool; + return (void *)table->CmdSetEvent; } - if (!strcmp(name, "DestroyCommandPool")) { + 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->DestroyCommandPool; + return (void *)table->CmdResetEvent; } - if (!strcmp(name, "ResetCommandPool")) { + 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->ResetCommandPool; + return (void *)table->CmdWaitEvents; } - if (!strcmp(name, "AllocateCommandBuffers")) { + 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->AllocateCommandBuffers; + return (void *)table->CmdPushConstants; } - if (!strcmp(name, "FreeCommandBuffers")) { + 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->FreeCommandBuffers; + return (void *)table->CreateGraphicsPipelines; } - if (!strcmp(name, "BeginCommandBuffer")) { + 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->BeginCommandBuffer; + return (void *)table->CreateFramebuffer; } - if (!strcmp(name, "EndCommandBuffer")) { + if (!strcmp(name, "DestroyFramebuffer")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL; - return (void *)table->EndCommandBuffer; + return (void *)table->DestroyFramebuffer; } - if (!strcmp(name, "ResetCommandBuffer")) { + if (!strcmp(name, "CreateRenderPass")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL; - return (void *)table->ResetCommandBuffer; + return (void *)table->CreateRenderPass; } - if (!strcmp(name, "CmdBindPipeline")) { + if (!strcmp(name, "DestroyRenderPass")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL; - return (void *)table->CmdBindPipeline; + return (void *)table->DestroyRenderPass; + } + if (!strcmp(name, "GetRenderAreaGranularity")) { + 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, "CmdSetViewport")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_0) return NULL; @@ -2047,10 +2156,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -2075,46 +2180,10 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -2127,46 +2196,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -2179,10 +2208,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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")) { @@ -2201,10 +2226,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -2225,13 +2246,9 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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 (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 (!strcmp(name, "CmdDispatchBase")) { 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; @@ -2249,59 +2266,67 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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 (!strcmp(name, "ResetQueryPool")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL; - return (void *)table->CmdDrawIndirectCount; + return (void *)table->ResetQueryPool; } - if (!strcmp(name, "CmdDrawIndexedIndirectCount")) { + if (!strcmp(name, "GetSemaphoreCounterValue")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL; - return (void *)table->CmdDrawIndexedIndirectCount; + return (void *)table->GetSemaphoreCounterValue; } - if (!strcmp(name, "CreateRenderPass2")) { + if (!strcmp(name, "WaitSemaphores")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL; - return (void *)table->CreateRenderPass2; + return (void *)table->WaitSemaphores; } - if (!strcmp(name, "CmdBeginRenderPass2")) { + if (!strcmp(name, "SignalSemaphore")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL; - return (void *)table->CmdBeginRenderPass2; + return (void *)table->SignalSemaphore; } - if (!strcmp(name, "CmdNextSubpass2")) { + if (!strcmp(name, "GetBufferDeviceAddress")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL; - return (void *)table->CmdNextSubpass2; + return (void *)table->GetBufferDeviceAddress; } - if (!strcmp(name, "CmdEndRenderPass2")) { + if (!strcmp(name, "GetBufferOpaqueCaptureAddress")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL; - return (void *)table->CmdEndRenderPass2; + return (void *)table->GetBufferOpaqueCaptureAddress; } - if (!strcmp(name, "ResetQueryPool")) { + if (!strcmp(name, "GetDeviceMemoryOpaqueCaptureAddress")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_2) return NULL; - return (void *)table->ResetQueryPool; + return (void *)table->GetDeviceMemoryOpaqueCaptureAddress; } - if (!strcmp(name, "GetSemaphoreCounterValue")) { + 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->GetSemaphoreCounterValue; + return (void *)table->CmdDrawIndirectCount; } - if (!strcmp(name, "WaitSemaphores")) { + 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->WaitSemaphores; + return (void *)table->CmdDrawIndexedIndirectCount; } - if (!strcmp(name, "SignalSemaphore")) { + 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->SignalSemaphore; + return (void *)table->CreateRenderPass2; } - if (!strcmp(name, "GetBufferDeviceAddress")) { + 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->GetBufferDeviceAddress; + return (void *)table->CmdBeginRenderPass2; } - if (!strcmp(name, "GetBufferOpaqueCaptureAddress")) { + 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->GetBufferOpaqueCaptureAddress; + return (void *)table->CmdNextSubpass2; } - if (!strcmp(name, "GetDeviceMemoryOpaqueCaptureAddress")) { + 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->GetDeviceMemoryOpaqueCaptureAddress; + return (void *)table->CmdEndRenderPass2; } // ---- Core Vulkan 1.3 commands @@ -2321,18 +2346,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -2361,6 +2374,30 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -2437,24 +2474,8 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -2463,14 +2484,6 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -2479,21 +2492,29 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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, "CmdPushDescriptorSet")) { + 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->CmdPushDescriptorSet; + return (void *)table->CopyMemoryToImage; } - if (!strcmp(name, "CmdPushDescriptorSetWithTemplate")) { + 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->CmdPushDescriptorSetWithTemplate; + return (void *)table->CopyImageToMemory; } - if (!strcmp(name, "CmdSetRenderingAttachmentLocations")) { + 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->CmdSetRenderingAttachmentLocations; + return (void *)table->CopyImageToImage; } - if (!strcmp(name, "CmdSetRenderingInputAttachmentIndices")) { + 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->CmdSetRenderingInputAttachmentIndices; + 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; + } + if (!strcmp(name, "CmdPushDescriptorSetWithTemplate")) { + 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, "CmdBindDescriptorSets2")) { if (dev->should_ignore_device_commands_from_newer_version && api_version < VK_API_VERSION_1_4) return NULL; @@ -2511,21 +2532,25 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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 @@ -2726,6 +2751,9 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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; @@ -2740,6 +2768,13 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis 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_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; @@ -3234,6 +3269,10 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis // ---- 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; @@ -3258,6 +3297,17 @@ VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDis if (!strcmp(name, "UpdateIndirectExecutionSetPipelineEXT")) return (void *)table->UpdateIndirectExecutionSetPipelineEXT; if (!strcmp(name, "UpdateIndirectExecutionSetShaderEXT")) return (void *)table->UpdateIndirectExecutionSetShaderEXT; + // ---- VK_OHOS_native_buffer extension commands +#if defined(VK_USE_PLATFORM_OHOS) + if (!strcmp(name, "GetSwapchainGrallocUsageOHOS")) return (void *)table->GetSwapchainGrallocUsageOHOS; +#endif // VK_USE_PLATFORM_OHOS +#if defined(VK_USE_PLATFORM_OHOS) + if (!strcmp(name, "AcquireImageOHOS")) return (void *)table->AcquireImageOHOS; +#endif // VK_USE_PLATFORM_OHOS +#if defined(VK_USE_PLATFORM_OHOS) + if (!strcmp(name, "QueueSignalReleaseImageOHOS")) return (void *)table->QueueSignalReleaseImageOHOS; +#endif // VK_USE_PLATFORM_OHOS + // ---- VK_EXT_external_memory_metal extension commands #if defined(VK_USE_PLATFORM_METAL_EXT) if (!strcmp(name, "GetMemoryMetalHandleEXT")) return (void *)table->GetMemoryMetalHandleEXT; @@ -5291,6 +5341,22 @@ VKAPI_ATTR VkResult VKAPI_CALL ReleaseCapturedPipelineDataKHR( } +// ---- 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( @@ -5471,6 +5537,51 @@ VKAPI_ATTR void VKAPI_CALL CmdBindDescriptorBufferEmbeddedSamplers2EXT( } +// ---- 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_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( @@ -7736,7 +7847,7 @@ VKAPI_ATTR void VKAPI_CALL GetImageSubresourceLayout2EXT( 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, @@ -10403,6 +10514,39 @@ VKAPI_ATTR void VKAPI_CALL CmdBindTileMemoryQCOM( } +// ---- 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( @@ -10678,6 +10822,62 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSurfaceOHOS( #endif // VK_USE_PLATFORM_OHOS +// ---- VK_OHOS_native_buffer extension trampoline/terminators + +#if defined(VK_USE_PLATFORM_OHOS) +VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainGrallocUsageOHOS( + VkDevice device, + VkFormat format, + VkImageUsageFlags imageUsage, + uint64_t* grallocUsage) { + 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, + "vkGetSwapchainGrallocUsageOHOS: Invalid device " + "[VUID-vkGetSwapchainGrallocUsageOHOS-device-parameter]"); + abort(); /* Intentionally fail so user can correct issue. */ + } + return disp->GetSwapchainGrallocUsageOHOS(device, format, imageUsage, grallocUsage); +} + +#endif // VK_USE_PLATFORM_OHOS +#if defined(VK_USE_PLATFORM_OHOS) +VKAPI_ATTR VkResult VKAPI_CALL AcquireImageOHOS( + VkDevice device, + VkImage image, + int32_t nativeFenceFd, + VkSemaphore semaphore, + VkFence fence) { + 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, + "vkAcquireImageOHOS: Invalid device " + "[VUID-vkAcquireImageOHOS-device-parameter]"); + abort(); /* Intentionally fail so user can correct issue. */ + } + return disp->AcquireImageOHOS(device, image, nativeFenceFd, semaphore, fence); +} + +#endif // VK_USE_PLATFORM_OHOS +#if defined(VK_USE_PLATFORM_OHOS) +VKAPI_ATTR VkResult VKAPI_CALL QueueSignalReleaseImageOHOS( + VkQueue queue, + uint32_t waitSemaphoreCount, + const VkSemaphore* pWaitSemaphores, + VkImage image, + int32_t* pNativeFenceFd) { + 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, + "vkQueueSignalReleaseImageOHOS: Invalid queue " + "[VUID-vkQueueSignalReleaseImageOHOS-queue-parameter]"); + abort(); /* Intentionally fail so user can correct issue. */ + } + return disp->QueueSignalReleaseImageOHOS(queue, waitSemaphoreCount, pWaitSemaphores, image, pNativeFenceFd); +} + +#endif // VK_USE_PLATFORM_OHOS + // ---- VK_NV_cooperative_matrix2 extension trampoline/terminators VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV( @@ -10751,7 +10951,7 @@ VKAPI_ATTR VkResult VKAPI_CALL GetMemoryMetalHandlePropertiesEXT( VKAPI_ATTR void VKAPI_CALL CmdEndRendering2EXT( VkCommandBuffer commandBuffer, - const VkRenderingEndInfoEXT* pRenderingEndInfo) { + 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, @@ -11742,6 +11942,12 @@ bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *na 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; @@ -11790,6 +11996,22 @@ bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *na 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_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; @@ -13256,6 +13478,16 @@ bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *na 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; @@ -13338,6 +13570,26 @@ bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *na } #endif // VK_USE_PLATFORM_OHOS + // ---- VK_OHOS_native_buffer extension commands +#if defined(VK_USE_PLATFORM_OHOS) + if (!strcmp("vkGetSwapchainGrallocUsageOHOS", name)) { + *addr = (void *)GetSwapchainGrallocUsageOHOS; + return true; + } +#endif // VK_USE_PLATFORM_OHOS +#if defined(VK_USE_PLATFORM_OHOS) + if (!strcmp("vkAcquireImageOHOS", name)) { + *addr = (void *)AcquireImageOHOS; + return true; + } +#endif // VK_USE_PLATFORM_OHOS +#if defined(VK_USE_PLATFORM_OHOS) + if (!strcmp("vkQueueSignalReleaseImageOHOS", name)) { + *addr = (void *)QueueSignalReleaseImageOHOS; + return true; + } +#endif // VK_USE_PLATFORM_OHOS + // ---- VK_NV_cooperative_matrix2 extension commands if (!strcmp("vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV", name)) { *addr = (void *)GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV; @@ -13534,6 +13786,9 @@ void fill_out_enabled_instance_extensions(uint32_t extension_count, const char * // ---- 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; } @@ -13648,7 +13903,7 @@ PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *de } 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 @@ -13713,7 +13968,7 @@ PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *de // ---- 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 @@ -14023,6 +14278,7 @@ const char *const LOADER_INSTANCE_EXTENSIONS[] = { 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, diff --git a/loader/generated/vk_loader_extensions.h b/loader/generated/vk_loader_extensions.h index 9bb6d3b41..b8c55aa49 100644 --- a/loader/generated/vk_loader_extensions.h +++ b/loader/generated/vk_loader_extensions.h @@ -526,6 +526,7 @@ struct loader_instance_extension_enable_list { 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; diff --git a/loader/generated/vk_object_types.h b/loader/generated/vk_object_types.h index 6d30aef0a..4d5c2e4eb 100644 --- a/loader/generated/vk_object_types.h +++ b/loader/generated/vk_object_types.h @@ -49,23 +49,23 @@ typedef enum VulkanObjectType { 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, + kVulkanObjectTypeQueryPool = 11, + kVulkanObjectTypeImageView = 12, + kVulkanObjectTypeCommandPool = 13, + kVulkanObjectTypeRenderPass = 14, + kVulkanObjectTypeFramebuffer = 15, + kVulkanObjectTypeEvent = 16, + kVulkanObjectTypeBufferView = 17, + kVulkanObjectTypeShaderModule = 18, + kVulkanObjectTypePipelineCache = 19, + kVulkanObjectTypePipelineLayout = 20, + kVulkanObjectTypePipeline = 21, + kVulkanObjectTypeDescriptorSetLayout = 22, + kVulkanObjectTypeSampler = 23, + kVulkanObjectTypeDescriptorSet = 24, + kVulkanObjectTypeDescriptorPool = 25, + kVulkanObjectTypeDescriptorUpdateTemplate = 26, + kVulkanObjectTypeSamplerYcbcrConversion = 27, kVulkanObjectTypePrivateDataSlot = 28, kVulkanObjectTypeSurfaceKHR = 29, kVulkanObjectTypeSwapchainKHR = 30, @@ -97,9 +97,9 @@ typedef enum VulkanObjectType { kVulkanObjectTypeIndirectExecutionSetEXT = 56, kVulkanObjectTypeIndirectCommandsLayoutEXT = 57, kVulkanObjectTypeMax = 58, - // Aliases for backwards compatibilty of "promoted" types - kVulkanObjectTypeSamplerYcbcrConversionKHR = kVulkanObjectTypeSamplerYcbcrConversion, + // Aliases for backwards compatibility of "promoted" types kVulkanObjectTypeDescriptorUpdateTemplateKHR = kVulkanObjectTypeDescriptorUpdateTemplate, + kVulkanObjectTypeSamplerYcbcrConversionKHR = kVulkanObjectTypeSamplerYcbcrConversion, kVulkanObjectTypePrivateDataSlotEXT = kVulkanObjectTypePrivateDataSlot, } VulkanObjectType; @@ -116,23 +116,23 @@ static const char * const object_string[kVulkanObjectTypeMax] = { "CommandBuffer", "Fence", "DeviceMemory", - "Event", "QueryPool", - "BufferView", "ImageView", + "CommandPool", + "RenderPass", + "Framebuffer", + "Event", + "BufferView", "ShaderModule", "PipelineCache", "PipelineLayout", "Pipeline", - "RenderPass", "DescriptorSetLayout", "Sampler", "DescriptorSet", "DescriptorPool", - "Framebuffer", - "CommandPool", - "SamplerYcbcrConversion", "DescriptorUpdateTemplate", + "SamplerYcbcrConversion", "PrivateDataSlot", "SurfaceKHR", "SwapchainKHR", @@ -178,23 +178,23 @@ const VkDebugReportObjectTypeEXT get_debug_report_enum[] = { 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_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_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 @@ -240,23 +240,23 @@ const VkObjectType get_object_type_enum[] = { 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_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_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 @@ -345,10 +345,10 @@ static inline VkObjectType convertDebugReportObjectToCoreObject(VkDebugReportObj 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) { @@ -435,10 +435,10 @@ static inline VkDebugReportObjectTypeEXT convertCoreObjectToDebugReportObject(Vk 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) { diff --git a/loader/loader.c b/loader/loader.c index 0ef7bd4d1..c79836aae 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -305,14 +306,13 @@ VkResult create_string_list(const struct loader_instance *inst, uint32_t allocat 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) { @@ -320,15 +320,38 @@ VkResult append_str_to_string_list(const struct loader_instance *inst, struct lo 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 return VK_ERROR_OUT_OF_HOST_MEMORY; } 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); @@ -341,6 +364,18 @@ VkResult copy_str_to_string_list(const struct loader_instance *inst, struct load 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) { @@ -353,6 +388,269 @@ void free_string_list(const struct loader_instance *inst, struct loader_string_l 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 "//../" 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) { + path = loader_instance_heap_realloc(inst, path, path_len, actual_len + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); + if (NULL == path) { + res = VK_ERROR_OUT_OF_HOST_MEMORY; + goto out; + } + // 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) { + 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) { @@ -1988,6 +2286,11 @@ VkResult loader_scanned_icd_add(const struct loader_instance *inst, struct loade } icd_tramp_list->count++; + // 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) { + goto out; + } out: if (res != VK_SUCCESS) { if (NULL != handle) { @@ -2262,7 +2565,7 @@ bool verify_meta_layer_component_layers(const struct loader_instance *inst, size } 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; @@ -2996,7 +3299,7 @@ void copy_data_file_info(const char *cur_path, const char *relative_path, size_t 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; @@ -3030,10 +3333,8 @@ void copy_data_file_info(const char *cur_path, const char *relative_path, size_t } } -// 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"); @@ -3042,15 +3343,26 @@ VkResult add_if_manifest_file(const struct loader_instance *inst, const char *fi 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 @@ -3242,12 +3554,14 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu 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 @@ -3795,18 +4109,26 @@ VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_t } #endif // VULKANSC - // 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; + 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; + } } - res = parse_generic_filter_environment_var(inst, VK_DRIVERS_DISABLE_ENV_VAR, &disable_filter); + + // Get a list of manifest files for ICDs + res = loader_get_data_files(inst, LOADER_DATA_FILE_MANIFEST_DRIVER, NULL, &manifest_files); if (VK_SUCCESS != res) { goto out; } - // Get a list of manifest files for ICDs - res = loader_get_data_files(inst, LOADER_DATA_FILE_MANIFEST_DRIVER, NULL, &manifest_files); + // 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; } @@ -3965,9 +4287,13 @@ VkResult get_override_layer_override_paths(struct loader_instance *inst, struct 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); @@ -4357,15 +4683,20 @@ loader_platform_dl_handle loader_open_layer_file(const struct loader_instance *i // 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; @@ -4391,6 +4722,7 @@ VkResult loader_enable_instance_layers(struct loader_instance *inst, const VkIns 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"); @@ -4417,15 +4749,17 @@ VkResult loader_enable_instance_layers(struct loader_instance *inst, const VkIns 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; @@ -4437,6 +4771,10 @@ VkResult loader_enable_instance_layers(struct loader_instance *inst, const VkIns warn_if_layers_are_older_than_application(inst); out: + if (enabled_layers_env != NULL) { + loader_free_getenv(enabled_layers_env, inst); + } + return res; } @@ -4795,6 +5133,11 @@ VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, c 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; @@ -5279,6 +5622,7 @@ VkResult loader_validate_instance_extensions(struct loader_instance *inst, const const VkInstanceCreateInfo *pCreateInfo) { VkExtensionProperties *extension_prop; char *env_value; + char *enabled_layers_env = NULL; bool check_if_known = true; VkResult res = VK_SUCCESS; @@ -5308,14 +5652,17 @@ VkResult loader_validate_instance_extensions(struct loader_instance *inst, const 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; } @@ -5401,6 +5748,10 @@ VkResult loader_validate_instance_extensions(struct loader_instance *inst, const 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; } @@ -5457,10 +5808,10 @@ VkResult loader_validate_device_extensions(struct loader_instance *this_instance // All named terminator_ 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; @@ -5678,7 +6029,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateI // API version 1.0 to a Vulkan 1.0 ICD. This does not apply to Vulkan SC as Vulkan // SC 1.0 is based on Vulkan 1.2 and does not need this compatibility workaround. // 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 = @@ -5696,6 +6047,27 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateI icd_create_info.pApplicationInfo = &icd_app_info; } #endif // VULKANSC + +#ifndef VULKANSC + // 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_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); + } +#endif // VULKANSC + 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) { @@ -6838,28 +7210,225 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDevices(VkInstance in 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_configuration_count > 0) { + // 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) { diff --git a/loader/loader.h b/loader/loader.h index 7d208a5c7..3505b33ae 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -110,14 +110,23 @@ VkResult loader_copy_to_new_str(const struct loader_instance *inst, const char * // 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); @@ -212,8 +221,13 @@ VkResult setup_loader_tramp_phys_dev_groups(struct loader_instance *inst, uint32 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, char *search_path, struct loader_string_list *out_files, bool use_first_found_manifest); diff --git a/loader/loader.rc b/loader/loader.rc index 38d62c8c6..2e5b60202 100644 --- a/loader/loader.rc +++ b/loader/loader.rc @@ -22,8 +22,8 @@ #include "winres.h" // All set through CMake -#define VER_FILE_VERSION 1, 4, 319, 0 -#define VER_FILE_DESCRIPTION_STR "1.4.319.Dev Build" +#define VER_FILE_VERSION 1, 4, 330, 0 +#define VER_FILE_DESCRIPTION_STR "1.4.330.Dev Build" #define VER_FILE_VERSION_STR "Vulkan Loader - Dev Build" #define VER_COPYRIGHT_STR "Copyright (C) 2015-2025" diff --git a/loader/loader_environment.c b/loader/loader_environment.c index 77593a9d3..8dd8493bb 100644 --- a/loader/loader_environment.c +++ b/loader/loader_environment.c @@ -448,20 +448,20 @@ bool check_name_matches_filter_environment_var(const char *name, const struct lo // 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,15 +560,11 @@ VkResult loader_add_environment_layers(struct loader_instance *inst, const enum out: - if (layer_env != NULL) { - loader_free_getenv(layer_env, inst); - } - return res; } -void parse_id_filter_enviroment_var(const struct loader_instance *inst, const char *env_var_name, - struct loader_envvar_id_filter *filter_struct) { +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); diff --git a/loader/loader_environment.h b/loader/loader_environment.h index da35237b5..ddbc29f10 100644 --- a/loader/loader_environment.h +++ b/loader/loader_environment.h @@ -49,12 +49,12 @@ VkResult parse_layers_disable_filter_environment_var(const struct loader_instanc 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_enviroment_var(const struct loader_instance *inst, const char *env_var_name, - struct loader_envvar_id_filter *filter_struct); +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_windows.c b/loader/loader_windows.c index 9e320f731..f7352f6b6 100644 --- a/loader/loader_windows.c +++ b/loader/loader_windows.c @@ -1122,7 +1122,7 @@ char *windows_get_app_package_manifest_path(const struct loader_instance *inst) 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 41b89ee65..78589a47c 100644 --- a/loader/log.c +++ b/loader/log.c @@ -274,3 +274,10 @@ void loader_log_asm_function_not_supported(const struct loader_instance *inst, V 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 1b594ab77..6075e1a0a 100644 --- a/loader/log.h +++ b/loader/log.h @@ -83,3 +83,7 @@ void loader_log_asm_function_not_supported(const struct loader_instance *inst, V const char *func_name) ASM_NAME("loader_log_asm_function_not_supported"); #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]); diff --git a/loader/settings.c b/loader/settings.c index d71069559..d8ebe27c9 100644 --- a/loader/settings.c +++ b/loader/settings.c @@ -44,13 +44,35 @@ void free_layer_configuration(const struct loader_instance* inst, loader_setting 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); + } + 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->layer_configurations); loader_instance_heap_free(inst, settings->settings_file_path); memset(settings, 0, sizeof(loader_settings)); } @@ -207,64 +229,408 @@ VkResult parse_layer_configurations(const struct loader_instance* inst, cJSON* s return res; } +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; + } +out: + if (res != VK_SUCCESS) { + free_driver_configuration(inst, additional_driver); + } + return res; +} + +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) { + 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++; + } +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); - 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; - } - loader_strncpy(*settings_file_path, path_len, base, base_len); - loader_strncat(*settings_file_path, path_len, suffix, suffix_len); - if (!loader_platform_file_exists(*settings_file_path)) { + 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; } - return VK_SUCCESS; + + 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) { + // 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 + #ifdef VULKANSC - VkResult res = - check_if_settings_path_exists(inst, loader_secure_getenv("HOME", inst), - "/.local/share/vulkansc/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path); + VkResult res = check_if_settings_path_exists(inst, xdg_config_home, "/vulkansc/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), - "/vulkansc/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path); + + res = check_if_settings_path_exists(inst, xdg_data_home, "/vulkansc/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", "/vulkansc/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, - settings_file_path); -#else - 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); + + // 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/vulkansc/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/vulkansc/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, "/vulkansc/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, + settings_file_path); + if (res == VK_SUCCESS) { + return res; + } + + res = check_if_settings_path_exists(inst, SYSCONFDIR, "/vulkansc/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, "/vulkansc/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); +#endif + res = check_if_settings_path_exists(inst, xdg_data_dirs, "/vulkansc/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); -#endif // VULKANSC +#else // VULKANSC + VkResult res = check_if_settings_path_exists(inst, xdg_config_home, "/vulkan/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, + settings_file_path); + if (res == VK_SUCCESS) { + return res; + } + + res = check_if_settings_path_exists(inst, xdg_data_home, "/vulkan/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, + settings_file_path); + if (res == VK_SUCCESS) { + return res; + } + + // 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/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/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/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/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/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/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, + settings_file_path); + if (res == VK_SUCCESS) { + return res; + } +#endif + + 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; +} + +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; + return true; } bool check_if_settings_are_equal(loader_settings* a, loader_settings* b) { @@ -275,19 +641,17 @@ bool check_if_settings_are_equal(loader_settings* a, loader_settings* b) { are_equal &= a->has_unordered_layer_location == b->has_unordered_layer_location; are_equal &= a->debug_level == b->debug_level; are_equal &= a->layer_configuration_count == b->layer_configuration_count; + are_equal &= a->additional_driver_count == b->additional_driver_count; + 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; } @@ -321,6 +685,37 @@ void log_settings(const struct loader_instance* inst, loader_settings* settings) 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_configuration_count > 0) { + 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, "---------------------------------"); } @@ -447,8 +842,10 @@ VkResult get_loader_settings(const struct loader_instance* inst, loader_settings 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); @@ -462,22 +859,23 @@ VkResult get_loader_settings(const struct loader_instance* inst, loader_settings 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; } @@ -490,9 +888,29 @@ VkResult get_loader_settings(const struct loader_instance* inst, loader_settings } } - 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_configuration_count != 0 || + loader_settings->additional_driver_count != 0 || loader_settings->device_configuration_count != 0) { + 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); @@ -651,6 +1069,7 @@ TEST_FUNCTION_EXPORT VkResult get_settings_layers(const struct loader_instance* 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) && + settings_layers->list[j].lib_name != NULL && newly_added_layer->lib_name != NULL && strcmp(settings_layers->list[j].lib_name, newly_added_layer->lib_name) == 0) { should_remove = true; break; @@ -885,3 +1304,39 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst, 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_configuration_count > 0) { + should_use = false; + } +out: + release_current_settings_lock(inst); + return should_use; +} diff --git a/loader/settings.h b/loader/settings.h index 4e776ff0a..df3448619 100644 --- a/loader/settings.h +++ b/loader/settings.h @@ -34,6 +34,7 @@ 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; @@ -61,6 +62,18 @@ typedef struct loader_settings_layer_configuration { } 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; @@ -69,6 +82,13 @@ typedef struct loader_settings { 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; + + uint32_t device_configuration_count; + loader_settings_device_configuration* device_configurations; + char* settings_file_path; } loader_settings; @@ -112,3 +132,11 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst, 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/trampoline.c b/loader/trampoline.c index 61387a4c9..ac6422d55 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -882,9 +882,9 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstan struct loader_envvar_id_filter vendor_id_filter; struct loader_envvar_id_filter driver_id_filter; - parse_id_filter_enviroment_var(inst, VK_DEVICE_ID_FILTER_ENV_VAR, &device_id_filter); - parse_id_filter_enviroment_var(inst, VK_VENDOR_ID_FILTER_ENV_VAR, &vendor_id_filter); - parse_id_filter_enviroment_var(inst, VK_DRIVER_ID_FILTER_ENV_VAR, &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 if ((0 == device_id_filter.count) && (0 == vendor_id_filter.count) && (0 == driver_id_filter.count)) { @@ -2686,9 +2686,9 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups( struct loader_envvar_id_filter vendor_id_filter; struct loader_envvar_id_filter driver_id_filter; - parse_id_filter_enviroment_var(inst, VK_DEVICE_ID_FILTER_ENV_VAR, &device_id_filter); - parse_id_filter_enviroment_var(inst, VK_VENDOR_ID_FILTER_ENV_VAR, &vendor_id_filter); - parse_id_filter_enviroment_var(inst, VK_DRIVER_ID_FILTER_ENV_VAR, &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. if ((0 == device_id_filter.count) && (0 == vendor_id_filter.count) && (0 == driver_id_filter.count)) { diff --git a/loader/unknown_ext_chain_gas_x86.S b/loader/unknown_ext_chain_gas_x86.S index 5ee020512..2a9bb81b3 100644 --- a/loader/unknown_ext_chain_gas_x86.S +++ b/loader/unknown_ext_chain_gas_x86.S @@ -88,11 +88,16 @@ vkdev_ext\num: .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 @@ vkPhysDevExtTramp\num: .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 @@ terminError\num: 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 5c0cf4051..26316b776 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 @@ -312,7 +312,7 @@ static inline char *loader_platform_dirname(char *path) { return dirname(path); // 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; diff --git a/loader/wsi.c b/loader/wsi.c index 59ab1456b..ddc8e7678 100644 --- a/loader/wsi.c +++ b/loader/wsi.c @@ -850,8 +850,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance insta const struct loader_struct_type_info ci_types[] = { {VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, sizeof(VkWin32SurfaceCreateInfoKHR)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkWin32SurfaceCreateInfoKHR", pAllocator); + 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; @@ -949,8 +952,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(VkInstance ins const struct loader_struct_type_info ci_types[] = { {VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, sizeof(VkWaylandSurfaceCreateInfoKHR)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkWaylandSurfaceCreateInfoKHR", pAllocator); + 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; @@ -1052,8 +1058,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(VkInstance instanc const struct loader_struct_type_info ci_types[] = { {VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, sizeof(VkXcbSurfaceCreateInfoKHR)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkXcbSurfaceCreateInfoKHR", pAllocator); + 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; @@ -1158,8 +1167,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(VkInstance instan const struct loader_struct_type_info ci_types[] = { {VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, sizeof(VkXlibSurfaceCreateInfoKHR)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkXlibSurfaceCreateInfoKHR", pAllocator); + 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; @@ -1264,8 +1276,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDirectFBSurfaceEXT(VkInstance in const struct loader_struct_type_info ci_types[] = { {VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT, sizeof(VkDirectFBSurfaceCreateInfoEXT)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkDirectFBSurfaceCreateInfoEXT", pAllocator); + 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; @@ -1412,8 +1427,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateHeadlessSurfaceEXT(VkInstance in const struct loader_struct_type_info ci_types[] = { {VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT, sizeof(VkHeadlessSurfaceCreateInfoEXT)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkHeadlessSurfaceCreateInfoEXT", pAllocator); + 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; @@ -1498,8 +1516,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance insta const struct loader_struct_type_info ci_types[] = { {VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK, sizeof(VkMacOSSurfaceCreateInfoMVK)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkMacOSSurfaceCreateInfoMVK", pAllocator); + 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; @@ -1609,8 +1630,11 @@ terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamD const struct loader_struct_type_info ci_types[] = { {VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP, sizeof(VkStreamDescriptorSurfaceCreateInfoGGP)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkStreamDescriptorSurfaceCreateInfoGGP", pAllocator); + 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; @@ -1664,8 +1688,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance insta const struct loader_struct_type_info ci_types[] = { {VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT, sizeof(VkMetalSurfaceCreateInfoEXT)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkMetalSurfaceCreateInfoEXT", pAllocator); + 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; @@ -1726,8 +1753,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateScreenSurfaceQNX(VkInstance inst const struct loader_struct_type_info ci_types[] = { {VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX, sizeof(VkScreenSurfaceCreateInfoQNX)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkScreenSurfaceCreateInfoQNX", pAllocator); + 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; @@ -1827,8 +1857,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateViSurfaceNN(VkInstance instance, const struct loader_struct_type_info ci_types[] = { {VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN, sizeof(VkViSurfaceCreateInfoNN)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkViSurfaceCreateInfoNN", pAllocator); + 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; @@ -2141,8 +2174,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstanc {VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR, sizeof(VkDisplaySurfaceCreateInfoKHR)}, {VK_STRUCTURE_TYPE_DISPLAY_SURFACE_STEREO_CREATE_INFO_NV, sizeof(VkDisplaySurfaceStereoCreateInfoNV)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkDisplaySurfaceCreateInfoKHR", pAllocator); + 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; @@ -2570,8 +2606,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(VkInstan const struct loader_struct_type_info ci_types[] = { {VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA, sizeof(VkImagePipeSurfaceCreateInfoFUCHSIA)}, }; - copy_surface_create_info(loader_inst, icd_surface, pCreateInfo, sizeof(ci_types) / sizeof(ci_types[0]), ci_types, - "VkImagePipeSurfaceCreateInfoFUCHSIA", pAllocator); + 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; @@ -2598,58 +2637,54 @@ vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, cons } #ifndef VULKANSC // Vulkan SC does not support VK_EXT_surface_maintenance1 yet -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->enabled_instance_extensions.ext_surface_maintenance1) { - 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; - } - // If no VkSurfacePresentModeEXT was present, return - if (present_mode == VK_PRESENT_MODE_MAX_ENUM_KHR) { - return; + 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; } - - 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) { - if (surface_present_mode_compatibility->presentModeCount != 0) { - surface_present_mode_compatibility->pPresentModes[0] = present_mode; - surface_present_mode_compatibility->presentModeCount = 1; - } - } else { + 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_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 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; + } else { + surface_present_mode_compatibility->presentModeCount = 1; } - 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; } } #endif // VULKANSC @@ -2701,8 +2736,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K #ifndef VULKANSC // Vulkan SC does not support VK_EXT_surface_maintenance1 yet // 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->enabled_instance_extensions.ext_surface_maintenance1) { - 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); } #endif // VULKANSC @@ -2727,7 +2763,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K &pSurfaceCapabilities->surfaceCapabilities); #ifndef VULKANSC // Vulkan SC does not support VK_EXT_surface_maintenance1 yet - 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); + } #endif // VULKANSC return res; } diff --git a/scripts/generate_source.py b/scripts/generate_source.py index 515a530f7..90533835b 100755 --- a/scripts/generate_source.py +++ b/scripts/generate_source.py @@ -66,6 +66,7 @@ def RunGenerators(api: str, registry: str, directory: str, styleFile: str, targe 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 @@ -75,6 +76,7 @@ def RunGenerators(api: str, registry: str, directory: str, styleFile: str, targe # Generated directory and dispatch table helper file name may be API specific (e.g. Vulkan SC) generated_directory = 'loader/generated-vksc' if api == 'vulkansc' else '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': { @@ -101,6 +103,11 @@ def RunGenerators(api: str, registry: str, directory: str, styleFile: str, targe 'generator' : DispatchTableHelperGenerator, 'genCombined': False, 'directory' : 'tests/framework/layer/generated-vksc' if api == 'vulkansc' else 'tests/framework/layer/generated', + }, + f'{result_to_string_filename}': { + 'generator' : VkResultToStringGenerator, + 'genCombined': False, + 'directory' : 'tests/framework/generated', } }) @@ -115,7 +122,7 @@ def RunGenerators(api: str, registry: str, directory: str, styleFile: str, targe for index, target in enumerate(targets, start=1): print(f'[{index}|{len(targets)}] Generating {target}') - # First grab a class contructor object and create an instance + # First grab a class constructor object and create an instance generator = generators[target]['generator'] gen = generator() diff --git a/scripts/generators/helper_file_generator.py b/scripts/generators/helper_file_generator.py index e3c756a06..7cea3dff6 100644 --- a/scripts/generators/helper_file_generator.py +++ b/scripts/generators/helper_file_generator.py @@ -137,7 +137,7 @@ def generate(self): out.append(f' kVulkanObjectType{name} = {number},\n') out.append(f' kVulkanObjectTypeMax = {enum_num},\n') - out.append(' // Aliases for backwards compatibilty of "promoted" types\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') diff --git a/scripts/generators/loader_extension_generator.py b/scripts/generators/loader_extension_generator.py index 65a7b4b93..351272dca 100644 --- a/scripts/generators/loader_extension_generator.py +++ b/scripts/generators/loader_extension_generator.py @@ -264,16 +264,6 @@ def print_vk_layer_dispatch_table(self, out): self.OutputLayerInstanceDispatchTable(out) self.OutputLayerDeviceDispatchTable(out) - # 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 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: @@ -679,14 +669,11 @@ def InitDeviceFunctionTerminatorDispatchTable(self, out): out.append(f'#if defined({command.protect})\n') current_block = self.DescribeBlock(command, current_block, out) - if command.name == 'vkGetDeviceGroupSurfacePresentModes2EXT': # command.extensions[0].depends in [x for x in self.vk.commands.values() if x.device]: - # Hardcode the dependency expression as vulkan_object.py doesn't expose this information - dep_expr = self.ConvertDependencyExpression('VK_KHR_device_group,VK_VERSION_1_1', lambda ext_name: f'dev->driver_extensions.{ext_name[3:].lower()}_enabled') - out.append(f' if (dev->driver_extensions.{command.extensions[0][3:].lower()}_enabled && ({dep_expr}))\n') - out.append(f' dispatch->{command.name[2:]} = (PFN_{(command.name)})gpda(dev->icd_device, "{(command.name)}");\n') - else: - out.append(f' if (dev->driver_extensions.{command.extensions[0][3:].lower()}_enabled)\n') - out.append(f' dispatch->{command.name[2:]} = (PFN_{(command.name)})gpda(dev->icd_device, "{(command.name)}");\n') + 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') @@ -1319,12 +1306,10 @@ def DeviceExtensionGetTerminator(self, out): out.append(f' if (!strcmp(name, "{command.name[2:]}")) {{\n') out.append(' *found_name = true;\n') - if command.name == 'vkGetDeviceGroupSurfacePresentModes2EXT': # command.extensions[0].depends in [x for x in self.vk.commands.values() if x.device]: - # Hardcode the dependency expression as vulkan_object.py doesn't expose this information - dep_expr = self.ConvertDependencyExpression('VK_KHR_device_group,VK_VERSION_1_1', lambda ext_name: f'dev->driver_extensions.{ext_name[3:].lower()}_enabled') - out.append(f' return (dev->driver_extensions.{command.extensions[0][3:].lower()}_enabled && ({dep_expr})) ?\n') - else: - out.append(f' return dev->driver_extensions.{command.extensions[0][3:].lower()}_enabled ?\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') 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 000000000..9efb4aa24 --- /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 +# Author: Charles Giessen + +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 +#include + +#include + +''') + + 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(result);\n') + out.append(' }\n') + out.append(' }\n') diff --git a/scripts/known_good.json b/scripts/known_good.json index 52d05cd9e..d208637d1 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.319" + "commit": "v1.4.330" }, { "name": "Vulkan-Headers", @@ -19,7 +19,7 @@ "cmake_options": [ "-DGEN_VULKANSC_COMBINED=ON" ], - "commit": "vksc1.0.19" + "commit": "bf0610365d145d59daad3027ffef1a254e6169f9" }, { "name": "googletest", diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index dd0923e84..19a70a2cc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -69,6 +69,8 @@ endif() 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) @@ -95,7 +97,12 @@ add_executable( loader_testing_main.cpp loader_fuzz_tests.cpp ) -target_link_libraries(test_fuzzing PUBLIC testing_dependencies vulkan) + +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() if(VULKANSC) target_include_directories(test_fuzzing PUBLIC ${CMAKE_SOURCE_DIR}/loader ${CMAKE_SOURCE_DIR}/loader/generated-vksc) else() diff --git a/tests/framework/CMakeLists.txt b/tests/framework/CMakeLists.txt index ae0f08295..0e6bff12a 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) - -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 the framework folder, in the framework binary, and in the whole project (mainly for loader/generated) -if(VULKANSC) - target_include_directories(testing_framework_util PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/loader/generated-vksc) -else() - target_include_directories(testing_framework_util PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/loader/generated) -endif() +#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) - 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) - 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() +# setup framework_config_$ using framework_config_temp.h.in as a source +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/framework_config_$.h" INPUT "${CMAKE_CURRENT_BINARY_DIR}/framework_config_temp.h.in") -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_$.h") function(AddSharedLibrary LIBRARY_NAME) set(singleValueArgs DEF_FILE) @@ -67,26 +40,14 @@ function(AddSharedLibrary LIBRARY_NAME) 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_$ using framework_config_temp.h.in as a source -file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/framework_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_$.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}) -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 1dc5b73a4..20e1209ae 100644 --- a/tests/framework/README.md +++ b/tests/framework/README.md @@ -136,8 +136,7 @@ There are many utilities that the test framework and tests have access to. These * 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-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 000000000..a38496a70 Binary files /dev/null and b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6470575830925312 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 000000000..c5a8b7b23 Binary files /dev/null and b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-instance_enumerate_fuzzer-6740380288876544 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 000000000..ad9eccc99 Binary files /dev/null and b/tests/framework/data/fuzz_test_minimized_test_cases/clusterfuzz-testcase-minimized-settings_fuzzer-4626669072875520 differ diff --git a/tests/framework/data/fuzzer_output.json b/tests/framework/data/fuzzer_output.json index 571378087..6032f8079 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 b70e42b11..8c0c1f78e 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 "$" 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 000000000..cdf507fa9 --- /dev/null +++ b/tests/framework/generated/vk_result_to_string_helper.h @@ -0,0 +1,103 @@ +#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 +#include + +#include + +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_INVALID_PIPELINE_CACHE_DATA): + return os << "VK_ERROR_INVALID_PIPELINE_CACHE_DATA"; + case (VK_ERROR_NO_PIPELINE_MATCH): + return os << "VK_ERROR_NO_PIPELINE_MATCH"; + 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_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT): + return os << "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT"; + default: + return os << static_cast(result); + } +} diff --git a/tests/framework/icd/test_icd.cpp b/tests/framework/icd/test_icd.cpp index 17a492890..33f93679d 100644 --- a/tests/framework/icd/test_icd.cpp +++ b/tests/framework/icd/test_icd.cpp @@ -29,6 +29,13 @@ #include "test_icd.h" +#include +#include + +#include + +#include "equality_helpers.h" + // export vk_icdGetInstanceProcAddr #if !defined(TEST_ICD_EXPORT_ICD_GIPA) #define TEST_ICD_EXPORT_ICD_GIPA 0 @@ -92,7 +99,7 @@ bool IsInstanceExtensionEnabled(const char* 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; })) { @@ -103,22 +110,13 @@ bool IsPhysicalDeviceExtensionAvailable(const char* extension_name) { } PhysicalDevice& GetPhysDevice(VkPhysicalDevice physicalDevice) { - for (auto& phys_dev : icd.physical_devices) { - if (phys_dev.vk_physical_device.handle == physicalDevice) return phys_dev; + if (icd.physical_devices.count(physicalDevice) > 0) { + return icd.physical_devices.at(physicalDevice); } assert(false && "vkPhysicalDevice not found!"); - return icd.physical_devices[0]; -} - -std::vector::iterator find_physical_device(VkPhysicalDevice physicalDevice) { - 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; - }); - return found; + return icd.physical_devices.at(icd.physical_devices.begin()->first); } -bool is_physical_device_found(std::vector::iterator found) { return found != icd.physical_devices.end(); } - 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); @@ -127,22 +125,24 @@ bool is_valid_surface(VkSurfaceKHR surface_to_check) { struct FindDevice { bool found = false; - uint32_t phys_dev_index = 0; + VkPhysicalDevice phys_dev = 0; uint32_t dev_index = 0; }; FindDevice lookup_device(VkDevice device) { FindDevice fd{}; - for (uint32_t p = 0; p < icd.physical_devices.size(); p++) { - auto const& phys_dev = icd.physical_devices.at(p); + 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.found = true; - fd.phys_dev_index = p; fd.dev_index = d; - return fd; + break; } } + return fd; } return fd; } @@ -301,15 +301,22 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices([[maybe_unused]] if (pPhysicalDevices == nullptr) { *pPhysicalDeviceCount = static_cast(icd.physical_devices.size()); } else { + using SortPair = std::pair; + std::vector 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; } @@ -349,10 +356,15 @@ test_vkEnumeratePhysicalDeviceGroups([[maybe_unused]] VkInstance instance, uint3 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] = {}; } @@ -492,7 +504,7 @@ VKAPI_ATTR void VKAPI_CALL test_vkDestroyDebugReportCallbackEXT([[maybe_unused]] VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectTagEXT(VkDevice dev, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) { 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(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; @@ -505,7 +517,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectTagEXT(VkDevice dev, c VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectNameEXT(VkDevice dev, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) { 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(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; @@ -523,7 +535,7 @@ VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerInsertEXT(VkCommandBuffer, const VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectNameEXT(VkDevice dev, const VkDebugUtilsObjectNameInfoEXT* pNameInfo) { if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) { VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pNameInfo->objectHandle); - if (pd != icd.physical_devices.at(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; @@ -536,7 +548,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectNameEXT(VkDevice dev, c VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectTagEXT(VkDevice dev, const VkDebugUtilsObjectTagInfoEXT* pTagInfo) { if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) { VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pTagInfo->objectHandle); - if (pd != icd.physical_devices.at(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; @@ -584,19 +596,19 @@ VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceQueueFamilyProperties(VkPhysi VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) { check_allocator_handle(pAllocator); - auto found = find_physical_device(physicalDevice); - if (!is_physical_device_found(found)) { + if (icd.physical_devices.count(physicalDevice) == 0) { return VK_ERROR_INITIALIZATION_FAILED; } + auto& found = icd.physical_devices.at(physicalDevice); auto device_handle = DispatchableHandle(); *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; } @@ -606,9 +618,10 @@ VKAPI_ATTR void VKAPI_CALL test_vkDestroyDevice(VkDevice device, const VkAllocat if (found != icd.device_handles.end()) icd.device_handles.erase(found); 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); } #ifndef VULKANSC // VK_EXT_tooling_info is not supported in Vulkan SC @@ -896,9 +909,8 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysi } } if (nullptr != pSupported) { - auto found = find_physical_device(physicalDevice); - if (is_physical_device_found(found)) { - *pSupported = found->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; @@ -1158,7 +1170,7 @@ VKAPI_ATTR void VKAPI_CALL test_vkGetDeviceQueue([[maybe_unused]] VkDevice devic uint32_t queueIndex, VkQueue* pQueue) { 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; } } @@ -1248,6 +1260,16 @@ VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties2(VkPhysicalDevice layered_driver_props->underlyingAPI = phys_dev.layered_driver_underlying_api; } #endif // VULKANSC + if (pNext->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES) { + auto* vulkan_11_props = reinterpret_cast(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(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(pNext); *device_driver_props = phys_dev.driver_properties; @@ -1712,7 +1734,7 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_physical_device_func([[maybe_unused } #endif // VULKANSC - 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); @@ -1750,9 +1772,9 @@ PFN_vkVoidFunction get_instance_func(VkInstance instance, const char* pName) { return nullptr; } -bool should_check(std::vector 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* 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; } @@ -1761,18 +1783,20 @@ bool should_check(std::vector const& exts, VkDevice device, const c } PFN_vkVoidFunction get_device_func(VkDevice device, const char* pName) { - DeviceCreateInfo create_info{}; + std::vector* enabled_extensions = nullptr; + FindDevice found_device{}; if (device != nullptr) { - auto fd = 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); @@ -1780,15 +1804,15 @@ PFN_vkVoidFunction get_device_func(VkDevice device, const char* pName) { 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); } #ifndef VULKANSC // VK_EXT_debug_marker is not supported in Vulkan SC - 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); @@ -1806,13 +1830,21 @@ PFN_vkVoidFunction get_device_func(VkDevice device, const char* pName) { 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; } diff --git a/tests/framework/icd/test_icd.h b/tests/framework/icd/test_icd.h index 54b20bf4e..441f642e6 100644 --- a/tests/framework/icd/test_icd.h +++ b/tests/framework/icd/test_icd.h @@ -29,7 +29,14 @@ #pragma once -#include "test_util.h" +#include +#include +#include +#include + +#include "util/dispatchable_handle.h" +#include "util/platform_wsi.h" +#include "util/functions.h" #include "layer/layer_util.h" @@ -72,6 +79,9 @@ inline std::ostream& operator<<(std::ostream& os, const InterfaceVersionCheck& r } return os << static_cast(result); } + +using VulkanUUID = std::array; + // clang-format on // Move only type because it holds a DispatchableHandle @@ -82,6 +92,8 @@ struct PhysicalDevice { DispatchableHandle vk_physical_device; 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) @@ -127,6 +139,9 @@ struct PhysicalDevice { 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 device_handles; std::vector device_create_infos; @@ -146,9 +161,14 @@ struct PhysicalDevice { 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 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; @@ -194,7 +214,31 @@ struct TestICD { BUILDER_VECTOR(Extension, instance_extensions, instance_extension) std::vector enabled_instance_extensions; - BUILDER_VECTOR_MOVE_ONLY(PhysicalDevice, physical_devices, physical_device); + std::unordered_map 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; + } + + 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); @@ -236,6 +280,10 @@ struct TestICD { return info; } + // 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 device_to_physical_device_map; + #if defined(WIN32) 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 f22db2892..000000000 --- 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 - */ - -#pragma once - -#include -#include -#include - -// 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 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-vksc/vk_dispatch_table_helper.h b/tests/framework/layer/generated-vksc/vk_dispatch_table_helper.h index b709415fe..8f36dc11a 100644 --- a/tests/framework/layer/generated-vksc/vk_dispatch_table_helper.h +++ b/tests/framework/layer/generated-vksc/vk_dispatch_table_helper.h @@ -59,25 +59,44 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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->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->CreateCommandPool = (PFN_vkCreateCommandPool)gpa(device, "vkCreateCommandPool"); + 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->CreatePipelineCache = (PFN_vkCreatePipelineCache)gpa(device, "vkCreatePipelineCache"); table->DestroyPipelineCache = (PFN_vkDestroyPipelineCache)gpa(device, "vkDestroyPipelineCache"); - 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"); @@ -91,19 +110,21 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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->CreateCommandPool = (PFN_vkCreateCommandPool)gpa(device, "vkCreateCommandPool"); - 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"); @@ -113,57 +134,30 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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->GetDeviceQueue2 = (PFN_vkGetDeviceQueue2)gpa(device, "vkGetDeviceQueue2"); + table->CmdDispatchBase = (PFN_vkCmdDispatchBase)gpa(device, "vkCmdDispatchBase"); + table->GetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport)gpa(device, "vkGetDescriptorSetLayoutSupport"); table->CreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)gpa(device, "vkCreateSamplerYcbcrConversion"); table->DestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion)gpa(device, "vkDestroySamplerYcbcrConversion"); - 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"); @@ -171,13 +165,16 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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->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"); @@ -185,6 +182,12 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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"); @@ -204,26 +207,23 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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->CmdSetLineStipple = (PFN_vkCmdSetLineStipple)gpa(device, "vkCmdSetLineStipple"); table->MapMemory2 = (PFN_vkMapMemory2)gpa(device, "vkMapMemory2"); table->UnmapMemory2 = (PFN_vkUnmapMemory2)gpa(device, "vkUnmapMemory2"); - table->CmdBindIndexBuffer2 = (PFN_vkCmdBindIndexBuffer2)gpa(device, "vkCmdBindIndexBuffer2"); - table->GetRenderingAreaGranularity = (PFN_vkGetRenderingAreaGranularity)gpa(device, "vkGetRenderingAreaGranularity"); table->GetDeviceImageSubresourceLayout = (PFN_vkGetDeviceImageSubresourceLayout)gpa(device, "vkGetDeviceImageSubresourceLayout"); table->GetImageSubresourceLayout2 = (PFN_vkGetImageSubresourceLayout2)gpa(device, "vkGetImageSubresourceLayout2"); - table->CmdPushDescriptorSet = (PFN_vkCmdPushDescriptorSet)gpa(device, "vkCmdPushDescriptorSet"); - table->CmdSetRenderingAttachmentLocations = (PFN_vkCmdSetRenderingAttachmentLocations)gpa(device, "vkCmdSetRenderingAttachmentLocations"); - table->CmdSetRenderingInputAttachmentIndices = (PFN_vkCmdSetRenderingInputAttachmentIndices)gpa(device, "vkCmdSetRenderingInputAttachmentIndices"); - table->CmdBindDescriptorSets2 = (PFN_vkCmdBindDescriptorSets2)gpa(device, "vkCmdBindDescriptorSets2"); - table->CmdPushConstants2 = (PFN_vkCmdPushConstants2)gpa(device, "vkCmdPushConstants2"); - table->CmdPushDescriptorSet2 = (PFN_vkCmdPushDescriptorSet2)gpa(device, "vkCmdPushDescriptorSet2"); 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->CmdBindDescriptorSets2 = (PFN_vkCmdBindDescriptorSets2)gpa(device, "vkCmdBindDescriptorSets2"); + table->CmdPushConstants2 = (PFN_vkCmdPushConstants2)gpa(device, "vkCmdPushConstants2"); + table->CmdPushDescriptorSet2 = (PFN_vkCmdPushDescriptorSet2)gpa(device, "vkCmdPushDescriptorSet2"); + 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->GetCommandPoolMemoryConsumption = (PFN_vkGetCommandPoolMemoryConsumption)gpa(device, "vkGetCommandPoolMemoryConsumption"); table->GetFaultData = (PFN_vkGetFaultData)gpa(device, "vkGetFaultData"); table->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR"); diff --git a/tests/framework/layer/generated/vk_dispatch_table_helper.h b/tests/framework/layer/generated/vk_dispatch_table_helper.h index f8379812b..41535dac5 100644 --- a/tests/framework/layer/generated/vk_dispatch_table_helper.h +++ b/tests/framework/layer/generated/vk_dispatch_table_helper.h @@ -28,7 +28,7 @@ #include #include #include -#include "vk_layer_dispatch_table.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) { @@ -62,30 +62,50 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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->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->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"); @@ -100,20 +120,21 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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->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"); @@ -123,62 +144,35 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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->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->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->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"); @@ -186,13 +180,16 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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->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"); @@ -200,6 +197,12 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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"); @@ -219,28 +222,25 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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->CmdSetLineStipple = (PFN_vkCmdSetLineStipple)gpa(device, "vkCmdSetLineStipple"); table->MapMemory2 = (PFN_vkMapMemory2)gpa(device, "vkMapMemory2"); table->UnmapMemory2 = (PFN_vkUnmapMemory2)gpa(device, "vkUnmapMemory2"); - table->CmdBindIndexBuffer2 = (PFN_vkCmdBindIndexBuffer2)gpa(device, "vkCmdBindIndexBuffer2"); - table->GetRenderingAreaGranularity = (PFN_vkGetRenderingAreaGranularity)gpa(device, "vkGetRenderingAreaGranularity"); 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->CmdSetRenderingAttachmentLocations = (PFN_vkCmdSetRenderingAttachmentLocations)gpa(device, "vkCmdSetRenderingAttachmentLocations"); - table->CmdSetRenderingInputAttachmentIndices = (PFN_vkCmdSetRenderingInputAttachmentIndices)gpa(device, "vkCmdSetRenderingInputAttachmentIndices"); 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->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->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"); @@ -361,6 +361,7 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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"); @@ -369,6 +370,9 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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->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"); @@ -707,6 +711,8 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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"); @@ -723,6 +729,15 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp 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_OHOS) + table->GetSwapchainGrallocUsageOHOS = (PFN_vkGetSwapchainGrallocUsageOHOS)gpa(device, "vkGetSwapchainGrallocUsageOHOS"); +#endif // VK_USE_PLATFORM_OHOS +#if defined(VK_USE_PLATFORM_OHOS) + table->AcquireImageOHOS = (PFN_vkAcquireImageOHOS)gpa(device, "vkAcquireImageOHOS"); +#endif // VK_USE_PLATFORM_OHOS +#if defined(VK_USE_PLATFORM_OHOS) + table->QueueSignalReleaseImageOHOS = (PFN_vkQueueSignalReleaseImageOHOS)gpa(device, "vkQueueSignalReleaseImageOHOS"); +#endif // VK_USE_PLATFORM_OHOS #if defined(VK_USE_PLATFORM_METAL_EXT) table->GetMemoryMetalHandleEXT = (PFN_vkGetMemoryMetalHandleEXT)gpa(device, "vkGetMemoryMetalHandleEXT"); #endif // VK_USE_PLATFORM_METAL_EXT diff --git a/tests/framework/layer/layer_util.h b/tests/framework/layer/layer_util.h index 59e9b1f54..74cabb4c4 100644 --- a/tests/framework/layer/layer_util.h +++ b/tests/framework/layer/layer_util.h @@ -29,7 +29,9 @@ #pragma once -#include "test_util.h" +#include "builder_defines.h" + +#include "vulkan_object_wrappers.h" struct LayerDefinition { BUILDER_VALUE(std::string, layerName) @@ -40,10 +42,10 @@ struct LayerDefinition { 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 6027cde18..2236fd9fe 100644 --- a/tests/framework/layer/test_layer.cpp +++ b/tests/framework/layer/test_layer.cpp @@ -29,6 +29,13 @@ #include "test_layer.h" +#include + +#include + +#include "util/test_defines.h" +#include "util/equality_helpers.h" + #ifdef VULKANSC #include "generated-vksc/vk_dispatch_table_helper.h" #else @@ -253,7 +260,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateInstance(const VkInstanceCreateInfo* 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 008595f56..eb56cf621 100644 --- a/tests/framework/layer/test_layer.h +++ b/tests/framework/layer/test_layer.h @@ -29,11 +29,11 @@ #pragma once -#include "test_util.h" - #include +#include -#include "layer/layer_util.h" +#include +#include #ifdef VULKANSC #include "loader/generated-vksc/vk_layer_dispatch_table.h" @@ -41,6 +41,10 @@ #include "loader/generated/vk_layer_dispatch_table.h" #endif // VULKANSC +#include "util/functions.h" + +#include "layer_util.h" + /* Interface Version 0 */ diff --git a/tests/framework/shim/shim.h b/tests/framework/shim/shim.h index b98007dbc..760fd993a 100644 --- a/tests/framework/shim/shim.h +++ b/tests/framework/shim/shim.h @@ -27,13 +27,19 @@ #pragma once -#include "test_util.h" +#include +#include +#include +#include #include #include -#include +#include -#if defined(WIN32) +#if defined(_WIN32) + +#include +#include #include #include #include @@ -46,10 +52,18 @@ #include #endif -enum class ManifestCategory { implicit_layer, explicit_layer, icd, settings }; +#include "util/test_defines.h" + +#if TESTING_COMMON_UNIX_PLATFORMS +#include +#endif + +#include "util/folder_manager.h" +#include "util/functions.h" + enum class GpuType { unspecified, integrated, discrete, external }; -#if defined(WIN32) +#if defined(_WIN32) #ifdef VULKANSC #define VK_VARIANT_REG_STR "SC" #define VK_VARIANT_REG_STR_W L"SC" @@ -122,15 +136,15 @@ struct D3DKMT_Adapter { D3DKMT_Adapter& add_path(std::filesystem::path src, std::vector& 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 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 @@ -141,12 +155,9 @@ struct FrameworkEnvironment; // forward declaration // defined in the .cpp wont be found by the rest of the application struct PlatformShim { PlatformShim() { fputs_stderr_log.reserve(65536); } - PlatformShim(GetFoldersFunc get_folders_by_name_function) : get_folders_by_name_function(get_folders_by_name_function) { - fputs_stderr_log.reserve(65536); - } // Used to get info about which drivers & layers have been added to folders - GetFoldersFunc get_folders_by_name_function; + fs::FileSystemManager* file_system_manager; // Captures the output to stderr from fputs & fputc - aka the output of loader_log() std::string fputs_stderr_log; @@ -154,28 +165,25 @@ struct PlatformShim { // 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); @@ -207,27 +215,18 @@ struct PlatformShim { size_t created_key_count = 0; std::vector 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); - - 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 system_library_redirection_map; void set_app_package_path(std::filesystem::path const& path); - std::unordered_map redirection_map; - std::unordered_map dlopen_redirection_map; - std::unordered_set known_path_set; - void set_elevated_privilege(bool elev) { use_fake_elevation = elev; } bool use_fake_elevation = false; @@ -237,6 +236,7 @@ struct PlatformShim { std::string bundle_contents; #endif #endif + bool is_finished_setup = false; bool is_during_destruction = false; }; @@ -245,12 +245,12 @@ std::string category_path_name(ManifestCategory category); extern "C" { // dynamically link on windows and macos -#if defined(WIN32) || defined(__APPLE__) -using PFN_get_platform_shim = PlatformShim* (*)(GetFoldersFunc get_folders_by_name_function); +#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(GetFoldersFunc get_folders_by_name_function); +PlatformShim* get_platform_shim(); #endif } diff --git a/tests/framework/shim/shim_common.cpp b/tests/framework/shim/shim_common.cpp index 3e2ff2e65..0c73526df 100644 --- a/tests/framework/shim/shim_common.cpp +++ b/tests/framework/shim/shim_common.cpp @@ -28,20 +28,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 parse_env_var_list(std::string const& var) { std::vector 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) { @@ -59,7 +55,7 @@ std::vector parse_env_var_list(std::string const& var) { return items; } -#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) { @@ -92,10 +88,7 @@ void PlatformShim::reset() { 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) { @@ -107,7 +100,7 @@ void PlatformShim::add_manifest(ManifestCategory category, std::filesystem::path } } -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) { @@ -147,9 +140,7 @@ void PlatformShim::add_CM_Device_ID([[maybe_unused]] std::wstring const& id, [[m // // 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 #include @@ -163,105 +154,12 @@ std::string category_path_name(ManifestCategory category) { 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 PlatformShim::set_app_package_path(std::filesystem::path const& path) {} - -void parse_and_add_env_var_override(std::vector& 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::redirect_category(std::filesystem::path const& new_path, ManifestCategory category) { - std::vector 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()) { -#ifdef VULKANSC - redirect_path(std::filesystem::path(path) / "vulkansc" / category_path_name(category), new_path); -#else - redirect_path(std::filesystem::path(path) / "vulkan" / category_path_name(category), new_path); -#endif // VULKANSC - } - } -} - -void PlatformShim::set_fake_path(ManifestCategory category, std::filesystem::path const& path) { - // use /etc as the 'redirection path' by default since its always searched -#ifdef VULKANSC - redirect_path(std::filesystem::path(SYSCONFDIR) / "vulkansc" / category_path_name(category), path); -#else - redirect_path(std::filesystem::path(SYSCONFDIR) / "vulkan" / category_path_name(category), path); -#endif // VULKANSC -} - -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; +void PlatformShim::add_system_library(std::string const& filename, std::filesystem::path const& actual_path) { + system_library_redirection_map[filename] = actual_path; } -std::filesystem::path PlatformShim::query_default_redirect_path(ManifestCategory category) { -#ifdef VULKANSC - return std::filesystem::path(SYSCONFDIR) / "vulkansc" / category_path_name(category); -#else - return std::filesystem::path(SYSCONFDIR) / "vulkan" / category_path_name(category); -#endif // VULKANSC +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 a3abba5a8..da3fd151a 100644 --- a/tests/framework/shim/unix_shim.cpp +++ b/tests/framework/shim/unix_shim.cpp @@ -28,21 +28,26 @@ #include "shim.h" #include +#include #if defined(__APPLE__) #include #endif +#include + +#include "util/folder_manager.h" + PlatformShim platform_shim; extern "C" { #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__GNU__) || defined(__QNX__) -PlatformShim* get_platform_shim(GetFoldersFunc get_folders_by_name_function) { - platform_shim = PlatformShim(get_folders_by_name_function); +PlatformShim* get_platform_shim() { + platform_shim = PlatformShim(); return &platform_shim; } #elif defined(__APPLE__) -FRAMEWORK_EXPORT PlatformShim* get_platform_shim(GetFoldersFunc get_folders_by_name_function) { - platform_shim = PlatformShim(get_folders_by_name_function); +FRAMEWORK_EXPORT PlatformShim* get_platform_shim() { + platform_shim = PlatformShim(); return &platform_shim; } #endif @@ -141,20 +146,16 @@ FRAMEWORK_EXPORT DIR* OPENDIR_FUNC_NAME(const char* path_name) { #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; } @@ -171,18 +172,19 @@ FRAMEWORK_EXPORT struct dirent* READDIR_FUNC_NAME(DIR* dir_stream) { } #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 folder_contents; + std::vector readdir_contents; std::vector dirent_filenames; while (true) { errno = 0; @@ -198,21 +200,17 @@ FRAMEWORK_EXPORT struct dirent* READDIR_FUNC_NAME(DIR* dir_stream) { (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 = platform_shim.get_folders_by_name_function(real_path.c_str()); - // 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; } } @@ -226,7 +224,7 @@ FRAMEWORK_EXPORT int CLOSEDIR_FUNC_NAME(DIR* dir_stream) { #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(), @@ -243,48 +241,62 @@ FRAMEWORK_EXPORT int ACCESS_FUNC_NAME(const char* in_pathname, int mode) { #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) { #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); + std::filesystem::path path{in_filename}; + if (!path.has_parent_path()) { + return 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(); + return real_fopen(real_path.c_str(), mode); } else { - f_ptr = real_fopen(in_filename, mode); + return real_fopen(in_filename, mode); } - - return f_ptr; } FRAMEWORK_EXPORT void* DLOPEN_FUNC_NAME(const char* in_filename, int flags) { #if !defined(__APPLE__) if (!real_dlopen) real_dlopen = (PFN_DLOPEN)dlsym(RTLD_NEXT, "dlopen"); #endif + if (platform_shim.is_during_destruction || !platform_shim.is_finished_setup) { + return real_dlopen(in_filename, flags); + } - if (platform_shim.is_dlopen_redirect_name(in_filename)) { - return real_dlopen(platform_shim.dlopen_redirection_map[in_filename].c_str(), 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); } - return real_dlopen(in_filename, flags); } FRAMEWORK_EXPORT uid_t GETEUID_FUNC_NAME(void) { diff --git a/tests/framework/shim/windows_shim.cpp b/tests/framework/shim/windows_shim.cpp index 1ca1a68e2..1c6bc0b9f 100644 --- a/tests/framework/shim/windows_shim.cpp +++ b/tests/framework/shim/windows_shim.cpp @@ -31,6 +31,10 @@ #include #endif +#include + +#include + #include #include @@ -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 @@ BOOL WINAPI DllMain([[maybe_unused]] HINSTANCE hinst, DWORD dwReason, [[maybe_un } return TRUE; } -FRAMEWORK_EXPORT PlatformShim *get_platform_shim(GetFoldersFunc get_folders_by_name_function) { - platform_shim = PlatformShim(get_folders_by_name_function); - 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 bb1760338..174e89dee 100644 --- a/tests/framework/test_environment.cpp +++ b/tests/framework/test_environment.cpp @@ -28,163 +28,11 @@ #include "test_environment.h" +#include #include +#include -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); -#ifndef VULKANSC // Sparse resources are not supported in Vulkan SC - funcs.vkGetPhysicalDeviceSparseImageFormatProperties = GPA(vkGetPhysicalDeviceSparseImageFormatProperties); - funcs.vkGetPhysicalDeviceSparseImageFormatProperties2 = GPA(vkGetPhysicalDeviceSparseImageFormatProperties2); -#endif // VULKANSC - 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); - -#ifndef VULKANSC // Usual WSI platforms are not supported in Vulkan SC -#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 -#endif // VULKANSC -#if defined(VK_USE_PLATFORM_SCREEN_QNX) - funcs.vkCreateScreenSurfaceQNX = GPA(vkCreateScreenSurfaceQNX); - funcs.vkGetPhysicalDeviceScreenPresentationSupportQNX = GPA(vkGetPhysicalDeviceScreenPresentationSupportQNX); -#endif // VK_USE_PLATFORM_SCREEN_QNX -#ifndef VULKANSC // Usual WSI platforms are not supported in Vulkan SC -#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 -#endif // VULKANSC - 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) { -#ifndef VULKANSC // VK_EXT_debug_report is not supported in Vulkan SC - vkCreateDebugReportCallbackEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT")); - vkDestroyDebugReportCallbackEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT")); -#endif // VULKANSC - 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"); -#ifndef VULKANSC // vkDestroyCommandPool is not supported in Vulkan SC - vkDestroyCommandPool = load(device, "vkDestroyCommandPool"); -#endif // VULKANSC - vkCreateSwapchainKHR = load(device, "vkCreateSwapchainKHR"); - vkGetSwapchainImagesKHR = load(device, "vkGetSwapchainImagesKHR"); -#ifndef VULKANSC // vkDestroySwapchainKHR is not supported in Vulkan SC - vkDestroySwapchainKHR = load(device, "vkDestroySwapchainKHR"); -#endif // VULKANSC -} +#include "json_writer.h" InstWrapper::InstWrapper(VulkanFunctions& functions, VkAllocationCallbacks* callbacks) noexcept : functions(&functions), callbacks(callbacks) {} @@ -354,139 +202,23 @@ bool FindPrefixPostfixStringOnLine(DebugUtilsLogger const& env_log, const char* return env_log.find_prefix_then_postfix(prefix, postfix); } -namespace fs { -FolderManager::FolderManager(std::filesystem::path root_path, std::string name) noexcept : folder(root_path / name) { - clear(); - // Don't actually create the folder yet, as we will do it on demand -} -FolderManager::~FolderManager() noexcept { clear(); } -FolderManager::FolderManager(FolderManager&& other) noexcept : actually_created(other.actually_created), folder(other.folder) { - other.folder.clear(); -} -FolderManager& FolderManager::operator=(FolderManager&& other) noexcept { - folder = other.folder; - actually_created = other.actually_created; - other.folder.clear(); - return *this; -} - -void FolderManager::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 FolderManager::write_manifest(std::filesystem::path const& name, std::string const& contents) { - check_if_first_use(); - std::filesystem::path out_path = folder / name; - 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 FolderManager::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 FolderManager::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 FolderManager::get_files() const { return added_files; } - -std::filesystem::path FolderManager::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 FolderManager::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 FolderManager::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"; - } - } -} - -} // namespace fs - -PlatformShimWrapper::PlatformShimWrapper(GetFoldersFunc get_folders_by_name_function, 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(get_folders_by_name_function); + 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(get_folders_by_name_function); + 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(); } - 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); @@ -500,7 +232,7 @@ 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_full_path() noexcept { return icd_library.get_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; } @@ -517,99 +249,134 @@ 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_full_path() noexcept { return layer_library.get_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), - test_folder(std::filesystem::path(FRAMEWORK_BUILD_DIRECTORY), - std::string(::testing::UnitTest::GetInstance()->GetInstance()->current_test_suite()->name()) + "_" + - ::testing::UnitTest::GetInstance()->current_test_info()->name()), - platform_shim( - [this](const char* folder_name) -> std::vector { - for (auto& folder : folders) { - if (folder.location() == folder_name) { - return folder.get_files(); - } - } - return {}; - }, - settings.log_filter) { - // Clean out test folder in case a previous run's files are still around - test_folder.clear(); + : settings(settings), platform_shim(file_system_manager, settings.log_filter) { + // Setup default path redirections + + 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, 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, 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}, + }; - // This order is important, it matches the enum ManifestLocation, used to index the folders vector - folders.emplace_back(test_folder.location(), std::string("null_dir")); - folders.emplace_back(test_folder.location(), std::string("icd_manifests")); - folders.emplace_back(test_folder.location(), std::string("icd_env_vars_manifests")); - folders.emplace_back(test_folder.location(), std::string("explicit_layer_manifests")); - folders.emplace_back(test_folder.location(), std::string("explicit_env_var_layer_folder")); - folders.emplace_back(test_folder.location(), std::string("explicit_add_env_var_layer_folder")); - folders.emplace_back(test_folder.location(), std::string("implicit_layer_manifests")); - folders.emplace_back(test_folder.location(), std::string("implicit_env_var_layer_manifests")); - folders.emplace_back(test_folder.location(), std::string("implicit_add_env_var_layer_manifests")); - folders.emplace_back(test_folder.location(), std::string("override_layer_manifests")); - folders.emplace_back(test_folder.location(), std::string("app_package_manifests")); - folders.emplace_back(test_folder.location(), std::string("macos_bundle")); - folders.emplace_back(test_folder.location(), std::string("unsecured_location")); - folders.emplace_back(test_folder.location(), std::string("settings_location")); +#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; - 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(); #ifdef VULKANSC - platform_shim->redirect_path(home + "/.local/share/vulkansc/icd.d", unsecured_location); - platform_shim->redirect_path(home + "/.local/share/vulkansc/implicit_layer.d", unsecured_location); - platform_shim->redirect_path(home + "/.local/share/vulkansc/explicit_layer.d", unsecured_location); -#else - 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); -#endif // VULKANSC -#endif + for (auto const& [redirect, location] : secured_redirection_map) { + file_system_manager.add_path_redirect(secure_manifest_base_location + "/vulkansc/" + redirect, location); } -#if COMMON_UNIX_PLATFORMS -#ifdef VULKANSC - if (settings.secure_loader_settings) { - platform_shim->redirect_path("/etc/vulkansc/loader_settings.d", get_folder(ManifestLocation::settings_location).location()); - } else { - platform_shim->redirect_path(get_env_var("HOME") + "/.local/share/vulkansc/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) + "/vulkansc/" + 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) + "/vulkansc/" + 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/vulkansc/" + redirect, location); + } + } } #else - 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()); + for (auto const& [redirect, location] : secured_redirection_map) { + file_system_manager.add_path_redirect(secure_manifest_base_location + "/vulkan/" + redirect, 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 // VULKANSC #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(); -#ifdef VULKANSC - platform_shim->redirect_path(bundle_location / "vulkansc/icd.d", bundle_location); - platform_shim->redirect_path(bundle_location / "vulkansc/explicit_layer.d", bundle_location); - platform_shim->redirect_path(bundle_location / "vulkansc/implicit_layer.d", bundle_location); -#else - 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 -#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() { @@ -622,23 +389,27 @@ FrameworkEnvironment::~FrameworkEnvironment() { TestICD& FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept { size_t cur_icd_index = icds.size(); - fs::FolderManager* fs_ptr = &get_folder(ManifestLocation::driver); + fs::Folder* fs_ptr = &get_folder(ManifestLocation::driver); switch (icd_details.discovery_type) { case (ManifestDiscoveryType::env_var): case (ManifestDiscoveryType::add_env_var): fs_ptr = &get_folder(ManifestLocation::driver_env_var); break; +#if defined(WIN32) case (ManifestDiscoveryType::windows_app_package): fs_ptr = &get_folder(ManifestLocation::windows_app_package); break; +#endif case (ManifestDiscoveryType::override_folder): fs_ptr = &get_folder(ManifestLocation::override_layer); break; +#if defined(__APPLE__) case (ManifestDiscoveryType::macos_bundle): fs_ptr = &get_folder(ManifestLocation::macos_bundle); break; +#endif case (ManifestDiscoveryType::unsecured_generic): - fs_ptr = &get_folder(ManifestLocation::unsecured_location); + fs_ptr = &get_folder(ManifestLocation::unsecured_driver); break; case (ManifestDiscoveryType::null_dir): case (ManifestDiscoveryType::none): @@ -657,17 +428,9 @@ TestICD& FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept { 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); -#if COMMON_UNIX_PLATFORMS +#if TESTING_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) { -#ifdef VULKANSC - platform_shim->redirect_dlopen_name(std::filesystem::path(SYSCONFDIR) / "vulkansc" / "icd.d" / "." / new_lib_name, - new_driver_location); -#else - platform_shim->redirect_dlopen_name(std::filesystem::path(SYSCONFDIR) / "vulkan" / "icd.d" / "." / new_lib_name, - new_driver_location); -#endif // VULKANSC + platform_shim->add_system_library(new_lib_name, new_driver_location); } #endif #if defined(WIN32) @@ -697,10 +460,20 @@ TestICD& FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept { icds.back().shimmed_manifest_path = icds.back().manifest_path; switch (icd_details.discovery_type) { case (ManifestDiscoveryType::generic): - platform_shim->add_manifest(ManifestCategory::icd, icds.back().manifest_path); -#if COMMON_UNIX_PLATFORMS +#if defined(WIN32) + platform_shim->add_manifest_to_registry(ManifestCategory::icd, icds.back().manifest_path); +#elif TESTING_COMMON_UNIX_PLATFORMS icds.back().shimmed_manifest_path = - platform_shim->query_default_redirect_path(ManifestCategory::icd) / new_manifest_path; + file_system_manager.get_path_redirect_by_manifest_location(ManifestLocation::driver) / new_manifest_path; +#endif + break; + case (ManifestDiscoveryType::unsecured_generic): +#if defined(WIN32) + platform_shim->add_unsecured_manifest_to_registry(ManifestCategory::icd, icds.back().manifest_path); +#elif TESTING_COMMON_UNIX_PLATFORMS + icds.back().shimmed_manifest_path = + file_system_manager.get_path_redirect_by_manifest_location(ManifestLocation::unsecured_driver) / + new_manifest_path; #endif break; case (ManifestDiscoveryType::env_var): @@ -709,7 +482,6 @@ TestICD& FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept { } 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) { @@ -717,21 +489,22 @@ TestICD& FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept { } 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::override_folder): - 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); + +#if defined(WIN32) + case (ManifestDiscoveryType::windows_app_package): + platform_shim->set_app_package_path(folder.location()); break; +#endif +#if defined(__APPLE__) + case (ManifestDiscoveryType::macos_bundle): // macos_bundle contents are always discoverable by the loader +#endif + case (ManifestDiscoveryType::override_folder): // should be found through override layer/settings file, not 'normal' + // search paths case (ManifestDiscoveryType::null_dir): case (ManifestDiscoveryType::none): break; - case (ManifestDiscoveryType::windows_app_package): - platform_shim->set_app_package_path(folder.location()); - break; } } return icds.back().get_test_icd(); @@ -757,7 +530,8 @@ void FrameworkEnvironment::add_explicit_layer(TestLayerDetails layer_details) no } void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, ManifestCategory category) { - fs::FolderManager* fs_ptr = &get_folder(ManifestLocation::explicit_layer); + fs::Folder* fs_ptr = &get_folder(ManifestLocation::explicit_layer); + EnvVarWrapper* env_var_to_use = nullptr; switch (layer_details.discovery_type) { case (ManifestDiscoveryType::generic): if (category == ManifestCategory::implicit_layer) fs_ptr = &get_folder(ManifestLocation::implicit_layer); @@ -765,53 +539,48 @@ void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, Manife 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) { + env_var_to_use = &env_var_vk_layer_paths; + } else 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); - } + env_var_to_use = &env_var_vk_implicit_layer_paths; + } + if (layer_details.is_dir) { + env_var_to_use->add_to_list(fs_ptr->location()); + } else { + env_var_to_use->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) { + env_var_to_use = &add_env_var_vk_layer_paths; + } else 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); - } + env_var_to_use = &add_env_var_vk_implicit_layer_paths; + } + if (layer_details.is_dir) { + env_var_to_use->add_to_list(fs_ptr->location()); + } else { + env_var_to_use->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; +#if defined(__APPLE__) case (ManifestDiscoveryType::macos_bundle): fs_ptr = &(get_folder(ManifestLocation::macos_bundle)); break; +#endif case (ManifestDiscoveryType::unsecured_generic): - fs_ptr = &(get_folder(ManifestLocation::unsecured_location)); + fs_ptr = &(get_folder(category == ManifestCategory::implicit_layer ? ManifestLocation::unsecured_implicit_layer + : ManifestLocation::unsecured_explicit_layer)); break; +#if defined(WIN32) case (ManifestDiscoveryType::windows_app_package): fs_ptr = &(get_folder(ManifestLocation::windows_app_package)); break; +#endif case (ManifestDiscoveryType::none): case (ManifestDiscoveryType::null_dir): fs_ptr = &(get_folder(ManifestLocation::null)); @@ -828,20 +597,9 @@ void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, Manife auto new_layer_location = folder.copy_file(layer.lib_path, new_lib_path); -#if COMMON_UNIX_PLATFORMS +#if TESTING_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) { -#ifdef VULKANSC - platform_shim->redirect_dlopen_name( - std::filesystem::path(SYSCONFDIR) / "vulkansc" / category_path_name(category) / "." / new_lib_path, - new_layer_location); -#else - platform_shim->redirect_dlopen_name( - std::filesystem::path(SYSCONFDIR) / "vulkan" / category_path_name(category) / "." / new_lib_path, - new_layer_location); -#endif // VULKANSC + platform_shim->add_system_library(new_lib_path, new_layer_location); } #endif #if defined(WIN32) @@ -871,22 +629,28 @@ void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, Manife if (layer_details.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()); +#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); + 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); + platform_shim->add_unsecured_manifest_to_registry(category, layer_manifest_loc); } if (layer_details.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 TESTING_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; + layers.at(i).shimmed_manifest_path = + ((category == ManifestCategory::implicit_layer) + ? file_system_manager.get_path_redirect_by_manifest_location(ManifestLocation::implicit_layer) + : file_system_manager.get_path_redirect_by_manifest_location(ManifestLocation::explicit_layer)) / + layer_details.json_name; } #endif } @@ -952,6 +716,42 @@ std::string get_loader_settings_file_contents(const LoaderSettings& loader_setti } 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) { @@ -961,36 +761,41 @@ std::string get_loader_settings_file_contents(const LoaderSettings& loader_setti 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(); } @@ -1015,19 +820,24 @@ std::filesystem::path FrameworkEnvironment::get_shimmed_layer_manifest_path(size 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(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(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 FrameworkEnvironment::GetInstanceExtensions(uint32_t expected_count, const char* layer_name) { uint32_t count = 0; VkResult res = vulkan_functions.vkEnumerateInstanceExtensionProperties(layer_name, &count, nullptr); diff --git a/tests/framework/test_environment.h b/tests/framework/test_environment.h index f761cf5c5..37c2e2d74 100644 --- a/tests/framework/test_environment.h +++ b/tests/framework/test_environment.h @@ -47,10 +47,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" @@ -58,14 +66,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 @@ -112,158 +113,26 @@ void handle_assert_equal(size_t count, T left[], T right[]) { } } -// 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; -#ifndef VULKANSC // Sparse resources are not supported in Vulkan SC - PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties = nullptr; - PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 vkGetPhysicalDeviceSparseImageFormatProperties2 = nullptr; -#endif // VULKANSC - 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)); - } - - FromVoidStarFunc load(VkDevice device, const char* func_name) const { - return FromVoidStarFunc(vkGetDeviceProcAddr(device, func_name)); +template +bool check_permutation(std::initializer_list expected, std::array 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; -#ifndef VULKANSC // vkDestroyCommandPool is not supported in Vulkan SC - PFN_vkDestroyCommandPool vkDestroyCommandPool = nullptr; -#endif // VULKANSC - PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR = nullptr; - PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR = nullptr; -#ifndef VULKANSC // vkDestroySwapchainKHR is not supported in Vulkan SC - PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR = nullptr; -#endif // VULKANSC - - 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; +} +template +bool check_permutation(std::initializer_list expected, std::vector 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; +} // InstWrapper & DeviceWrapper - used to make creating instances & devices easier when writing tests struct InstWrapper { @@ -470,56 +339,13 @@ VkResult CreateDebugUtilsMessenger(DebugUtilsWrapper& debug_utils); void FillDebugUtilsCreateDetails(InstanceCreateInfo& create_info, DebugUtilsLogger& logger); void FillDebugUtilsCreateDetails(InstanceCreateInfo& create_info, DebugUtilsWrapper& wrapper); -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); - - // 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 location() const { return folder; } - - std::vector 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 added_files; - - void insert_file_to_tracking(std::filesystem::path const& name); - void check_if_first_use(); -}; -} // namespace fs - struct LoaderSettingsLayerConfiguration { 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; @@ -532,6 +358,20 @@ inline bool operator>(LoaderSettingsLayerConfiguration const& a, LoaderSettingsL 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; + +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(std::string, destinations, destination) @@ -540,6 +380,9 @@ struct LoaderLogConfiguration { struct AppSpecificSettings { 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) }; @@ -552,8 +395,7 @@ struct LoaderSettings { struct FrameworkEnvironment; // forward declaration struct PlatformShimWrapper { - PlatformShimWrapper(GetFoldersFunc get_folders_by_name_function, 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; @@ -602,25 +444,6 @@ struct TestLayerHandle { 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 { @@ -649,30 +472,19 @@ struct TestLayerDetails { BUILDER_VALUE_WITH_DEFAULT(LibraryPathType, library_path_type, LibraryPathType::absolute); }; -// 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 FrameworkSettings { BUILDER_VALUE_WITH_DEFAULT(const char*, log_filter, "all"); - BUILDER_VALUE_WITH_DEFAULT(bool, enable_default_search_paths, true); - BUILDER_VALUE(LoaderSettings, loader_settings); - BUILDER_VALUE(bool, secure_loader_settings); + 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 { @@ -691,12 +503,20 @@ struct FrameworkEnvironment { 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; - // 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; + // 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); @@ -712,16 +532,18 @@ struct FrameworkEnvironment { 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::FolderManager test_folder; + fs::FileSystemManager file_system_manager; // Query the global extensions // Optional: use layer_name to query the extensions of a specific layer @@ -730,7 +552,6 @@ struct FrameworkEnvironment { std::vector GetLayerProperties(uint32_t count); PlatformShimWrapper platform_shim; - std::vector folders; std::vector icds; std::vector layers; @@ -748,6 +569,18 @@ struct FrameworkEnvironment { 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); diff --git a/tests/framework/test_util.cpp b/tests/framework/test_util.cpp deleted file mode 100644 index aa5adffd6..000000000 --- a/tests/framework/test_util.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (c) 2021-2023 The Khronos Group Inc. - * Copyright (c) 2021-2023 Valve Corporation - * Copyright (c) 2021-2023 LunarG, Inc. - * Copyright (c) 2023-2023 RasterGrid Kft. - * - * 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 - */ - -#include "test_util.h" - -#include - -#if defined(WIN32) -#include -#include -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(&lpMsgBuf), 0, nullptr); - - std::cerr << function_name << " failed with " << win_api_error_str(status) << ": " - << std::string(reinterpret_cast(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 -void print_object_of_t(JsonWriter& writer, const char* object_name, std::vector const& vec) { - if (vec.size() == 0) return; - writer.StartKeyedObject(object_name); - for (auto& element : vec) { - element.get_manifest_str(writer); - } - writer.EndObject(); -} - -template -void print_array_of_t(JsonWriter& writer, const char* object_name, std::vector 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 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 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; -} - -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) && !defined(VULKANSC) - 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(enabled_layers.size()); - instance_info.ppEnabledLayerNames = enabled_layers.data(); - instance_info.enabledExtensionCount = static_cast(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) { -#ifdef VULKANSC - if (major == 1 && minor <= 2) { - this->api_version = VK_MAKE_API_VERSION(VKSC_API_VARIANT, 1, 0, patch); - } else { - this->api_version = VK_MAKE_API_VERSION(VKSC_API_VARIANT, major, minor, patch); - } -#else - this->api_version = VK_MAKE_API_VERSION(0, major, minor, patch); -#endif // VULKANSC - 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(enabled_layers.size()); - dev.ppEnabledLayerNames = enabled_layers.data(); - dev.enabledExtensionCount = static_cast(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(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(utf16.size()), nullptr, 0, nullptr, nullptr); - if (size <= 0) { - return {}; - } - std::string utf8(size, '\0'); - if (WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast(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(utf8.size()), nullptr, 0); - if (size <= 0) { - return {}; - } - std::wstring utf16(size, L'\0'); - if (MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast(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 b274c8055..000000000 --- a/tests/framework/test_util.h +++ /dev/null @@ -1,996 +0,0 @@ -/* - * Copyright (c) 2021-2023 The Khronos Group Inc. - * Copyright (c) 2021-2023 Valve Corporation - * Copyright (c) 2021-2023 LunarG, Inc. - * Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * Copyright (c) 2023-2023 RasterGrid Kft. - * - * 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 - */ - -/* - * 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 - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -// 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 -#include -#include -#elif COMMON_UNIX_PLATFORMS -#include -#include -#include -#include -#include - -// Prevent macro collisions from -#undef major -#undef minor - -#endif - -#include -#include -#include - -#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" - -using GetFoldersFunc = std::function(const char*)>; - -// 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 - -// 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 test_platform_dl_handle; -inline test_platform_dl_handle test_platform_open_library(const wchar_t* lib_path) { - // Try loading the library the original way first. - test_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 test_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 test_platform_close_library(test_platform_dl_handle library) { FreeLibrary(library); } -inline void* test_platform_get_proc_address(test_platform_dl_handle library, const char* name) { - assert(library); - assert(name); - return reinterpret_cast(GetProcAddress(library, name)); -} -inline char* test_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* test_platform_dl_handle; -inline test_platform_dl_handle test_platform_open_library(const char* libPath) { return dlopen(libPath, RTLD_LAZY | RTLD_LOCAL); } -inline void test_platform_open_library_print_error(std::filesystem::path const& libPath) { - std::wcerr << "Unable to open library: " << libPath << " due to: " << dlerror() << "\n"; -} -inline void test_platform_close_library(test_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* test_platform_get_proc_address(test_platform_dl_handle library, const char* name) { - assert(library); - assert(name); - return dlsym(library, name); -} -inline const char* test_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(function)) {} - - template - operator T() { - return reinterpret_cast(function); - } -}; - -struct LibraryWrapper { - explicit LibraryWrapper() noexcept {} - explicit LibraryWrapper(std::filesystem::path const& lib_path) noexcept : lib_path(lib_path) { - lib_handle = test_platform_open_library(lib_path.native().c_str()); - if (lib_handle == nullptr) { - test_platform_open_library_print_error(lib_path); - assert(lib_handle != nullptr && "Must be able to open library"); - } - } - ~LibraryWrapper() noexcept { - if (lib_handle != nullptr) { - test_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) { - test_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 = test_platform_get_proc_address(lib_handle, symbol_name); - if (symbol == nullptr) { - fprintf(stderr, "Unable to open symbol %s: %s\n", symbol_name, test_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; } - - test_platform_dl_handle lib_handle = nullptr; - std::filesystem::path lib_path; -}; - -template -PFN_vkVoidFunction to_vkVoidFunction(T func) { - return reinterpret_cast(func); -} -template -struct FRAMEWORK_EXPORT DispatchableHandle { - DispatchableHandle() { - auto ptr_handle = new VK_LOADER_DATA; - set_loader_magic_value(ptr_handle); - handle = reinterpret_cast(ptr_handle); - } - ~DispatchableHandle() { - if (handle) { - delete reinterpret_cast(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(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"; -#ifndef VULKANSC - 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"; -#else - case (VK_ERROR_NO_PIPELINE_MATCH): - return os << "VK_ERROR_NO_PIPELINE_MATCH"; - case (VK_ERROR_INVALID_PIPELINE_CACHE_DATA): - return os << "VK_ERROR_INVALID_PIPELINE_CACHE_DATA"; - case (VK_ERROR_VALIDATION_FAILED): - return os << "VK_ERROR_VALIDATION_FAILED"; -#endif // VULKANSC - 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"; -#ifndef VULKANSC - 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"; -#endif // VULKANSC - case (VK_RESULT_MAX_ENUM): - return os << "VK_RESULT_MAX_ENUM"; -#ifndef VULKANSC - 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"; -#else - default: - break; -#endif // VULKANSC - } - return os << static_cast(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 -// 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 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 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 name; \ - auto add_##singular_name(type&& singular_name)->decltype(*this) { \ - this->name.push_back(std::move(singular_name)); \ - return *this; \ - } - -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(uint32_t, api_version) - 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 { writer.AddKeyedString(vk_func, override_name); } - }; - struct Extension { - Extension() noexcept {} - Extension(std::string name, uint32_t spec_version = 0, std::vector entrypoints = {}) noexcept - : name(name), spec_version(spec_version), entrypoints(entrypoints) {} - std::string name; - uint32_t spec_version = 0; - std::vector 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; -}; - -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 { - 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(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) -#ifdef VULKANSC - uint32_t api_version = VKSC_API_VERSION_1_0; - InstanceCreateInfo& set_api_version(uint32_t const& api_version) { - if (VK_API_VERSION_MAJOR(api_version) == 1 && VK_API_VERSION_MINOR(api_version) <= 2) { - this->api_version = VK_MAKE_API_VERSION(VKSC_API_VARIANT, 1, 0, VK_API_VERSION_PATCH(api_version)); - } else { - this->api_version = api_version | VK_MAKE_API_VERSION(VKSC_API_VARIANT, 0, 0, 0); - } - return *this; - } -#else - BUILDER_VALUE_WITH_DEFAULT(uint32_t, api_version, VK_API_VERSION_1_0) -#endif // VULKANSC - 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 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 >> -bool operator==(const std::vector& a, const std::vector& 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 -bool check_permutation(std::initializer_list expected, std::array 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 -bool check_permutation(std::initializer_list expected, std::vector 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 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 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 -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(buffer.size())); - if (ret <= 0) return NULL; - buffer[ret] = '\0'; - buffer.resize(ret); - return buffer; -} -#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) -#include -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 -#include - -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(&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 000000000..ea90f6786 --- /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 +if(VULKANSC) + target_include_directories(testing_framework_util + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/.." "${CMAKE_CURRENT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/loader/generated-vksc") +else() + target_include_directories(testing_framework_util + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/.." "${CMAKE_CURRENT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}") +endif() + +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) + 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 000000000..c727c81b9 --- /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 + +// 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 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 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 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 000000000..80062640c --- /dev/null +++ b/tests/framework/util/dispatch_table.cpp @@ -0,0 +1,180 @@ +// 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); +#ifndef VULKANSC + funcs.vkGetPhysicalDeviceSparseImageFormatProperties = GPA(vkGetPhysicalDeviceSparseImageFormatProperties); + funcs.vkGetPhysicalDeviceSparseImageFormatProperties2 = GPA(vkGetPhysicalDeviceSparseImageFormatProperties2); +#endif + 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); + +#ifndef VULKANSC +#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 +#endif + 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) { +#ifndef VULKANSC // VK_EXT_debug_report is not supported in Vulkan SC + vkCreateDebugReportCallbackEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT")); + vkDestroyDebugReportCallbackEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT")); +#endif // VULKANSC + 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 000000000..f5454bbb2 --- /dev/null +++ b/tests/framework/util/dispatch_table.h @@ -0,0 +1,182 @@ +// 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 + +#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; +#ifndef VULKANSC + PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties = nullptr; + PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 vkGetPhysicalDeviceSparseImageFormatProperties2 = nullptr; +#endif + 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; + +#ifndef VULKANSC +#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 +#endif + 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)); + } + + FromVoidStarFunc load(VkDevice device, const char* func_name) const { + return FromVoidStarFunc(vkGetDeviceProcAddr(device, 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 000000000..98085bb7d --- /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 + +#include "test_defines.h" + +template +struct FRAMEWORK_EXPORT DispatchableHandle { + DispatchableHandle() { + auto ptr_handle = new VK_LOADER_DATA; + set_loader_magic_value(ptr_handle); + handle = reinterpret_cast(ptr_handle); + } + ~DispatchableHandle() { + if (handle) { + delete reinterpret_cast(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(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 000000000..e868d1607 --- /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 +#include +#include + +#include + +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 + +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(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 000000000..35b72adbe --- /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 + +#include "test_defines.h" + +#include "functions.h" + +#if defined(_WIN32) +#include +#include +#include +#elif TESTING_COMMON_UNIX_PLATFORMS +#include +#include +#include +#include +#include +#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 000000000..f9df38994 --- /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 + +#include + +#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 +#include +#include + +// 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 split_env_var_as_list(std::string const& env_var_contents) { + std::vector 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 000000000..2a0ecca7a --- /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 +#include + +#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 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 000000000..4a98599d4 --- /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 000000000..5c38f5031 --- /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 + +#include +#include + +#include + +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 >> +bool operator==(const std::vector& a, const std::vector& 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 000000000..53bbba661 --- /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 +#include + +#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 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 000000000..9d405cbb3 --- /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 +#include +#include +#include +#include + +#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 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 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 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 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 000000000..5debba9fe --- /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 + +#include + +class FromVoidStarFunc { + void* function; + + public: + FromVoidStarFunc(void* function) : function(function) {} + FromVoidStarFunc(PFN_vkVoidFunction function) : function(reinterpret_cast(function)) {} + + template + operator T() { + return reinterpret_cast(function); + } +}; + +template +PFN_vkVoidFunction to_vkVoidFunction(T func) { + return reinterpret_cast(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 000000000..9edb5d38d --- /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 + +// 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 +#include + +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(buffer.size())); + if (ret <= 0) return NULL; + buffer[ret] = '\0'; + buffer.resize(ret); + return buffer; +} +#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) +#include +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 +#include + +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 + +#include + +#include "wide_char_handling.h" + +std::string test_platform_executable_path() { + std::string buffer; + buffer.resize(1024); + DWORD ret = GetModuleFileName(NULL, static_cast(&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 000000000..bb296e54f --- /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 + +// 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 000000000..1a955c09a --- /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 + */ + +#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 000000000..a5c31545a --- /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 + */ + +#pragma once + +#include +#include +#include +#include + +#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 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 000000000..6666a5769 --- /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 +void print_object_of_t(JsonWriter& writer, const char* object_name, std::vector const& vec) { + if (vec.size() == 0) return; + writer.StartKeyedObject(object_name); + for (auto& element : vec) { + element.get_manifest_str(writer); + } + writer.EndObject(); +} + +template +void print_array_of_t(JsonWriter& writer, const char* object_name, std::vector 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 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 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 000000000..bc559dda7 --- /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 +#include +#include + +#include + +#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(uint32_t, api_version) + 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 entrypoints = {}) noexcept + : name(name), spec_version(spec_version), entrypoints(entrypoints) {} + std::string name; + uint32_t spec_version = 0; + std::vector 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 000000000..b8fd3d9af --- /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) && !defined(VULKANSC) + 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 000000000..66b7b507e --- /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 000000000..63d6a32e9 --- /dev/null +++ b/tests/framework/util/test_defines.h @@ -0,0 +1,97 @@ +/* + * 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 + +#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 000000000..88a311ef4 --- /dev/null +++ b/tests/framework/util/vulkan_object_wrappers.cpp @@ -0,0 +1,120 @@ +/* + * 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(enabled_layers.size()); + instance_info.ppEnabledLayerNames = enabled_layers.data(); + instance_info.enabledExtensionCount = static_cast(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) { +#ifdef VULKANSC + if (major == 1 && minor <= 2) { + this->api_version = VK_MAKE_API_VERSION(VKSC_API_VARIANT, 1, 0, patch); + } else { + this->api_version = VK_MAKE_API_VERSION(VKSC_API_VARIANT, major, minor, patch); + } +#else + this->api_version = VK_MAKE_API_VERSION(0, major, minor, patch); +#endif // VULKANSC + 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(enabled_layers.size()); + dev.ppEnabledLayerNames = enabled_layers.data(); + dev.enabledExtensionCount = static_cast(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(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 000000000..44958242e --- /dev/null +++ b/tests/framework/util/vulkan_object_wrappers.h @@ -0,0 +1,113 @@ +/* + * 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 +#include + +#include + +#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) +#ifdef VULKANSC + uint32_t api_version = VKSC_API_VERSION_1_0; + InstanceCreateInfo& set_api_version(uint32_t const& api_version) { + if (VK_API_VERSION_MAJOR(api_version) == 1 && VK_API_VERSION_MINOR(api_version) <= 2) { + this->api_version = VK_MAKE_API_VERSION(VKSC_API_VARIANT, 1, 0, VK_API_VERSION_PATCH(api_version)); + } else { + this->api_version = api_version | VK_MAKE_API_VERSION(VKSC_API_VARIANT, 0, 0, 0); + } + return *this; + } +#else + BUILDER_VALUE_WITH_DEFAULT(uint32_t, api_version, VK_API_VERSION_1_0) +#endif // VULKANSC + 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 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 000000000..ac4fb0bff --- /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(utf16.size()), nullptr, 0, nullptr, nullptr); + if (size <= 0) { + return {}; + } + std::string utf8(size, '\0'); + if (WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast(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(utf8.size()), nullptr, 0); + if (size <= 0) { + return {}; + } + std::wstring utf16(size, L'\0'); + if (MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast(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 000000000..805afe14c --- /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 + +// 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/live_verification/dynamic_loader_behavior/dynamic_library.h b/tests/live_verification/dynamic_loader_behavior/dynamic_library.h index 1d88d306e..b4bff319b 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 */ -#include "test_util.h" +#include +#include + +#include "util/test_defines.h" +#include "util/functions.h" +#include "util/dynamic_library_wrapper.h" extern "C" { @@ -38,7 +43,7 @@ using InitFunction = void (*)(); 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 2d2d6b35c..943917ec3 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 @@ int main() { 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 a25300c7e..924de58a4 100644 --- a/tests/loader_alloc_callback_tests.cpp +++ b/tests/loader_alloc_callback_tests.cpp @@ -442,7 +442,9 @@ TEST(Allocation, CreateInstanceIntentionalAllocFailInvalidManifests) { 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"; @@ -714,8 +716,7 @@ TEST(Allocation, CreateInstanceDeviceIntentionalAllocFail) { .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"}); } @@ -884,7 +885,7 @@ TEST(Allocation, EnumeratePhysicalDevicesIntentionalAllocFail) { 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}}; @@ -906,7 +907,7 @@ TEST(Allocation, EnumeratePhysicalDevicesIntentionalAllocFail) { 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; } @@ -980,7 +981,7 @@ TEST(Allocation, CreateInstanceDeviceWithDXGIDriverIntentionalAllocFail) { 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}); } diff --git a/tests/loader_debug_ext_tests.cpp b/tests/loader_debug_ext_tests.cpp index 4e8245802..95b3ee0e1 100644 --- a/tests/loader_debug_ext_tests.cpp +++ b/tests/loader_debug_ext_tests.cpp @@ -54,8 +54,8 @@ class DebugReportTest : public ::testing::Test { env = std::unique_ptr(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->get_test_icd(icd).add_physical_device({}); + env->get_test_icd(icd).add_physical_device({}); } // Initialize the expected output allow_any_message = false; @@ -389,8 +389,8 @@ class DebugUtilTest : public ::testing::Test { env = std::unique_ptr(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->get_test_icd(icd).add_physical_device({}); + env->get_test_icd(icd).add_physical_device({}); } // Initialize the expected output allow_any_message = false; @@ -1060,9 +1060,8 @@ void CheckDeviceFunctions(FrameworkEnvironment& env, bool use_GIPA, bool enable_ 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(TestICDDetails(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 @@ -1078,8 +1077,9 @@ TEST(GetProcAddr, DebugFuncsWithTerminator) { driver.add_instance_extensions({"VK_EXT_debug_utils"}); #else 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"}); #endif // VULKANSC + // Use getDeviceProcAddr & vary enabling the debug extensions ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false, true)); ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, true)); @@ -1091,9 +1091,10 @@ TEST(GetProcAddr, DebugFuncsWithTerminator) { 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(TestICDDetails(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 @@ -1129,9 +1130,10 @@ TEST(GetProcAddr, DebugFuncsWithTrampoline) { 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(TestICDDetails(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 diff --git a/tests/loader_envvar_tests.cpp b/tests/loader_envvar_tests.cpp index f56558c4e..ee4ef52e9 100644 --- a/tests/loader_envvar_tests.cpp +++ b/tests/loader_envvar_tests.cpp @@ -30,6 +30,8 @@ #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 @@ -122,18 +124,25 @@ TEST(EnvVarICDOverrideSetup, TestOnlyDriverEnvVar) { 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(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).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(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).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 @@ -159,27 +168,30 @@ TEST(EnvVarICDOverrideSetup, TestOnlyDriverEnvVarInFolder) { .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(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_discovery_type(ManifestDiscoveryType::env_var).set_is_dir(false)); + env.get_test_icd(0).add_physical_device("pd0"); - env.debug_log.clear(); - - env.platform_shim->set_elevated_privilege(true); + for (uint32_t add = 0; add < 2; ++add) { + env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).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); } #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__GNU__) || defined(__QNX__) @@ -205,14 +217,13 @@ TEST(EnvVarICDOverrideSetup, XDG) { // 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{}; + 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(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0"); InstWrapper inst{env.vulkan_functions}; @@ -241,9 +252,7 @@ TEST(EnvVarICDOverrideSetup, XDGContainsJsonFile) { // 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{}; + FrameworkEnvironment env{FrameworkSettings{}.set_xdg_config_dirs_env_var("bad_file.json")}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0"); InstWrapper inst{env.vulkan_functions}; @@ -256,26 +265,29 @@ TEST(EnvVarICDOverrideSetup, XDGContainsJsonFile) { 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.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 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(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).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 @@ -304,7 +316,7 @@ TEST(EnvVarICDOverrideSetup, TestBothDriverEnvVars) { 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.file_system_manager.add_path_redirect("/tmp/carol", ManifestLocation::explicit_layer_env_var); const char* layer_name = "TestLayer"; env.add_explicit_layer( @@ -321,35 +333,51 @@ TEST(EnvVarICDOverrideSetup, TestOnlyLayerEnvVar) { 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(TestICDDetails(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( + 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)); - 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.file_system_manager.add_path_redirect("/tmp/carol", ManifestLocation::explicit_layer_add_env_var); const char* layer_name = "TestLayer"; env.add_explicit_layer( @@ -367,35 +395,52 @@ TEST(EnvVarICDOverrideSetup, TestOnlyAddLayerEnvVar) { 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(TestICDDetails(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( + 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)); - 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}; - EXPECT_FALSE(env.debug_log.find("/tmp/carol")); + 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); - env.platform_shim->set_elevated_privilege(false); + EXPECT_FALSE(env.debug_log.find("/tmp/carol")); } // 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.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{} @@ -413,39 +458,57 @@ TEST(EnvVarICDOverrideSetup, TestOnlyImplicitLayerEnvVar) { 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(TestICDDetails(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.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_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 inst2{env.vulkan_functions}; - FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log); - inst2.CheckCreate(); + InstWrapper inst{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); + inst.CheckCreate(); - auto active_layers2 = inst2.GetActiveLayers(inst2.GetPhysDev(), 0); - ASSERT_TRUE(active_layers2.empty()); + 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.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{} @@ -462,7 +525,7 @@ TEST(EnvVarICDOverrideSetup, TestOnlyAddImplicitLayerEnvVar) { 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); @@ -475,21 +538,39 @@ TEST(EnvVarICDOverrideSetup, TestOnlyAddImplicitLayerEnvVar) { 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(TestICDDetails(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(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)); - 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(); - EXPECT_FALSE(env.debug_log.find("/tmp/carol")); + auto active_layers = inst.GetActiveLayers(inst.GetPhysDev(), 0); + ASSERT_TRUE(active_layers.empty()); - env.platform_shim->set_elevated_privilege(false); + EXPECT_FALSE(env.debug_log.find("/tmp/carol")); } #endif diff --git a/tests/loader_fuzz_tests.cpp b/tests/loader_fuzz_tests.cpp index 8ac252cd2..7e3ba0593 100644 --- a/tests/loader_fuzz_tests.cpp +++ b/tests/loader_fuzz_tests.cpp @@ -40,7 +40,7 @@ void execute_instance_enumerate_fuzzer(std::filesystem::path const& filename) { 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); @@ -135,7 +135,9 @@ TEST(BadJsonInput, ClusterFuzzTestCase_6583684169269248) { // 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 @@ -212,6 +214,10 @@ TEST(BadJsonInput, ClusterFuzzTestCase_6465902356791296) { // 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) @@ -281,3 +287,6 @@ TEST(BadJsonInput, ClusterFuzzTestCase_5123849246867456) { // 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 6a74721dd..6440bb099 100644 --- a/tests/loader_get_proc_addr_tests.cpp +++ b/tests/loader_get_proc_addr_tests.cpp @@ -242,8 +242,9 @@ TEST(GetProcAddr, Verify10FunctionsLoadWithMultipleDrivers) { // 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(TestICDDetails(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"); @@ -294,7 +295,7 @@ TEST(GetDeviceProcAddr, SwapchainFuncsWithTerminator) { ASSERT_FALSE(dev_funcs.vkDestroySwapchainKHR); #endif // VULKANSC } - 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"}); @@ -378,15 +379,15 @@ TEST(GetProcAddr, PreserveLayerGettingVkCreateDeviceWithNullInstance) { TEST(GetDeviceProcAddr, AppQueries11FunctionsWhileOnlyEnabling10) { FrameworkEnvironment env{}; - auto& driver = + auto& test_physical_device = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, 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 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}; @@ -432,15 +433,15 @@ TEST(GetDeviceProcAddr, AppQueries11FunctionsWhileOnlyEnabling10) { TEST(GetDeviceProcAddr, AppQueries12FunctionsWhileOnlyEnabling11) { FrameworkEnvironment env{}; - auto& driver = + auto& test_physical_device = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, 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 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}; @@ -489,16 +490,16 @@ TEST(GetDeviceProcAddr, AppQueries12FunctionsWhileOnlyEnabling11) { TEST(GetDeviceProcAddr, AppQueries13FunctionsWhileOnlyEnabling12) { FrameworkEnvironment env{}; - auto& driver = + auto& test_physical_device = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, 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 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_layer_tests.cpp b/tests/loader_layer_tests.cpp index 687790d5f..087031e0f 100644 --- a/tests/loader_layer_tests.cpp +++ b/tests/loader_layer_tests.cpp @@ -29,6 +29,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}; @@ -970,7 +973,8 @@ TEST(ImplicitLayers, DuplicateLayers) { .set_description("actually_layer_1") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("if_you_can")), - "regular_layer_1.json")); + "regular_layer_1.json") + .set_discovery_type(ManifestDiscoveryType::add_env_var)); auto& layer1 = env.get_test_layer(0); layer1.set_description("actually_layer_1"); layer1.set_make_spurious_log_in_create_instance("actually_layer_1"); @@ -981,22 +985,10 @@ TEST(ImplicitLayers, DuplicateLayers) { .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)); + .set_discovery_type(ManifestDiscoveryType::generic)); 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 -#ifdef VULKANSC - env.platform_shim->redirect_path(std::filesystem::path(USER_LOCAL_SHARE_DIR "/vulkansc/implicit_layer.d"), - env.get_folder(ManifestLocation::override_layer).location()); -#else - env.platform_shim->redirect_path(std::filesystem::path(USER_LOCAL_SHARE_DIR "/vulkan/implicit_layer.d"), - env.get_folder(ManifestLocation::override_layer).location()); -#endif // VULKANSC -#endif auto layer_props = env.GetLayerProperties(2); ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[0].layerName)); @@ -1186,6 +1178,55 @@ TEST(ImplicitLayers, DuplicateLayersInVK_ADD_IMPLICIT_LAYER_PATH) { ASSERT_FALSE(env.debug_log.find("actually_layer_2")); } +TEST(ImplicitLayers, OrderedByVK_INSTANCE_LAYERS) { + FrameworkEnvironment env; + env.add_icd(TestICDDetails(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")), + "implicit_layer.json"); + 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)), + "explicit_layer.json"); + // 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; @@ -1955,7 +1996,7 @@ TEST(OverrideMetaLayer, AppKeysDoesNotContainCurrentApplication) { } } -TEST(OverrideMetaLayer, RunningWithElevatedPrivilegesFromSecureLocation) { +TEST(OverrideMetaLayer, RunningWithRegularPrivilegesFromSecureLocation) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); @@ -1979,38 +2020,58 @@ TEST(OverrideMetaLayer, RunningWithElevatedPrivilegesFromSecureLocation) { .add_override_path(override_layer_folder.location())), "meta_test_layer.json"}); - { // 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(); - } + 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.platform_shim->set_elevated_privilege(true); +TEST(OverrideMetaLayer, RunningWithElevatedPrivilegesFromSecureLocation) { + FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)}; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); - { // try with elevated privileges - auto layer_props = env.GetLayerProperties(2); - EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props)); + 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_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)); - } + 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()); + 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"}); + + // 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, RunningWithElevatedPrivilegesFromUnsecureLocation) { +TEST(OverrideMetaLayer, RunningWithRegularPrivilegesFromUnsecureLocation) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); @@ -2034,32 +2095,51 @@ TEST(OverrideMetaLayer, RunningWithElevatedPrivilegesFromUnsecureLocation) { "meta_test_layer.json"} .set_discovery_type(ManifestDiscoveryType::unsecured_generic)); - { // 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(TestICDDetails(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(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"} + .set_discovery_type(ManifestDiscoveryType::unsecured_generic)); + + 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 @@ -2868,6 +2948,16 @@ TEST(ExplicitLayers, CorrectOrderOfApplicationEnabledLayers) { } } +// Helpers +bool contains(std::vector 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 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({}); @@ -4856,6 +4946,7 @@ TEST(LayerPhysDeviceMod, AddPhysicalDevices) { VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); + std::array added_phys_devs; for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; @@ -4865,12 +4956,11 @@ TEST(LayerPhysDeviceMod, AddPhysicalDevices) { #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; @@ -4933,6 +5023,7 @@ TEST(LayerPhysDeviceMod, RemovePhysicalDevices) { VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); + std::array added_phys_devs; for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; @@ -4942,12 +5033,11 @@ TEST(LayerPhysDeviceMod, RemovePhysicalDevices) { #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; @@ -4983,6 +5073,7 @@ TEST(LayerPhysDeviceMod, ReorderPhysicalDevices) { VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); + std::array added_phys_devs; for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; @@ -4992,12 +5083,11 @@ TEST(LayerPhysDeviceMod, ReorderPhysicalDevices) { #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; @@ -5033,6 +5123,7 @@ TEST(LayerPhysDeviceMod, AddRemoveAndReorderPhysicalDevices) { VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); + std::array added_phys_devs; for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; @@ -5042,12 +5133,11 @@ TEST(LayerPhysDeviceMod, AddRemoveAndReorderPhysicalDevices) { #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; @@ -5109,6 +5199,7 @@ TEST(LayerPhysDeviceMod, AddPhysicalDeviceGroups) { VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); + std::array added_phys_devs; for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; @@ -5118,12 +5209,11 @@ TEST(LayerPhysDeviceMod, AddPhysicalDeviceGroups) { #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; @@ -5196,6 +5286,7 @@ TEST(LayerPhysDeviceMod, RemovePhysicalDeviceGroups) { VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); + std::array added_phys_devs; for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; @@ -5205,12 +5296,11 @@ TEST(LayerPhysDeviceMod, RemovePhysicalDeviceGroups) { #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; @@ -5248,6 +5338,7 @@ TEST(LayerPhysDeviceMod, ReorderPhysicalDeviceGroups) { VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); + std::array added_phys_devs; for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; @@ -5257,12 +5348,11 @@ TEST(LayerPhysDeviceMod, ReorderPhysicalDeviceGroups) { #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; @@ -5300,6 +5390,7 @@ TEST(LayerPhysDeviceMod, AddRemoveAndReorderPhysicalDeviceGroups) { VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); + std::array added_phys_devs; for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; @@ -5309,12 +5400,11 @@ TEST(LayerPhysDeviceMod, AddRemoveAndReorderPhysicalDeviceGroups) { #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; @@ -5479,34 +5569,31 @@ TEST(TestLayers, AllowFilterWithImplicitLayer) { 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(); @@ -5516,7 +5603,7 @@ TEST(TestLayers, AllowFilterWithImplicitLayer) { 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"}; { @@ -5540,7 +5627,6 @@ TEST(TestLayers, AllowFilterWithImplicitLayer) { InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); - // layer's disable_environment takes priority ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { diff --git a/tests/loader_phys_dev_inst_ext_tests.cpp b/tests/loader_phys_dev_inst_ext_tests.cpp index ecf0993d1..59b20f5eb 100644 --- a/tests/loader_phys_dev_inst_ext_tests.cpp +++ b/tests/loader_phys_dev_inst_ext_tests.cpp @@ -61,7 +61,7 @@ void FillInRandomDeviceProps(VkPhysicalDeviceProperties& props, uint32_t api_ver 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -74,7 +74,7 @@ TEST(LoaderInstPhysDevExts, PhysDevProps2KHRNoSupport) { 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.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); @@ -88,9 +88,9 @@ TEST(LoaderInstPhysDevExts, PhysDevProps2KHRNoICDSupport) { TEST(LoaderInstPhysDevExts, PhysDevProps2KHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -126,9 +126,9 @@ TEST(LoaderInstPhysDevExts, PhysDevProps2Simple) { env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, 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); @@ -228,9 +228,9 @@ TEST(LoaderInstPhysDevExts, PhysDevProps2KHRInstanceSupports11) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_0)); 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); @@ -313,8 +313,7 @@ TEST(LoaderInstPhysDevExts, PhysDevProps2Mixed) { 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) { @@ -416,7 +415,7 @@ void FillInRandomFeatures(VkPhysicalDeviceFeatures& feats) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -429,7 +428,7 @@ TEST(LoaderInstPhysDevExts, PhysDevFeats2KHRNoSupport) { 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.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); @@ -444,8 +443,8 @@ TEST(LoaderInstPhysDevExts, PhysDevFeats2KHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -474,10 +473,10 @@ TEST(LoaderInstPhysDevExts, PhysDevFeats2Simple) { env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, 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); @@ -557,9 +556,9 @@ TEST(LoaderInstPhysDevExts, PhysDevFeats2KHRInstanceSupports11) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_0)); 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); @@ -629,8 +628,7 @@ TEST(LoaderInstPhysDevExts, PhysDevFeatsMixed) { 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) { @@ -679,7 +677,7 @@ void FillInRandomFormatProperties(std::vector& props) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -693,7 +691,7 @@ TEST(LoaderInstPhysDevExts, PhysDevFormatProps2KHRNoSupport) { 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.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); @@ -709,8 +707,8 @@ TEST(LoaderInstPhysDevExts, PhysDevFormatProps2KHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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( @@ -746,10 +744,10 @@ TEST(LoaderInstPhysDevExts, PhysDevFormatProps2Simple) { env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, 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); @@ -835,9 +833,9 @@ TEST(LoaderInstPhysDevExts, PhysDevFormatProps2KHRInstanceSupports11) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -913,8 +911,7 @@ TEST(LoaderInstPhysDevExts, PhysDevFormatPropsMixed) { 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) { @@ -967,7 +964,7 @@ void FillInRandomImageFormatData(VkImageFormatProperties& props) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -981,7 +978,7 @@ TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2KHRNoSupport) { 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.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); @@ -997,8 +994,8 @@ TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2KHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -1047,9 +1044,9 @@ TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2Simple) { env.add_icd(TestICDDetails(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); @@ -1190,9 +1187,9 @@ TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2KHRInstanceSupports11) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -1290,8 +1287,7 @@ TEST(LoaderInstPhysDevExts, PhysDevImageFormatPropsMixed) { 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) { @@ -1350,7 +1346,7 @@ TEST(LoaderInstPhysDevExts, PhysDevImageFormatPropsMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -1364,7 +1360,7 @@ TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2KHRNoSupport) { 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.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); @@ -1394,8 +1390,8 @@ TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2KHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -1426,9 +1422,9 @@ TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2Simple) { env.add_icd(TestICDDetails(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); @@ -1509,9 +1505,9 @@ TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2KHRInstanceSupports11) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -1581,8 +1577,7 @@ TEST(LoaderInstPhysDevExts, PhysDevMemoryPropsMixed) { 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) { @@ -1622,7 +1617,7 @@ TEST(LoaderInstPhysDevExts, PhysDevMemoryPropsMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -1636,7 +1631,7 @@ TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2KHRNoSupport) { 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.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); @@ -1667,8 +1662,8 @@ TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2KHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -1708,9 +1703,9 @@ TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2Simple) { env.add_icd(TestICDDetails(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); @@ -1821,9 +1816,9 @@ TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2KHRInstanceSupports11) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -1908,8 +1903,7 @@ TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyPropsMixed) { 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) { @@ -1957,7 +1951,7 @@ TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyPropsMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -1971,7 +1965,7 @@ TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2KHRNoSupport) { 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.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); @@ -1998,8 +1992,8 @@ TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2KHRInstanceAndICDSuppo FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -2053,9 +2047,9 @@ TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2Simple) { env.add_icd(TestICDDetails(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); @@ -2208,9 +2202,9 @@ TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2KHRInstanceSupports11) FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -2310,8 +2304,7 @@ TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatPropsMixed) { 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) { @@ -2379,7 +2372,7 @@ TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatPropsMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -2393,7 +2386,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtBufPropsKHRNoSupport) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.create_info.add_extension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); @@ -2416,8 +2409,8 @@ TEST(LoaderInstPhysDevExts, PhysDevExtBufProps2KHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -2435,7 +2428,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtBufProps2KHRInstanceAndICDSupport) { 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 @@ -2446,9 +2439,9 @@ TEST(LoaderInstPhysDevExts, PhysDevExtBufProps2Simple) { env.add_icd(TestICDDetails(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); @@ -2466,7 +2459,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtBufProps2Simple) { 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); @@ -2516,7 +2509,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtBufProps2Simple) { 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")); } } @@ -2556,8 +2549,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtBufPropsMixed) { 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) { @@ -2591,8 +2583,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtBufPropsMixed) { 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 && @@ -2628,7 +2619,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtBufPropsMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -2642,7 +2633,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtSemPropsKHRNoSupport) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.create_info.add_extension(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME); @@ -2667,8 +2658,8 @@ TEST(LoaderInstPhysDevExts, PhysDevExtSemProps2KHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -2686,7 +2677,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtSemProps2KHRInstanceAndICDSupport) { 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 @@ -2697,9 +2688,9 @@ TEST(LoaderInstPhysDevExts, PhysDevExtSemProps2Simple) { env.add_icd(TestICDDetails(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); @@ -2717,7 +2708,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtSemProps2Simple) { 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); @@ -2765,7 +2756,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtSemProps2Simple) { 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")); } } @@ -2805,8 +2796,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtSemPropsMixed) { 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) { @@ -2840,8 +2830,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtSemPropsMixed) { 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 && @@ -2876,7 +2865,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtSemPropsMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -2890,7 +2879,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtFencePropsKHRNoSupport) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.create_info.add_extension(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME); @@ -2915,8 +2904,8 @@ TEST(LoaderInstPhysDevExts, PhysDevExtFenceProps2KHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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); @@ -2934,7 +2923,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtFenceProps2KHRInstanceAndICDSupport) { 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 @@ -2945,9 +2934,9 @@ TEST(LoaderInstPhysDevExts, PhysDevExtFenceProps2Simple) { env.add_icd(TestICDDetails(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); @@ -2965,7 +2954,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtFenceProps2Simple) { 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); @@ -3014,7 +3003,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtFenceProps2Simple) { 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")); } } @@ -3053,8 +3042,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtFencePropsMixed) { 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) { @@ -3088,8 +3076,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtFencePropsMixed) { 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 && @@ -3125,7 +3112,7 @@ TEST(LoaderInstPhysDevExts, PhysDevExtFencePropsMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -3139,7 +3126,7 @@ TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRNoSupport) { 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.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); @@ -3176,10 +3163,10 @@ TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRInstanceAndICDSupport) { 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( @@ -3259,8 +3246,7 @@ TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRMixed) { 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}); @@ -3318,7 +3304,7 @@ TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -3332,7 +3318,7 @@ TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRNoSupport) { 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.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); @@ -3361,10 +3347,10 @@ TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRInstanceAndICDSupport) { 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( @@ -3394,10 +3380,10 @@ TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRInstanceAndICDSupport) { std::vector 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 formats2{}; @@ -3452,8 +3438,7 @@ TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRMixed) { 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}); @@ -3525,7 +3510,7 @@ TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -3539,7 +3524,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRNoSupport) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); @@ -3576,8 +3561,8 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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}); @@ -3595,12 +3580,12 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRInstanceAndICDSupport) { std::vector 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 @@ -3639,8 +3624,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRMixed) { 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) { @@ -3674,8 +3658,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRMixed) { 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 && @@ -3713,7 +3696,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -3727,7 +3710,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRNoSupport) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); @@ -3752,8 +3735,8 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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}); @@ -3771,12 +3754,12 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRInstanceAndICDSupport) { std::vector 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 @@ -3815,8 +3798,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRMixed) { 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) { @@ -3850,8 +3832,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRMixed) { 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 && @@ -3889,7 +3870,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -3903,7 +3884,7 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRNoSupport) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); @@ -3927,8 +3908,8 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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}); @@ -3946,12 +3927,12 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRInstanceAndICDSupport) { std::vector 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 @@ -3990,8 +3971,7 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRMixed) { 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) { @@ -4025,8 +4005,7 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRMixed) { 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 && @@ -4064,7 +4043,7 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -4077,7 +4056,7 @@ TEST(LoaderInstPhysDevExts, GetDispModePropsKHRNoSupport) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); @@ -4103,8 +4082,8 @@ TEST(LoaderInstPhysDevExts, GetDispModePropsKHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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}); @@ -4121,12 +4100,12 @@ TEST(LoaderInstPhysDevExts, GetDispModePropsKHRInstanceAndICDSupport) { std::vector 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 @@ -4165,8 +4144,7 @@ TEST(LoaderInstPhysDevExts, GetDispModePropsKHRMixed) { 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) { @@ -4199,8 +4177,7 @@ TEST(LoaderInstPhysDevExts, GetDispModePropsKHRMixed) { 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 && @@ -4239,7 +4216,7 @@ TEST(LoaderInstPhysDevExts, GetDispModePropsKHRMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -4252,7 +4229,7 @@ TEST(LoaderInstPhysDevExts, GetDispModesKHRNoSupport) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); @@ -4267,8 +4244,8 @@ TEST(LoaderInstPhysDevExts, GetDispModesKHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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}); @@ -4285,7 +4262,7 @@ TEST(LoaderInstPhysDevExts, GetDispModesKHRInstanceAndICDSupport) { 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 @@ -4324,8 +4301,7 @@ TEST(LoaderInstPhysDevExts, GetDispModesKHRMixed) { 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) { @@ -4358,8 +4334,7 @@ TEST(LoaderInstPhysDevExts, GetDispModesKHRMixed) { 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 && @@ -4392,7 +4367,7 @@ TEST(LoaderInstPhysDevExts, GetDispModesKHRMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -4405,7 +4380,7 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRNoSupport) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); @@ -4441,8 +4416,8 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRInstanceAndICDSupport) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(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}); @@ -4458,7 +4433,7 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRInstanceAndICDSupport) { 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 @@ -4497,8 +4472,7 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRMixed) { 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) { @@ -4531,8 +4505,7 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRMixed) { 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 && @@ -4565,7 +4538,7 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -4579,7 +4552,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRNoSupport) { 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.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); @@ -4597,8 +4570,8 @@ TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRInstanceAndICDSupport) { 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}); @@ -4670,8 +4643,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRMixed) { 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 @@ -4725,7 +4697,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -4739,7 +4711,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRNoSupport) { 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.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); @@ -4757,8 +4729,8 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRInstanceAndICDSupport) { 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}); @@ -4829,8 +4801,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRMixed) { 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 @@ -4883,7 +4854,7 @@ TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -4896,7 +4867,7 @@ TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRNoSupport) { 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.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); @@ -4913,8 +4884,8 @@ TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRInstanceAndICDSupport) { 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}); @@ -4983,8 +4954,7 @@ TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRMixed) { 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 @@ -5035,7 +5005,7 @@ TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -5048,7 +5018,7 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRNoSupport) { 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.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); @@ -5065,8 +5035,8 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRInstanceAndICDSupport) { 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}); @@ -5127,8 +5097,7 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRMixed) { 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 @@ -5176,7 +5145,7 @@ TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -5189,7 +5158,7 @@ TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTNoSupport) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.create_info.add_extension(VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME); @@ -5206,8 +5175,8 @@ TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTInstanceAndICDSupport) { 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}); @@ -5262,8 +5231,7 @@ TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTMixed) { 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 @@ -5297,8 +5265,7 @@ TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTMixed) { 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 && @@ -5328,7 +5295,7 @@ TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTMixed) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.CheckCreate(); @@ -5341,7 +5308,7 @@ TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTNoSupport) { 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.get_test_icd(0).add_physical_device({}); InstWrapper instance(env.vulkan_functions); instance.create_info.add_extension(VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME); @@ -5358,8 +5325,8 @@ TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTInstanceAndICDSupport) { 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}); @@ -5375,7 +5342,7 @@ TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTInstanceAndICDSupport) { 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 @@ -5415,8 +5382,7 @@ TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTMixed) { 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 @@ -5450,8 +5416,7 @@ TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTMixed) { 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 && @@ -5484,18 +5449,18 @@ TEST(LoaderInstPhysDevExts, DifferentInstanceExtensions) { // 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.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.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.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}; @@ -5539,18 +5504,15 @@ TEST(LoaderInstPhysDevExts, DifferentPhysicalDeviceExtensions) { // 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.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.get_test_icd(1).add_and_get_physical_device("pd1").extensions.push_back({VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, 0}); #ifndef VULKANSC // VK_EXT_calibrated_timestamps is not supported in Vulkan SC 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}); -#endif // VULKANSC + env.get_test_icd(2).add_and_get_physical_device("pd2").extensions.push_back({VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, 0}); +#endif 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 ee464a1cd..1d601dcb0 100644 --- a/tests/loader_regression_tests.cpp +++ b/tests/loader_regression_tests.cpp @@ -376,11 +376,12 @@ TEST(EnumerateDeviceLayerProperties, LayersMatch) { 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(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_and_get_physical_device("physical_device_0"); std::array 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(); @@ -403,11 +404,12 @@ TEST(EnumerateDeviceExtensionProperties, DeviceExtensionEnumerated) { 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(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_and_get_physical_device("physical_device_0"); std::array 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(); @@ -523,10 +525,7 @@ TEST(EnumerateDeviceExtensionProperties, ImplicitLayerPresentNoExtensions) { std::vector 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(TestICDDetails(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") @@ -542,7 +541,7 @@ TEST(EnumerateDeviceExtensionProperties, ImplicitLayerPresentNoExtensions) { 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(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_and_get_physical_device({}); std::vector exts; std::vector layer_exts; @@ -559,10 +558,10 @@ TEST(EnumerateDeviceExtensionProperties, ImplicitLayerPresentWithExtensions) { 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(); @@ -573,7 +572,7 @@ TEST(EnumerateDeviceExtensionProperties, ImplicitLayerPresentWithExtensions) { 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(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_and_get_physical_device({}); std::vector exts; std::vector layer_exts; @@ -590,12 +589,12 @@ TEST(EnumerateDeviceExtensionProperties, ImplicitLayerPresentWithLotsOfExtension 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(); @@ -658,7 +657,7 @@ TEST(EnumerateDeviceExtensionProperties, NoDriverExtensionsImplicitLayerPresentW 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(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_and_get_physical_device({}); std::vector exts; std::vector layer_exts; @@ -675,14 +674,14 @@ TEST(EnumerateDeviceExtensionProperties, ImplicitLayerPresentWithDuplicateExtens 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(); @@ -693,7 +692,7 @@ TEST(EnumerateDeviceExtensionProperties, ImplicitLayerPresentWithDuplicateExtens 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(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_and_get_physical_device({}); std::vector exts; std::vector layer_exts; @@ -710,7 +709,7 @@ TEST(EnumerateDeviceExtensionProperties, ImplicitLayerPresentWithOnlyDuplicateEx 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(); @@ -746,8 +745,8 @@ TEST(EnumeratePhysicalDevices, TwoCall) { 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}; @@ -772,8 +771,8 @@ TEST(EnumeratePhysicalDevices, MatchOneAndTwoCallNumbers) { 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}; @@ -808,8 +807,8 @@ TEST(EnumeratePhysicalDevices, TwoCallIncomplete) { 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}; @@ -885,7 +884,7 @@ TEST(EnumeratePhysicalDevices, CallTwiceNormal) { auto& driver = env.add_icd(TestICDDetails(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}; @@ -911,7 +910,7 @@ TEST(EnumeratePhysicalDevices, CallTwiceIncompleteOnceNormal) { auto& driver = env.add_icd(TestICDDetails(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}; @@ -947,7 +946,7 @@ TEST(EnumeratePhysicalDevices, CallThriceSuccessReduce) { auto& driver = env.add_icd(TestICDDetails(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}; @@ -982,8 +981,8 @@ TEST(EnumeratePhysicalDevices, CallThriceAddInBetween) { FrameworkEnvironment env{}; auto& driver = env.add_icd(TestICDDetails(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(); @@ -994,8 +993,8 @@ TEST(EnumeratePhysicalDevices, CallThriceAddInBetween) { 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 physical_device_handles_2 = std::vector(returned_physical_count); ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles_2.data())); @@ -1022,7 +1021,7 @@ TEST(EnumeratePhysicalDevices, CallThriceRemoveInBetween) { auto& driver = env.add_icd(TestICDDetails(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}; @@ -1076,10 +1075,11 @@ TEST(EnumeratePhysicalDevices, CallThriceRemoveInBetween) { TEST(EnumeratePhysicalDevices, MultipleAddRemoves) { FrameworkEnvironment env{}; auto& driver = env.add_icd(TestICDDetails(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, 8> physical_dev_handles; InstWrapper inst{env.vulkan_functions}; @@ -1092,7 +1092,7 @@ TEST(EnumeratePhysicalDevices, MultipleAddRemoves) { 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(driver.physical_devices.size()); @@ -1102,8 +1102,8 @@ TEST(EnumeratePhysicalDevices, MultipleAddRemoves) { 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(driver.physical_devices.size()); @@ -1119,7 +1119,7 @@ TEST(EnumeratePhysicalDevices, MultipleAddRemoves) { 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(driver.physical_devices.size()); @@ -1132,7 +1132,7 @@ TEST(EnumeratePhysicalDevices, MultipleAddRemoves) { 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(driver.physical_devices.size()); @@ -1269,9 +1269,9 @@ TEST(EnumeratePhysicalDevices, DeviceFiltering) { auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).set_min_icd_interface_version(5); for (uint32_t i = 0; i < 10; i++) { - driver.physical_devices.emplace_back("physical_device_" + std::to_string(i)); - driver.physical_devices.back().properties.deviceID = 0x1000 + i; - driver.physical_devices.back().properties.vendorID = 0x2000 + 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}; @@ -1391,9 +1391,9 @@ TEST(EnumeratePhysicalDevices, DeviceFilteringByDriverId) { .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); for (uint32_t i = 0; i < 10; i++) { - driver.physical_devices.emplace_back("physical_device_" + std::to_string(i)); - driver.physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); - driver.physical_devices.back().driver_properties.driverID = VkDriverId(100 + 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}; @@ -1601,7 +1601,7 @@ TEST(CreateDevice, ConsecutiveCreate) { auto& driver = env.add_icd(TestICDDetails(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(); @@ -1618,7 +1618,7 @@ TEST(CreateDevice, ConsecutiveCreateWithoutDestruction) { auto& driver = env.add_icd(TestICDDetails(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(); @@ -1946,14 +1946,16 @@ TEST(EnumeratePhysicalDeviceGroups, OneCall) { .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); // ICD contains 3 devices in two groups + std::array 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; - } - 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]); + 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(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 @@ -2080,14 +2082,16 @@ TEST(EnumeratePhysicalDeviceGroups, TwoCall) { .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); // ICD contains 3 devices in two groups + std::array 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; - } - 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]); + 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(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 @@ -2197,14 +2201,16 @@ TEST(EnumeratePhysicalDeviceGroups, TwoCallIncomplete) { .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); // ICD contains 3 devices in two groups + std::array 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 { @@ -2298,19 +2304,19 @@ TEST(EnumeratePhysicalDeviceGroups, TestCoreVersusExtensionSameReturns) { .add_instance_extension({VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME}); // Generate the devices + std::array 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; @@ -2387,19 +2393,19 @@ TEST(EnumeratePhysicalDeviceGroups, CallThriceAddGroupInBetween) { .set_icd_api_version(VK_API_VERSION_1_1); // Generate the devices + std::array 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}; @@ -2422,7 +2428,7 @@ TEST(EnumeratePhysicalDeviceGroups, CallThriceAddGroupInBetween) { } // 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 group_props_after{}; group_props_after.resize(before_group_count, @@ -2482,20 +2488,20 @@ TEST(EnumeratePhysicalDeviceGroups, CallTwiceRemoveGroupInBetween) { .set_icd_api_version(VK_API_VERSION_1_1); // Generate the devices + std::array 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}; @@ -2569,19 +2575,19 @@ TEST(EnumeratePhysicalDeviceGroups, CallTwiceAddDeviceInBetween) { .set_icd_api_version(VK_API_VERSION_1_1); // Generate the devices + std::array 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}; @@ -2603,7 +2609,7 @@ TEST(EnumeratePhysicalDeviceGroups, CallTwiceAddDeviceInBetween) { } // 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 group_props_after{}; group_props_after.resize(expected_group_count, @@ -2655,19 +2661,19 @@ TEST(EnumeratePhysicalDeviceGroups, CallTwiceRemoveDeviceInBetween) { .set_icd_api_version(VK_API_VERSION_1_1); // Generate the devices + std::array 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}; @@ -2752,19 +2758,19 @@ TEST(EnumeratePhysicalDeviceGroups, MultipleAddRemoves) { .set_icd_api_version(VK_API_VERSION_1_1); // Generate the devices + std::array 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}; @@ -2791,7 +2797,7 @@ TEST(EnumeratePhysicalDeviceGroups, MultipleAddRemoves) { } // 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 group_props_after_add_group{}; @@ -2836,9 +2842,7 @@ TEST(EnumeratePhysicalDeviceGroups, MultipleAddRemoves) { } // 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 group_props_after_add_device{}; @@ -2892,44 +2896,40 @@ TEST(EnumeratePhysicalDeviceGroups, FakePNext) { env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, 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)); 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); @@ -2975,17 +2975,20 @@ TEST(EnumeratePhysicalDeviceGroups, DeviceFiltering) { .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); // ICD contains 10 devices in 5 groups - for (size_t i = 0; i < 10; 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; + std::array 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; - driver.physical_devices.back().properties.deviceID = 0x1000 + i; - driver.physical_devices.back().properties.vendorID = 0x2000 + i; + 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(driver.physical_devices[2 * i]); - driver.physical_device_groups.back().use_physical_device(driver.physical_devices[2 * i + 1]); + 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}; @@ -3123,17 +3126,20 @@ TEST(EnumeratePhysicalDeviceGroups, DeviceFilteringByDriverId) { .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); // ICD contains 10 devices in 5 groups - for (size_t i = 0; i < 10; 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; + std::array 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); - driver.physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); - driver.physical_devices.back().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(driver.physical_devices[2 * i]); - driver.physical_device_groups.back().use_physical_device(driver.physical_devices[2 * i + 1]); + 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}; @@ -3273,10 +3279,9 @@ TEST(ExtensionManual, ToolingProperties) { { // core FrameworkEnvironment env{}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_3)) - .add_physical_device({}) .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}; @@ -3324,45 +3329,44 @@ TEST(SortedPhysicalDevices, DevicesSortEnabled10NoAppExt) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, 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.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.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.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(); @@ -3432,45 +3436,44 @@ TEST(SortedPhysicalDevices, DevicesSortEnabled10AppExt) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, 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.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.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.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); @@ -3555,48 +3558,47 @@ TEST(SortedPhysicalDevices, DevicesSortEnabled11) { env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, 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.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.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.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); @@ -3683,39 +3685,38 @@ TEST(SortedPhysicalDevices, DevicesSortedDisabled) { env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); 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.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.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.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); @@ -3785,68 +3786,63 @@ TEST(SortedPhysicalDevices, DeviceGroupsSortedEnabled) { env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, 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)); 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)); 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)); 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); @@ -3978,60 +3974,55 @@ TEST(SortedPhysicalDevices, DeviceGroupsSortedDisabled) { env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, 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)); 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)); 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)); 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); @@ -4187,10 +4178,10 @@ TEST(PortabilityICDConfiguration, PortabilityAndRegularICD) { 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}; @@ -4268,10 +4259,10 @@ TEST(PortabilityICDConfiguration, PortabilityAndRegularICDCheckFlagsPassedIntoIC 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; @@ -4397,7 +4388,7 @@ TEST(DuplicateRegistryEntries, Layers) { 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( @@ -4415,7 +4406,7 @@ TEST(DuplicateRegistryEntries, Layers) { 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)) .add_physical_device("physical_device_0") @@ -4433,13 +4424,12 @@ TEST(DuplicateRegistryEntries, Drivers) { 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(TestICDDetails(TEST_ICD_PATH_VERSION_2).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( @@ -4466,16 +4456,13 @@ TEST(LibraryLoading, SystemLocations) { } #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)}; +// 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(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::override_folder)) .add_physical_device({}); - auto symlink_path = - env.get_folder(ManifestLocation::driver_env_var).add_symlink(env.get_icd_manifest_path(0), "symlink_to_driver.json"); - - 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); @@ -4484,29 +4471,23 @@ TEST(ManifestDiscovery, ValidSymlinkInXDGEnvVar) { // Check that valid symlinks do not cause the loader to crash TEST(ManifestDiscovery, ValidSymlink) { - FrameworkEnvironment env{FrameworkSettings{}.set_enable_default_search_paths(false)}; + FrameworkEnvironment env{FrameworkSettings{}}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::override_folder)) .add_physical_device({}); - auto symlink_path = - env.get_folder(ManifestLocation::driver_env_var).add_symlink(env.get_icd_manifest_path(0), "symlink_to_driver.json"); - - 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)}; - - auto symlink_path = - env.get_folder(ManifestLocation::driver) - .add_symlink(env.get_folder(ManifestLocation::driver).location() / "nothing_here.json", "symlink_to_nothing.json"); +// 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); @@ -4515,13 +4496,10 @@ TEST(ManifestDiscovery, InvalidSymlinkXDGEnvVar) { // Check that invalid symlinks do not cause the loader to crash TEST(ManifestDiscovery, InvalidSymlink) { - FrameworkEnvironment env{FrameworkSettings{}.set_enable_default_search_paths(false)}; - - auto symlink_path = - env.get_folder(ManifestLocation::driver_env_var) - .add_symlink(env.get_folder(ManifestLocation::driver).location() / "nothing_here.json", "symlink_to_nothing.json"); + 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); @@ -4535,11 +4513,11 @@ 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; + 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(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; + 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()); @@ -4549,7 +4527,7 @@ TEST(ManifestDiscovery, AppleBundles) { // Verify that this is the 'right' GPU, aka the one from the bundle 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_0.properties.deviceID, props.deviceID); } // Add two drivers, one to the bundle and one using the driver env-var @@ -4557,11 +4535,13 @@ 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; + + 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(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; + 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()); @@ -4571,7 +4551,7 @@ TEST(ManifestDiscovery, AppleBundlesEnvVarActive) { // 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 @@ -4603,9 +4583,9 @@ TEST(LayerCreatesDevice, Basic) { 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.get_test_icd(0).add_and_get_physical_device("Device0"); env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)); - env.get_test_icd(1).physical_devices.emplace_back("Device1"); + env.get_test_icd(1).add_and_get_physical_device("Device1"); env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name("implicit_layer_name") @@ -4745,7 +4725,9 @@ TEST(InvalidManifest, ICD) { 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}; @@ -4770,7 +4752,9 @@ TEST(InvalidManifest, Layer) { 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}; @@ -4779,14 +4763,13 @@ TEST(InvalidManifest, Layer) { #ifndef VULKANSC // VK_MSFT_layered_driver is not supported in Vulkan SC #if defined(WIN32) -void add_dxgi_adapter(FrameworkEnvironment& env, std::filesystem::path const& name, LUID luid, uint32_t vendor_id) { +VkPhysicalDevice 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)); 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); @@ -4813,6 +4796,7 @@ void add_dxgi_adapter(FrameworkEnvironment& env, std::filesystem::path const& na } 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) { @@ -4825,7 +4809,7 @@ TEST(EnumerateAdapterPhysicalDevices, SameAdapterLUID_reordered) { // 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; @@ -4869,7 +4853,8 @@ TEST(EnumerateAdapterPhysicalDevices, SameAdapterLUID_reordered) { } // 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}; @@ -4921,12 +4906,13 @@ TEST(EnumerateAdapterPhysicalDevices, SameAdapterLUID_same_order) { // 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}; @@ -5398,7 +5384,7 @@ TEST(DriverUnloadingFromZeroPhysDevs, HandleRecreation) { 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); diff --git a/tests/loader_settings_tests.cpp b/tests/loader_settings_tests.cpp index 395b70a42..7f8019404 100644 --- a/tests/loader_settings_tests.cpp +++ b/tests/loader_settings_tests.cpp @@ -29,23 +29,40 @@ #include -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 + 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) + #ifdef VULKANSC - if (use_secure) - return s + "/etc/vulkansc/loader_settings.d/vk_loader_settings.json"; - else - return s + "/home/fake_home/.local/share/vulkansc/loader_settings.d/vk_loader_settings.json"; + "/vulkansc/loader_settings.d/vk_loader_settings.json"; #else - 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"; -#endif // VULKANSC + "/vulkan/loader_settings.d/vk_loader_settings.json"; +#endif +#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) + +#ifdef VULKANSC + "/vulkansc/loader_settings.d/vk_loader_settings.json\" but did not contain any valid settings."; +#else + "/vulkan/loader_settings.d/vk_loader_settings.json\" but did not contain any valid settings."; +#endif #endif } enum class LayerType { @@ -117,39 +134,56 @@ TEST(SettingsFile, SettingsInUnsecuredLocation) { 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)); + 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(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({}); + const char* regular_layer_name = "VK_LAYER_TestLayer_0"; + env.add_explicit_layer(TestLayerDetails{ + 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"))), + 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)}; + FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(true)}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({}); env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)); const char* regular_layer_name = "VK_LAYER_TestLayer_0"; @@ -163,33 +197,18 @@ TEST(SettingsFile, SettingsInSecuredLocation) { .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(); - 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)); + 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 @@ -494,19 +513,21 @@ TEST(SettingsFile, LayerListIsEmpty) { writer.StartObject(); writer.AddKeyedString("file_format_version", "1.0.0"); writer.StartKeyedObject("settings"); - writer.StartKeyedObject("layers"); - writer.EndObject(); + writer.StartKeyedArray("layers"); + writer.EndArray(); writer.EndObject(); writer.EndObject(); - env.write_settings_file(writer.output); + env.write_settings_file(writer.output, true); - ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0)); + auto layer_props = env.GetLayerProperties(1); + ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name)); 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_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); + ASSERT_TRUE(env.debug_log.find(get_settings_not_in_use_log_message(env, true))); + auto actice_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); + ASSERT_TRUE(string_eq(actice_layer_props.at(0).layerName, implicit_layer_name)); } // If a settings file exists but contains no valid settings - don't consider it @@ -543,7 +564,7 @@ TEST(SettingsFile, InvalidSettingsFile) { 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(); } @@ -554,7 +575,7 @@ TEST(SettingsFile, InvalidSettingsFile) { 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(); } @@ -568,7 +589,7 @@ TEST(SettingsFile, InvalidSettingsFile) { writer.StartKeyedObject("settings"); writer.EndObject(); writer.EndObject(); - env.write_settings_file(writer.output); + env.write_settings_file(writer.output, true); check_integrity(); } @@ -585,7 +606,7 @@ TEST(SettingsFile, InvalidSettingsFile) { writer.EndObject(); } writer.EndObject(); - env.write_settings_file(writer.output); + env.write_settings_file(writer.output, true); check_integrity(); } @@ -988,6 +1009,55 @@ TEST(SettingsFile, MetaLayerAlsoActivates) { } } +TEST(SettingsFile, DuplicateMetaLayers) { + FrameworkEnvironment env{}; + env.add_icd(TestICDDetails(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)), + "explicit_test_layer.json"); + // 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")), + "implicit_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_layer(explicit_layer_name) + .set_disable_environment("NotGonnaWork")), + "meta_test_layer.json"); + + 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{}; @@ -1764,8 +1834,8 @@ TEST(SettingsFile, EnvVarsWork_VK_LOADER_LAYERS_DISABLE) { 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.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{ @@ -1773,11 +1843,13 @@ TEST(SettingsFile, MultipleKeysInRegistryInUnsecureLocation) { 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.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(TestICDDetails(TEST_ICD_PATH_VERSION_2)); auto layer_props = env.GetLayerProperties(1); @@ -1787,16 +1859,16 @@ TEST(SettingsFile, MultipleKeysInRegistryInUnsecureLocation) { 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)}; + FrameworkEnvironment env{FrameworkSettings{}.set_run_as_if_with_elevated_privleges(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"); + 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{ @@ -1812,7 +1884,6 @@ TEST(SettingsFile, MultipleKeysInRegistryInSecureLocation) { env.add_icd(TestICDDetails(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)); { auto layer_props = env.GetLayerProperties(1); @@ -2571,14 +2642,14 @@ TEST(SettingsFile, StderrLog_NoOutput) { 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.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); @@ -2662,14 +2733,14 @@ TEST(SettingsFile, NoStderr_log_but_VK_LOADER_DEBUG) { 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.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); @@ -3034,3 +3105,578 @@ TEST(SettingsFile, EnvVarsWorkTogether) { EXPECT_TRUE(env.platform_shim->find_in_log("Insert instance layer \"VK_LAYER_add_env_var_implicit_layer\"")); } } + +// 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(TestICDDetails(TEST_ICD_PATH_VERSION_2)) + .add_physical_device(PhysicalDevice{}.set_deviceName(regular_driver_name).finish()); + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).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(TestICDDetails(TEST_ICD_PATH_VERSION_2)) + .add_physical_device(PhysicalDevice{}.set_deviceName(regular_driver_name).finish()); + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).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(TestICDDetails(TEST_ICD_PATH_VERSION_2)) + .add_physical_device(PhysicalDevice{}.set_deviceName(regular_driver_name).finish()); + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).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(TestICDDetails(TEST_ICD_PATH_VERSION_2).set_discovery_type(ManifestDiscoveryType::override_folder)) + .add_physical_device(PhysicalDevice{}.set_deviceName(settings_driver_name).finish()); + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device(PhysicalDevice{}.set_deviceName(driver_name).finish()); + + env.add_explicit_layer(TestLayerDetails{ + ManifestLayer{}.add_layer( + ManifestLayer::LayerDescription{}.set_name("VK_LAYER_layer").set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), + "regular_test_layer.json"} + .set_discovery_type(ManifestDiscoveryType::override_folder)); + 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 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(TestICDDetails(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 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(TestICDDetails(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 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(TestICDDetails(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(TestICDDetails(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(TestICDDetails(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 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(TestICDDetails(TEST_ICD_PATH_VERSION_2)) + .add_physical_device(PhysicalDevice().set_deviceName("A").set_deviceUUID(uuids[0]).finish()); + + auto& icd = env.add_icd(TestICDDetails(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(TestICDDetails(TEST_ICD_PATH_VERSION_2).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 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(TestICDDetails(TEST_ICD_PATH_VERSION_2).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(TestICDDetails(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 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(TestICDDetails(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(TestICDDetails(TEST_ICD_PATH_VERSION_2).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 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(TestICDDetails(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(TestICDDetails(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(TestICDDetails(TEST_ICD_PATH_VERSION_2).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 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(TestICDDetails(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(TestICDDetails(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(TestICDDetails(TEST_ICD_PATH_VERSION_2).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))); +} diff --git a/tests/loader_testing_main.cpp b/tests/loader_testing_main.cpp index 018bea434..263c1e36f 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 { @@ -70,14 +72,16 @@ int main(int argc, char** argv) { 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 482bd5fb6..91ce4e20d 100644 --- a/tests/loader_threading_tests.cpp +++ b/tests/loader_threading_tests.cpp @@ -88,7 +88,7 @@ TEST(Threading, InstanceCreateDestroyLoop) { uint32_t num_loops_try_get_instance_proc_addr = 5; uint32_t num_loops_try_get_device_proc_addr = 100; - 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 instance_creation_threads; @@ -112,7 +112,7 @@ TEST(Threading, DeviceCreateDestroyLoop) { uint32_t num_loops_create_destroy_device = 1000; 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)}, diff --git a/tests/loader_unknown_ext_tests.cpp b/tests/loader_unknown_ext_tests.cpp index 782275682..08fbe6cbb 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,13 @@ using layer_implementation_physical_device_functions = layer_implementation_func 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(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_and_get_physical_device({}); uint32_t function_count = MAX_NUM_UNKNOWN_EXTS; std::vector 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(); @@ -357,13 +360,15 @@ TEST(UnknownFunction, PhysicalDeviceFunctionMultipleDriverSupport) { 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}; @@ -395,12 +400,14 @@ TEST(UnknownFunctionDeathTests, PhysicalDeviceFunctionErrorPath) { 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}; @@ -452,12 +459,14 @@ TEST(UnknownFunction, PhysicalDeviceFunctionMultipleDriverSupportWithImplicitLay 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); } @@ -513,11 +522,12 @@ TEST(UnknownFunction, PhysicalDeviceFunctionWithImplicitLayerInterception) { 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(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_and_get_physical_device({}); uint32_t function_count = 100; std::vector 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") @@ -541,7 +551,7 @@ TEST(UnknownFunction, PhysicalDeviceFunctionWithMultipleImplicitLayersIntercepti std::vector 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") @@ -558,7 +568,7 @@ TEST(UnknownFunction, PhysicalDeviceFunctionWithMultipleImplicitLayersIntercepti 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,18 +636,18 @@ void unknown_function_test_impl(std::vector const& flags) { using layer_intercept_functions_type = layer_intercept_functions; FrameworkEnvironment env{}; - auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); + auto& driver = env.add_icd(TestICDDetails(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 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)) { @@ -1087,8 +1097,7 @@ struct D {}; 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(TestICDDetails(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); @@ -1120,8 +1129,8 @@ TEST(UnknownFunction, PhysicalDeviceFunctionTwoLayerInterception) { 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(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_and_get_physical_device({}); std::vector unknown_funcs; unknown_funcs.emplace_back("vkZero_uint32_uint32_0"); diff --git a/tests/loader_version_tests.cpp b/tests/loader_version_tests.cpp index 9be5528a7..d2b3579f3 100644 --- a/tests/loader_version_tests.cpp +++ b/tests/loader_version_tests.cpp @@ -102,8 +102,8 @@ TEST(ICDInterfaceVersion2Plus, l5_icd5) { 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"); + driver.add_and_get_physical_device("physical_device_1"); + driver.add_and_get_physical_device("physical_device_0"); uint32_t physical_count = static_cast(driver.physical_devices.size()); uint32_t returned_physical_count = static_cast(driver.physical_devices.size()); std::vector physical_device_handles = std::vector(physical_count); @@ -133,8 +133,8 @@ TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, version_6) { // 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 physical_device_handles{physical_count}; @@ -184,8 +184,8 @@ TEST(ICDInterfaceVersion2, EnumAdapters2) { auto& driver = env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA}.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(driver.physical_devices.size()); uint32_t returned_physical_count = static_cast(driver.physical_devices.size()); std::vector physical_device_handles = std::vector(physical_count); @@ -213,7 +213,7 @@ TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyPhysDevResul .set_icd_api_version(VK_API_VERSION_1_1); const std::vector 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{}; @@ -257,13 +257,16 @@ TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyGroupResults .set_icd_api_version(VK_API_VERSION_1_1); const std::vector 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{}; @@ -333,17 +336,17 @@ TEST(MultipleICDConfig, Basic) { env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)); env.add_icd(TestICDDetails(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(); @@ -352,9 +355,9 @@ TEST(MultipleICDConfig, Basic) { 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) { @@ -364,11 +367,11 @@ TEST(MultipleDriverConfig, DifferentICDInterfaceVersions) { env.add_icd(TestICDDetails(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; @@ -391,18 +394,18 @@ TEST(MultipleDriverConfig, DifferentICDsWithDevices) { // 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; @@ -429,26 +432,26 @@ TEST(MultipleDriverConfig, DifferentICDsWithDevicesAndGroups) { // 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); @@ -493,20 +496,15 @@ TEST(MultipleICDConfig, version_5_and_version_6) { 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(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(driver_6.physical_devices.size()); driver_6.set_max_icd_interface_version(6); @@ -595,8 +593,9 @@ VkResult test_vkSetPrivateData(VkDevice, VkObjectType, uint64_t, VkPrivateDataSl 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(TestICDDetails(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)}, @@ -635,7 +634,7 @@ TEST(MinorVersionUpdate, Version1_3) { 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(); @@ -945,8 +944,7 @@ void CheckDirectDriverLoading(FrameworkEnvironment& env, std::vector 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; + 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"); @@ -958,8 +956,7 @@ void CheckDirectDriverLoading(FrameworkEnvironment& env, std::vector 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; + direct_driver_icd.add_and_get_physical_device({}).properties.driverVersion = driver.driver_version; if (!exclusive && driver.expect_to_find) { expected_driver_count++; } @@ -1156,7 +1153,7 @@ 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({}); + direct_driver_icd.add_physical_device({}); VkDirectDriverLoadingInfoLUNARG ddl_info{}; ddl_info.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG; diff --git a/tests/loader_wsi_tests.cpp b/tests/loader_wsi_tests.cpp index 52be52064..8f50342f6 100644 --- a/tests/loader_wsi_tests.cpp +++ b/tests/loader_wsi_tests.cpp @@ -128,7 +128,7 @@ TEST(WsiTests, GetPhysicalDeviceWin32PresentNoICDSupport) { 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}; @@ -155,7 +155,7 @@ TEST(WsiTests, GetPhysicalDeviceWin32PresentICDSupport) { 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}; @@ -182,8 +182,8 @@ TEST(WsiTests, Win32GetPhysicalDeviceSurfaceSupportKHR) { 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; } @@ -313,7 +313,7 @@ TEST(WsiTests, GetPhysicalDeviceXcbPresentNoICDSupport) { 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}; @@ -340,7 +340,7 @@ TEST(WsiTests, GetPhysicalDeviceXcbPresentICDSupport) { 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}; @@ -367,8 +367,8 @@ TEST(WsiTests, XcbGetPhysicalDeviceSurfaceSupportKHR) { 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; } @@ -497,7 +497,7 @@ TEST(WsiTests, GetPhysicalDeviceXlibPresentNoICDSupport) { 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}; @@ -524,7 +524,7 @@ TEST(WsiTests, GetPhysicalDeviceXlibPresentICDSupport) { 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}; @@ -551,8 +551,8 @@ TEST(WsiTests, XlibGetPhysicalDeviceSurfaceSupportKHR) { 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; } @@ -681,7 +681,7 @@ TEST(WsiTests, GetPhysicalDeviceWaylandPresentNoICDSupport) { 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}; @@ -708,7 +708,7 @@ TEST(WsiTests, GetPhysicalDeviceWaylandPresentICDSupport) { 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}; @@ -735,8 +735,8 @@ TEST(WsiTests, WaylandGetPhysicalDeviceSurfaceSupportKHR) { 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; } @@ -940,15 +940,15 @@ TEST(WsiTests, EXTSurfaceMaintenance1) { 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(TestICDDetails(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; @@ -958,21 +958,22 @@ TEST(WsiTests, EXTSurfaceMaintenance1) { auto& icd2 = env.add_icd(TestICDDetails(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> 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; + test_physical_device_1.surface_present_mode_compatibility = compatible_present_modes; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)) .setup_WSI() .add_physical_device(PhysicalDevice{}
JSON NodeDescription and NotesRestrictionsParentIntrospection Query