updata1.4.309

Signed-off-by: ZhangLiang <zhangliang335@h-partners.com>
This commit is contained in:
ZhangLiang
2025-04-23 09:58:25 +00:00
parent 3727acb995
commit d01d760495
148 changed files with 13405 additions and 5438 deletions
+67 -16
View File
@@ -1,5 +1,5 @@
# Copyright (c) 2021-2023 Valve Corporation
# Copyright (c) 2021-2023 LunarG, Inc.
# Copyright (c) 2021-2024 Valve Corporation
# Copyright (c) 2021-2024 LunarG, Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@ permissions: read-all
jobs:
linux:
needs: codegen
runs-on: ${{matrix.os}}
strategy:
matrix:
@@ -45,7 +46,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.7'
python-version: '3.11'
- name: Test CMake min
# NOTE: The main users who benefit from an older CMake version
# are linux users stuck on older LTS releases. It's idiomatic best
@@ -55,9 +56,12 @@ jobs:
if: ${{ matrix.os == 'ubuntu-20.04' }}
uses: lukka/get-cmake@latest
with:
cmakeVersion: 3.17.2
cmakeVersion: 3.22.1
- run: sudo apt update
- run: sudo apt install --yes --no-install-recommends libwayland-dev libxrandr-dev
# This is to combat a bug when using 6.6 linux kernels with thread/address sanitizer
# https://github.com/google/sanitizers/issues/1716
- run: sudo sysctl vm.mmap_rnd_bits=28
- run: |
cmake -S. -B build \
-D CMAKE_BUILD_TYPE=${{ matrix.config }} \
@@ -79,6 +83,7 @@ jobs:
- run: scripts/generate_source.py --verify ext/Vulkan-Headers/registry/
linux-no-asm:
needs: codegen
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
@@ -98,6 +103,7 @@ jobs:
- run: ctest --output-on-failure -E UnknownFunction --test-dir build/
linux-32:
needs: codegen
runs-on: ubuntu-22.04
strategy:
matrix:
@@ -106,10 +112,10 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.7'
python-version: '3.11'
- uses: lukka/get-cmake@latest
with:
cmakeVersion: 3.17.2
cmakeVersion: 3.22.1
- name: Enable 32 bit
run: sudo dpkg --add-architecture i386
- run: sudo apt-get update
@@ -124,6 +130,7 @@ jobs:
-D UPDATE_DEPS=ON \
-D BUILD_WERROR=ON \
-D SYSCONFDIR=/etc/not_vulkan \
-D PKG_CONFIG_EXECUTABLE=/usr/bin/i686-linux-gnu-pkg-config \
-G Ninja
env:
CFLAGS: -m32
@@ -136,15 +143,16 @@ jobs:
working-directory: build/
linux-32-no-asm:
needs: codegen
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.7'
python-version: '3.11'
- uses: lukka/get-cmake@latest
with:
cmakeVersion: 3.17.2
cmakeVersion: 3.22.1
- name: Enable 32 bit
run: sudo dpkg --add-architecture i386
- run: sudo apt-get update
@@ -159,6 +167,7 @@ jobs:
-D UPDATE_DEPS=ON \
-D BUILD_WERROR=ON \
-D USE_GAS=OFF \
-D PKG_CONFIG_EXECUTABLE=/usr/bin/i686-linux-gnu-pkg-config \
-G Ninja
env:
CFLAGS: -m32
@@ -170,6 +179,8 @@ jobs:
working-directory: build/
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
strategy:
matrix:
@@ -189,6 +200,8 @@ jobs:
- run: ctest --output-on-failure -C ${{matrix.config}} --test-dir build/
windows_vs-no-asm:
# windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
needs: linux-no-asm
runs-on: windows-latest
strategy:
matrix:
@@ -208,6 +221,8 @@ 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:
@@ -230,7 +245,9 @@ jobs:
- run: cmake --install build --prefix build/install
mac:
runs-on: macos-11
# Mac is 10x expensive to run on GitHub machines, so only run if we know something else passed as well
needs: windows_clang
runs-on: macos-13
strategy:
matrix:
config: [ Debug, Release ]
@@ -239,7 +256,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.7'
python-version: '3.11'
- uses: lukka/get-cmake@latest
- run: |
cmake -S. -B build \
@@ -258,8 +275,10 @@ jobs:
- run: ctest --output-on-failure --test-dir build/
apple-cross-compile:
# Mac is 10x expensive to run on GitHub machines, so only run if we know something else passed as well
needs: windows_clang
name: ${{ matrix.CMAKE_SYSTEM_NAME }}
runs-on: macos-12
runs-on: macos-13
strategy:
matrix:
CMAKE_SYSTEM_NAME: [ iOS, tvOS ]
@@ -267,7 +286,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.7'
python-version: '3.11'
- uses: lukka/get-cmake@latest
- run: |
cmake -S . -B build \
@@ -289,6 +308,8 @@ jobs:
# Building a universal binary disables assembly automatically
# Furthermore the Vulkan SDK ships universal binaries
mac-univeral:
# Mac is 10x expensive to run on GitHub machines, so only run if we know something else passed as well
needs: windows_clang
name: "Universal Binary Testing (STATIC ${{ matrix.static }}) w/ ${{ matrix.generator }}"
runs-on: macos-latest
strategy:
@@ -299,7 +320,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.7'
python-version: '3.11'
- uses: lukka/get-cmake@latest
- run: |
cmake -S. -B build \
@@ -322,12 +343,15 @@ jobs:
vtool -show-build /tmp/lib/libvulkan.dylib | grep 'architecture arm64'
chromium:
needs: codegen
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: scripts/gn/gn.py
mingw:
# windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
needs: linux-no-asm
runs-on: windows-2022
defaults:
run:
@@ -336,7 +360,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.8'
python-version: '3.11'
- uses: lukka/get-cmake@latest
- name: Setup uasm
run: |
@@ -353,7 +377,9 @@ jobs:
- run: cmake --build build
- run: cmake --install build --prefix /tmp
mingw-no-asm:
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:
@@ -362,7 +388,30 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.8'
python-version: '3.11'
- uses: lukka/get-cmake@latest
- run: |
cmake -S. -B build \
-D UPDATE_DEPS=ON \
-D CMAKE_BUILD_TYPE=Release \
-D BUILD_WERROR=ON \
-D USE_GAS=ON \
-G Ninja
- run: cmake --build build
- run: cmake --install build --prefix /tmp
mingw-no-asm:
# windows is 2x expensive to run on GitHub machines, so only run if we know something else simple passed as well
needs: linux-no-asm
runs-on: windows-2022
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- uses: lukka/get-cmake@latest
# Make sure this doesn't fail even without explicitly setting '-D USE_MASM=OFF' and without uasm
- run: |
@@ -375,6 +424,8 @@ jobs:
- 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:
+5 -5
View File
@@ -53,7 +53,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@012739e5082ff0c22ca6d6ab32e07c36df03c4a4 # v3.22.12
uses: github/codeql-action/init@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -68,16 +68,16 @@ 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@012739e5082ff0c22ca6d6ab32e07c36df03c4a4 # v3.22.12
uses: github/codeql-action/autobuild@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
- uses: actions/setup-python@v5
if: matrix.language == 'cpp'
with:
python-version: '3.7'
python-version: '3.11'
- uses: lukka/get-cmake@latest
if: matrix.language == 'cpp'
with:
cmakeVersion: 3.17.2
cmakeVersion: 3.22.1
- name: Install Dependencies
if: matrix.language == 'cpp'
run: |
@@ -96,6 +96,6 @@ jobs:
run: cmake --build build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@012739e5082ff0c22ca6d6ab32e07c36df03c4a4 # v3.22.12
uses: github/codeql-action/analyze@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
with:
category: "/language:${{matrix.language}}"
+1 -1
View File
@@ -37,7 +37,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Run clang-format
uses: jidicula/clang-format-action@v4.11.0
uses: jidicula/clang-format-action@v4.14.0
with:
clang-format-version: '16'
check-path: ${{ matrix.path }}
+1
View File
@@ -27,6 +27,7 @@ VKConfig.h
*.files
*.includes
.vscode/
.cache
.DS_Store
_out64
out32/*
+63 -6
View File
@@ -36,6 +36,7 @@ config("vulkan_internal_config") {
"-Wno-unused-variable",
"-fPIC",
]
cflags_cc = [ "-std=c++17" ]
ldflags = [ "-Wl,-Bsymbolic" ]
@@ -54,6 +55,46 @@ config("vulkan_loader_config") {
defines = [ "LOADER_USE_UNSAFE_FILE_SEARCH=1" ]
}
support_unknown_function_handling = false
if (defined(ar_path) && ar_path != "" && !is_win &&
(current_cpu == "arm64" || current_cpu == "x86_64")) {
support_unknown_function_handling = true
static_library("asm_offset") {
sources = [ "loader/asm_offset.c" ]
deps = [ "$vulkan_headers_dir:vulkan_headers" ]
# Output raw assembly instead of compiled object file. The assembly will be included as a member of the output ar file.
cflags = [ "-S" ]
configs += [ ":vulkan_internal_config" ]
configs += [ ":vulkan_loader_config" ]
}
action("gen_defines") {
script = "scripts/parse_asm_values.py"
deps = [ ":asm_offset" ]
inputs = [
"$target_out_dir/libasm_offset.a",
ar_path,
]
if (current_cpu == "arm64") {
cpu = "aarch64"
} else {
cpu = "x86_64"
}
args = [
rebase_path("$target_gen_dir/gen_defines.asm", root_build_dir),
rebase_path("$target_out_dir/libasm_offset.a", root_build_dir),
"GAS",
"Clang",
cpu,
rebase_path(ar_path, root_build_dir),
"libasm_offset.asm_offset.c.o",
]
outputs = [ "$target_gen_dir/gen_defines.asm" ]
}
}
ohos_shared_library("vulkan_loader") {
branch_protector_ret = "pac_ret"
sources = [
@@ -64,7 +105,9 @@ ohos_shared_library("vulkan_loader") {
"loader/cJSON.h",
"loader/debug_utils.c",
"loader/debug_utils.h",
"loader/dev_ext_trampoline.c",
# Should only be linked when assembler is used
# "loader/dev_ext_trampoline.c",
"loader/extension_manual.c",
"loader/extension_manual.h",
"loader/generated/vk_layer_dispatch_table.h",
@@ -77,9 +120,13 @@ ohos_shared_library("vulkan_loader") {
"loader/loader_common.h",
"loader/loader_environment.c",
"loader/loader_environment.h",
"loader/loader_json.c",
"loader/loader_json.h",
"loader/log.c",
"loader/log.h",
"loader/phys_dev_ext.c",
# Should only be linked when assembler is used
# "loader/phys_dev_ext.c",
"loader/settings.c",
"loader/settings.h",
"loader/stack_allocation.h",
@@ -88,9 +135,6 @@ ohos_shared_library("vulkan_loader") {
"loader/unknown_function_handling.c",
"loader/unknown_function_handling.h",
"loader/vk_loader_layer.h",
# TODO(jmadill): Use assembler where available.
"loader/unknown_ext_chain.c",
"loader/vk_loader_platform.h",
"loader/wsi.c",
"loader/wsi.h",
@@ -112,12 +156,25 @@ ohos_shared_library("vulkan_loader") {
"vulkan-headers:vulkan_headers",
]
if (support_unknown_function_handling) {
if (current_cpu == "arm64") {
sources += [ "loader/unknown_ext_chain_gas_aarch.S" ]
} else if (current_cpu == "x86_64") {
sources += [ "loader/unknown_ext_chain_gas_x86.S" ]
} else {
assert(false, "Unexpected CPU $current_cpu")
}
defines += [ "UNKNOWN_FUNCTIONS_SUPPORTED=1" ]
deps += [ ":gen_defines" ]
include_dirs = [ "$target_gen_dir" ]
}
output_name = "vulkan"
output_extension = "so"
part_name = "vulkan-loader"
subsystem_name = "thirdparty"
license_file = "//third_party/vulkan-loader/LICENSE.txt"
}
## Build libvulkan.so }}}
+7 -10
View File
@@ -16,6 +16,7 @@ Instructions for building this repository on Linux, Windows, and MacOS.
- [Repository Dependencies](#repository-dependencies)
- [Vulkan-Headers](#vulkan-headers)
- [Test Dependencies](#test-dependencies)
- [Warnings as errors off by default!](#warnings-as-errors-off-by-default)
- [Build and Install Directory Locations](#build-and-install-directory-locations)
- [Building Dependent Repositories with Known-Good Revisions](#building-dependent-repositories-with-known-good-revisions)
- [Automatically](#automatically)
@@ -54,7 +55,6 @@ Instructions for building this repository on Linux, Windows, and MacOS.
- [Cross Compilation](#cross-compilation)
- [Unknown function handling which requires explicit assembly implementations](#unknown-function-handling-which-requires-explicit-assembly-implementations)
- [Platforms which fully support unknown function handling](#platforms-which-fully-support-unknown-function-handling)
- [Link Time Optimization](#link-time-optimization)
- [Tests](#tests)
@@ -81,7 +81,7 @@ indicated by *install_dir*:
## Build Requirements
1. `C99` capable compiler
2. `CMake` version 3.17.2 or greater
2. `CMake` version 3.22.1 or greater
3. `Git`
### Test Requirements
@@ -271,7 +271,7 @@ These variables should be set using the `-D` option when invoking CMake to gener
- [2019](https://www.visualstudio.com/vs/older-downloads/)
- The Community Edition of each of the above versions is sufficient, as
well as any more capable edition.
- [CMake 3.17.2](https://cmake.org/files/v3.17/cmake-3.17.2-win64-x64.zip) is recommended.
- [CMake 3.22.1](https://cmake.org/files/v3.22.1/cmake-3.22.1-win64-x64.zip) is recommended.
- Use the installer option to add CMake to the system PATH
- Git Client Support
- [Git for Windows](http://git-scm.com/download/win) is a popular solution
@@ -382,7 +382,7 @@ This repository has been built and tested on the two most recent Ubuntu LTS
versions, although earlier versions may work.
It is be straightforward to adapt this repository to other Linux distributions.
[CMake 3.17.2](https://cmake.org/files/v3.17/cmake-3.17.2-Linux-x86_64.tar.gz) is recommended.
[CMake 3.22.1](https://cmake.org/files/v3.22.1/cmake-3.22.1-Linux-x86_64.tar.gz) is recommended.
#### Required Package List
@@ -561,7 +561,7 @@ Clone the Vulkan-Loader repository:
### MacOS build
[CMake 3.17.2](https://cmake.org/files/v3.17/cmake-3.17.2-Darwin-x86_64.tar.gz) is recommended.
[CMake 3.22.1](https://cmake.org/files/v3.22.1/cmake-3.22.1-Darwin-x86_64.tar.gz) is recommended.
#### Building with the Unix Makefiles Generator
@@ -633,15 +633,12 @@ can be manually disabled by setting `USE_GAS` or `USE_MASM` to `OFF`.
* 64 bit Linux (x64)
* 32 bit Linux (x86)
* 64 bit Arm (aarch64)
* 32 bit Arm (aarch32)
Platforms not listed will use a fallback C Code path that relies on tail-call optimization to work.
No guarantees are made about the use of the fallback code paths.
### Link Time Optimization
When cross compiling, the use of Link Time Optimization (LTO) and unknown function handling
is not supported. Either LTO needs to be turned off, or the assembly should be disabled.
## Tests
To build tests, make sure that the `BUILD_TESTS` option is set to true. Using
+64 -15
View File
@@ -16,9 +16,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# ~~~
cmake_minimum_required(VERSION 3.17.2)
cmake_minimum_required(VERSION 3.22.1)
project(VULKAN_LOADER VERSION 1.4.309 LANGUAGES C)
option(CODE_COVERAGE "Enable Code Coverage" OFF)
if (CODE_COVERAGE)
include(scripts/CodeCoverage.cmake)
add_code_coverage_all_targets()
endif()
project(VULKAN_LOADER VERSION 1.3.275 LANGUAGES C)
# This variable enables downstream users to customize the target API
# variant (e.g. Vulkan SC)
@@ -104,6 +111,7 @@ elseif(APPLE)
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|DragonFly|GNU")
option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON)
option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON)
option(BUILD_WSI_XLIB_XRANDR_SUPPORT "Build X11 Xrandr WSI support" ON)
option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON)
option(BUILD_WSI_DIRECTFB_SUPPORT "Build DirectFB WSI support" OFF)
@@ -111,21 +119,31 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|DragonFly|GNU")
if(BUILD_WSI_XCB_SUPPORT)
pkg_check_modules(XCB REQUIRED QUIET IMPORTED_TARGET xcb)
pkg_get_variable(XCB_INCLUDE_DIRS xcb includedir)
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_XCB_KHR)
target_link_libraries(platform_wsi INTERFACE PkgConfig::XCB)
target_include_directories(platform_wsi INTERFACE ${XCB_INCLUDE_DIRS})
endif()
if(BUILD_WSI_XLIB_SUPPORT)
pkg_check_modules(X11 REQUIRED QUIET IMPORTED_TARGET x11)
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_XLIB_KHR VK_USE_PLATFORM_XLIB_XRANDR_EXT)
target_link_libraries(platform_wsi INTERFACE PkgConfig::X11)
pkg_get_variable(XLIB_INCLUDE_DIRS x11 includedir)
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_XLIB_KHR)
target_include_directories(platform_wsi INTERFACE ${XLIB_INCLUDE_DIRS})
if(BUILD_WSI_XLIB_XRANDR_SUPPORT)
pkg_check_modules(XRANDR REQUIRED QUIET IMPORTED_TARGET xrandr)
pkg_get_variable(XLIB_XRANDR_INCLUDE_DIRS xrandr includedir)
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_XLIB_XRANDR_EXT)
target_include_directories(platform_wsi INTERFACE ${XLIB_XRANDR_INCLUDE_DIRS})
endif()
endif()
if(BUILD_WSI_WAYLAND_SUPPORT)
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_WAYLAND_KHR)
endif()
if(BUILD_WSI_DIRECTFB_SUPPORT)
pkg_check_modules(DirectFB QUIET REQUIRED IMPORTED_TARGET directfb)
pkg_get_variable(DIRECTFB_INCLUDE_DIRS directfb includedir)
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_DIRECTFB_EXT)
target_link_libraries(platform_wsi INTERFACE PkgConfig::DirectFB)
# vulkan_core.h includes <directfb.h> but the header is installed to directfb/directfb.h
target_include_directories(platform_wsi INTERFACE ${DIRECTFB_INCLUDE_DIRS} ${DIRECTFB_INCLUDE_DIRS}/directfb)
endif()
elseif(CMAKE_SYSTEM_NAME MATCHES "QNX")
message(FATAL_ERROR "See BUILD.md for QNX build")
@@ -141,6 +159,8 @@ target_link_libraries(loader_common_options INTERFACE platform_wsi)
# Enable beta Vulkan extensions
target_compile_definitions(loader_common_options INTERFACE VK_ENABLE_BETA_EXTENSIONS)
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" SYSTEM_PROCESSOR)
option(BUILD_WERROR "Enable warnings as errors")
# Set warnings as errors and the main diagnostic flags
@@ -148,28 +168,46 @@ option(BUILD_WERROR "Enable warnings as errors")
# Note that clang-cl.exe should use MSVC flavor flags, not GNU
if (CMAKE_C_COMPILER_ID STREQUAL "MSVC" OR (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "MSVC"))
if (BUILD_WERROR)
target_compile_options(loader_common_options INTERFACE /WX)
target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:/WX>)
endif()
target_compile_options(loader_common_options INTERFACE /W4)
target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:/W4>)
elseif(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
# using GCC or Clang with the regular front end
if (BUILD_WERROR)
target_compile_options(loader_common_options INTERFACE -Werror)
target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:-Werror>)
endif()
target_compile_options(loader_common_options INTERFACE -Wall -Wextra)
target_compile_options(loader_common_options INTERFACE
$<$<COMPILE_LANGUAGE::CXX,C>:-Wall>
$<$<COMPILE_LANGUAGE::CXX,C>:-Wextra>
)
endif()
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(loader_common_options INTERFACE -Wno-missing-field-initializers)
target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:-Wno-missing-field-initializers>)
# need to prepend /clang: to compiler arguments when using clang-cl
if (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND "${CMAKE_C_COMPILER_FRONTEND_VARIANT}" MATCHES "MSVC")
target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:/clang:-fno-strict-aliasing>)
else()
target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:-fno-strict-aliasing>)
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_compile_options(loader_common_options INTERFACE -Wno-stringop-truncation -Wno-stringop-overflow)
target_compile_options(loader_common_options INTERFACE
$<$<COMPILE_LANGUAGE::CXX,C>:-Wno-stringop-truncation>
$<$<COMPILE_LANGUAGE::CXX,C>:-Wno-stringop-overflow>
)
if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 7.1)
target_compile_options(loader_common_options INTERFACE -Wshadow=local) #only added in GCC 7
target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:-Wshadow=local>) #only added in GCC 7
endif()
endif()
target_compile_options(loader_common_options INTERFACE -Wpointer-arith)
target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:-Wpointer-arith>)
# Force GLIBC to use the 64 bit interface for file operations instead of 32 bit - More info in issue #1551
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "4")
target_compile_definitions(loader_common_options INTERFACE _FILE_OFFSET_BITS=64)
endif()
endif()
if(CMAKE_C_COMPILER_ID MATCHES "MSVC" OR (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "MSVC"))
@@ -178,13 +216,24 @@ if(CMAKE_C_COMPILER_ID MATCHES "MSVC" OR (CMAKE_C_COMPILER_ID STREQUAL "Clang" A
# /guard:cf: Enable control flow guard
# /wd4152: Disable warning on conversion of a function pointer to a data pointer
# /wd4201: Disable warning on anonymous struct/unions
target_compile_options(loader_common_options INTERFACE /sdl /GR- /guard:cf /wd4152 /wd4201)
target_compile_options(loader_common_options INTERFACE
$<$<COMPILE_LANGUAGE::CXX,C>:/sdl>
$<$<COMPILE_LANGUAGE::CXX,C>:/GR->
$<$<COMPILE_LANGUAGE::CXX,C>:/guard:cf>
$<$<COMPILE_LANGUAGE::CXX,C>:/wd4152>
$<$<COMPILE_LANGUAGE::CXX,C>:/wd4201>
)
# Enable control flow guard
target_link_options(loader_common_options INTERFACE "LINKER:/guard:cf")
# Prevent <windows.h> from polluting the code. guards against things like MIN and MAX
target_compile_definitions(loader_common_options INTERFACE WIN32_LEAN_AND_MEAN)
# For some reason Advapi32.lib needs to be explicitely linked to when building for Arm (32 bit) on Windows, but isn't required on any other architecture
if (SYSTEM_PROCESSOR MATCHES "arm" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
target_link_libraries(loader_common_options INTERFACE Advapi32)
endif()
endif()
# DEBUG enables runtime loader ICD verification
+1 -1
View File
@@ -26,7 +26,7 @@
</policylist>
<filefilterlist>
<filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies">
<filteritem type="filename" name="*.png|*.dll|*.so|*.aps" desc="No need to check original Khronos Group binary files"/>
<filteritem type="filename" name="*.png|*.dll|*.so|*.aps|clusterfuzz-testcase*" desc="No need to check original Khronos Group binary files"/>
</filefilter>
</filefilterlist>
<licensematcherlist>
+1 -1
View File
@@ -3,7 +3,7 @@
"Name": "Khronos Group - Vulkan-Loader",
"License": "Apache-2.0",
"License File": "LICENSE",
"Version Number": "v1.3.275",
"Version Number": "v1.4.309",
"Owner": "wangxutao5@huawei.com",
"Upstream URL": "https://github.com/KhronosGroup/Vulkan-Loader.git",
"Description": "This project provides the Vulkan ICD desktop loader for Windows, Linux, MacOS, and OpenHarmony."
+1 -1
View File
@@ -41,7 +41,7 @@ Vulkan-Loader会根据GPU驱动的**json清单文件**中配置的`library_path`
"file_format_version": "1.0.1",
"ICD": {
"library_path": "path to driver library",
"api_version": "1.3.275",
"api_version": "1.4.309",
"library_arch" : "64",
"is_portability_driver": false
}
+13 -8
View File
@@ -472,18 +472,23 @@ This can be accomplished in one of two ways:
[VkConfig](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md)
tool shipped with the Vulkan SDK.
2. Directing the loader to look for layers in specific files and/or folders by using the
`VK_LAYER_PATH` environment variable.
`VK_LAYER_PATH` and/or `VK_IMPLICIT_LAYER_PATH` environment variables.
The `VK_LAYER_PATH` environment variable can contain multiple paths separated by
the operating-system specific path separator.
The `VK_LAYER_PATH` and `VK_IMPLICIT_LAYER_PATH` environment variables can contain multiple
paths separated by the operating-system specific path separator.
On Windows, this is a semicolon (`;`), while on Linux and macOS it is a colon
(`:`).
If `VK_LAYER_PATH` exists, the files and/or folders listed will be scanned for explicit
layer manifest files.
Implicit layer discovery is unaffected by this environment variable.
Each directory listed should be the full pathname of a folder containing layer
manifest files.
If `VK_IMPLICIT_LAYER_PATH` exists, the files and/or folders listed will be scanned for
implicit layer manifest files.
Explicit layer discovery is unaffected by this environment variable.
Each directory listed in `VK_LAYER_PATH` and `VK_IMPLICIT_LAYER_PATH` should be the full
pathname of a folder containing layer manifest files.
See the
[Table of Debug Environment Variables](LoaderInterfaceArchitecture.md#table-of-debug-environment-variables)
@@ -493,9 +498,9 @@ for more details.
#### Exception for Elevated Privileges
For security reasons, `VK_LAYER_PATH` is ignored if running with elevated
privileges.
Because of this, `VK_LAYER_PATH` can only be used for applications that do not
For security reasons, `VK_LAYER_PATH` and `VK_IMPLICIT_LAYER_PATH` are ignored if running
with elevated privileges.
Because of this, the environment variables can only be used for applications that do not
use elevated privileges.
For more information see
+82 -80
View File
@@ -99,57 +99,59 @@ For example, the output of the loader looking for implicit layers may look like
the following:
```
LAYER: Searching for layer manifest files
LAYER: In following locations:
LAYER: /home/${USER}/.config/vulkan/implicit_layer.d
LAYER: /etc/xdg/vulkan/implicit_layer.d
LAYER: /usr/local/etc/vulkan/implicit_layer.d
LAYER: /etc/vulkan/implicit_layer.d
LAYER: /home/${USER}/.local/share/vulkan/implicit_layer.d
LAYER: /home/${USER}/.local/share/flatpak/exports/share/vulkan/implicit_layer.d
LAYER: /var/lib/flatpak/exports/share/vulkan/implicit_layer.d
LAYER: /usr/local/share/vulkan/implicit_layer.d
LAYER: /usr/share/vulkan/implicit_layer.d
LAYER: Found the following files:
LAYER: /home/${USER}/.local/share/vulkan/implicit_layer.d/renderdoc_capture.json
LAYER: /home/${USER}/.local/share/vulkan/implicit_layer.d/steamfossilize_i386.json
LAYER: /home/${USER}/.local/share/vulkan/implicit_layer.d/steamfossilize_x86_64.json
LAYER: /home/${USER}/.local/share/vulkan/implicit_layer.d/steamoverlay_i386.json
LAYER: /home/${USER}/.local/share/vulkan/implicit_layer.d/steamoverlay_x86_64.json
LAYER: /usr/share/vulkan/implicit_layer.d/nvidia_layers.json
LAYER: /usr/share/vulkan/implicit_layer.d/VkLayer_MESA_device_select.json
[Vulkan Loader] LAYER: Searching for implicit layer manifest files
[Vulkan Loader] LAYER: In following locations:
[Vulkan Loader] LAYER: /home/${USER}/.config/vulkan/implicit_layer.d
[Vulkan Loader] LAYER: /etc/xdg/vulkan/implicit_layer.d
[Vulkan Loader] LAYER: /usr/local/etc/vulkan/implicit_layer.d
[Vulkan Loader] LAYER: /etc/vulkan/implicit_layer.d
[Vulkan Loader] LAYER: /home/${USER}/.local/share/vulkan/implicit_layer.d
[Vulkan Loader] LAYER: /home/${USER}/.local/share/flatpak/exports/share/vulkan/implicit_layer.d
[Vulkan Loader] LAYER: /var/lib/flatpak/exports/share/vulkan/implicit_layer.d
[Vulkan Loader] LAYER: /usr/local/share/vulkan/implicit_layer.d
[Vulkan Loader] LAYER: /usr/share/vulkan/implicit_layer.d
[Vulkan Loader] LAYER: Found the following files:
[Vulkan Loader] LAYER: /home/${USER}/.local/share/vulkan/implicit_layer.d/renderdoc_capture.json
[Vulkan Loader] LAYER: /home/${USER}/.local/share/vulkan/implicit_layer.d/steamfossilize_i386.json
[Vulkan Loader] LAYER: /home/${USER}/.local/share/vulkan/implicit_layer.d/steamfossilize_x86_64.json
[Vulkan Loader] LAYER: /home/${USER}/.local/share/vulkan/implicit_layer.d/steamoverlay_i386.json
[Vulkan Loader] LAYER: /home/${USER}/.local/share/vulkan/implicit_layer.d/steamoverlay_x86_64.json
[Vulkan Loader] LAYER: /usr/share/vulkan/implicit_layer.d/nvidia_layers.json
[Vulkan Loader] LAYER: /usr/share/vulkan/implicit_layer.d/VkLayer_MESA_device_select.json
```
Then, the loading of layer libraries is reported similar to this:
```
LAYER | DEBUG: Loading layer library libVkLayer_khronos_validation.so
LAYER | INFO: Insert instance layer VK_LAYER_KHRONOS_validation (libVkLayer_khronos_validation.so)
LAYER | DEBUG: Loading layer library libVkLayer_MESA_device_select.so
LAYER | INFO: Insert instance layer VK_LAYER_MESA_device_select (libVkLayer_MESA_device_select.so)
[Vulkan Loader] DEBUG | LAYER : Loading layer library libVkLayer_khronos_validation.so
[Vulkan Loader] INFO | LAYER : Insert instance layer VK_LAYER_KHRONOS_validation (libVkLayer_khronos_validation.so)
[Vulkan Loader] DEBUG | LAYER : Loading layer library libVkLayer_MESA_device_select.so
[Vulkan Loader] INFO | LAYER : Insert instance layer VK_LAYER_MESA_device_select (libVkLayer_MESA_device_select.so)
```
Finally, when the Vulkan instance is created, you can see the full instance
call-chain from a functional standpoint with output like this:
```
LAYER: vkCreateInstance layer callstack setup to:
LAYER: <Application>
LAYER: ||
LAYER: <Loader>
LAYER: ||
LAYER: VK_LAYER_MESA_device_select
LAYER: Type: Implicit
LAYER: Disable Env Var: NODEVICE_SELECT
LAYER: Manifest: /usr/share/vulkan/implicit_layer.d/VkLayer_MESA_device_select.json
LAYER: Library: libVkLayer_MESA_device_select.so
LAYER: ||
LAYER: VK_LAYER_KHRONOS_validation
LAYER: Type: Explicit
LAYER: Manifest: /usr/share/vulkan/explicit_layer.d/VkLayer_khronos_validation.json
LAYER: Library: libVkLayer_khronos_validation.so
LAYER: ||
LAYER: <Drivers>
[Vulkan Loader] LAYER: vkCreateInstance layer callstack setup to:
[Vulkan Loader] LAYER: <Application>
[Vulkan Loader] LAYER: ||
[Vulkan Loader] LAYER: <Loader>
[Vulkan Loader] LAYER: ||
[Vulkan Loader] LAYER: VK_LAYER_MESA_device_select
[Vulkan Loader] LAYER: Type: Implicit
[Vulkan Loader] LAYER: Enabled By: Implicit Layer
[Vulkan Loader] LAYER: Disable Env Var: NODEVICE_SELECT
[Vulkan Loader] LAYER: Manifest: /usr/share/vulkan/implicit_layer.d/VkLayer_MESA_device_select.json
[Vulkan Loader] LAYER: Library: libVkLayer_MESA_device_select.so
[Vulkan Loader] LAYER: ||
[Vulkan Loader] LAYER: VK_LAYER_KHRONOS_validation
[Vulkan Loader] LAYER: Type: Explicit
[Vulkan Loader] LAYER: Enabled By: By the Application
[Vulkan Loader] LAYER: Manifest: /usr/share/vulkan/explicit_layer.d/VkLayer_khronos_validation.json
[Vulkan Loader] LAYER: Library: libVkLayer_khronos_validation.so
[Vulkan Loader] LAYER: ||
[Vulkan Loader] LAYER: <Drivers>
```
In this scenario, two layers were used (the same two that were loaded earlier):
@@ -186,9 +188,9 @@ This will disable all implicit layers and the loader will report any disabled
layers to the logging output when layer logging is enabled in the following way:
```
WARNING | LAYER: Implicit layer "VK_LAYER_MESA_device_select" forced disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'.
WARNING | LAYER: Implicit layer "VK_LAYER_AMD_switchable_graphics_64" forced disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'.
WARNING | LAYER: Implicit layer "VK_LAYER_Twitch_Overlay" forced disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'.
[Vulkan Loader] WARNING | LAYER: Implicit layer "VK_LAYER_MESA_device_select" forced disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'.
[Vulkan Loader] WARNING | LAYER: Implicit layer "VK_LAYER_AMD_switchable_graphics_64" forced disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'.
[Vulkan Loader] WARNING | LAYER: Implicit layer "VK_LAYER_Twitch_Overlay" forced disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'.
```
### Selectively Re-enable Layers
@@ -283,34 +285,34 @@ look like the following (NOTE: additional spaces have been removed from the
output for easier reading):
```
DRIVER: Searching for driver manifest files
DRIVER: In following folders:
DRIVER: /home/$(USER)/.config/vulkan/icd.d
DRIVER: /etc/xdg/vulkan/icd.d
DRIVER: /etc/vulkan/icd.d
DRIVER: /home/$(USER)/.local/share/vulkan/icd.d
DRIVER: /home/$(USER)/.local/share/flatpak/exports/share/vulkan/icd.d
DRIVER: /var/lib/flatpak/exports/share/vulkan/icd.d
DRIVER: /usr/local/share/vulkan/icd.d
DRIVER: /usr/share/vulkan/icd.d
DRIVER: Found the following files:
DRIVER: /usr/share/vulkan/icd.d/intel_icd.x86_64.json
DRIVER: /usr/share/vulkan/icd.d/lvp_icd.x86_64.json
DRIVER: /usr/share/vulkan/icd.d/radeon_icd.x86_64.json
DRIVER: /usr/share/vulkan/icd.d/lvp_icd.i686.json
DRIVER: /usr/share/vulkan/icd.d/radeon_icd.i686.json
DRIVER: /usr/share/vulkan/icd.d/intel_icd.i686.json
DRIVER: /usr/share/vulkan/icd.d/nvidia_icd.json
DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/intel_icd.x86_64.json, version "1.0.0"
DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/lvp_icd.x86_64.json, version "1.0.0"
DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/radeon_icd.x86_64.json, version "1.0.0"
DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/lvp_icd.i686.json, version "1.0.0"
DRIVER: Requested driver /usr/lib/libvulkan_lvp.so was wrong bit-type. Ignoring this JSON
DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/radeon_icd.i686.json, version "1.0.0"
DRIVER: Requested driver /usr/lib/libvulkan_radeon.so was wrong bit-type. Ignoring this JSON
DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/intel_icd.i686.json, version "1.0.0"
DRIVER: Requested driver /usr/lib/libvulkan_intel.so was wrong bit-type. Ignoring this JSON
DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/nvidia_icd.json, version "1.0.0"
[Vulkan Loader] DRIVER: Searching for driver manifest files
[Vulkan Loader] DRIVER: In following folders:
[Vulkan Loader] DRIVER: /home/$(USER)/.config/vulkan/icd.d
[Vulkan Loader] DRIVER: /etc/xdg/vulkan/icd.d
[Vulkan Loader] DRIVER: /etc/vulkan/icd.d
[Vulkan Loader] DRIVER: /home/$(USER)/.local/share/vulkan/icd.d
[Vulkan Loader] DRIVER: /home/$(USER)/.local/share/flatpak/exports/share/vulkan/icd.d
[Vulkan Loader] DRIVER: /var/lib/flatpak/exports/share/vulkan/icd.d
[Vulkan Loader] DRIVER: /usr/local/share/vulkan/icd.d
[Vulkan Loader] DRIVER: /usr/share/vulkan/icd.d
[Vulkan Loader] DRIVER: Found the following files:
[Vulkan Loader] DRIVER: /usr/share/vulkan/icd.d/intel_icd.x86_64.json
[Vulkan Loader] DRIVER: /usr/share/vulkan/icd.d/lvp_icd.x86_64.json
[Vulkan Loader] DRIVER: /usr/share/vulkan/icd.d/radeon_icd.x86_64.json
[Vulkan Loader] DRIVER: /usr/share/vulkan/icd.d/lvp_icd.i686.json
[Vulkan Loader] DRIVER: /usr/share/vulkan/icd.d/radeon_icd.i686.json
[Vulkan Loader] DRIVER: /usr/share/vulkan/icd.d/intel_icd.i686.json
[Vulkan Loader] DRIVER: /usr/share/vulkan/icd.d/nvidia_icd.json
[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/intel_icd.x86_64.json, version "1.0.0"
[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/lvp_icd.x86_64.json, version "1.0.0"
[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/radeon_icd.x86_64.json, version "1.0.0"
[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/lvp_icd.i686.json, version "1.0.0"
[Vulkan Loader] DRIVER: Requested driver /usr/lib/libvulkan_lvp.so was wrong bit-type. Ignoring this JSON
[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/radeon_icd.i686.json, version "1.0.0"
[Vulkan Loader] DRIVER: Requested driver /usr/lib/libvulkan_radeon.so was wrong bit-type. Ignoring this JSON
[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/intel_icd.i686.json, version "1.0.0"
[Vulkan Loader] DRIVER: Requested driver /usr/lib/libvulkan_intel.so was wrong bit-type. Ignoring this JSON
[Vulkan Loader] DRIVER: Found ICD manifest file /usr/share/vulkan/icd.d/nvidia_icd.json, version "1.0.0"
```
Then when the application selects the device to use, you will see the Vulkan
@@ -318,13 +320,13 @@ device call chain reported in the following way (NOTE: additional spaces have
been removed from the output for easier reading):
```
DRIVER: vkCreateDevice layer callstack setup to:
DRIVER: <Application>
DRIVER: ||
DRIVER: <Loader>
DRIVER: ||
DRIVER: <Device>
DRIVER: Using "Intel(R) UHD Graphics 630 (CFL GT2)" with driver: "/usr/lib64/libvulkan_intel.so"
[Vulkan Loader] DRIVER: vkCreateDevice layer callstack setup to:
[Vulkan Loader] DRIVER: <Application>
[Vulkan Loader] DRIVER: ||
[Vulkan Loader] DRIVER: <Loader>
[Vulkan Loader] DRIVER: ||
[Vulkan Loader] DRIVER: <Device>
[Vulkan Loader] DRIVER: Using "Intel(R) UHD Graphics 630 (CFL GT2)" with driver: "/usr/lib64/libvulkan_intel.so"
```
@@ -351,8 +353,8 @@ The loader outputs messages like the following when the environment variables
are used:
```
WARNING | DRIVER: Driver "intel_icd.x86_64.json" ignored because not selected by env var 'VK_LOADER_DRIVERS_SELECT'
WARNING | DRIVER: Driver "radeon_icd.x86_64.json" ignored because it was disabled by env var 'VK_LOADER_DRIVERS_DISABLE'
[Vulkan Loader] WARNING | DRIVER: Driver "intel_icd.x86_64.json" ignored because not selected by env var 'VK_LOADER_DRIVERS_SELECT'
[Vulkan Loader] WARNING | DRIVER: Driver "radeon_icd.x86_64.json" ignored because it was disabled by env var 'VK_LOADER_DRIVERS_DISABLE'
```
For more info on how to use the filtering environment variables, refer to the
+3 -3
View File
@@ -172,7 +172,7 @@ message will show for each driver that has been ignored.
This message will look like the following:
```
WARNING | DRIVER: Driver "intel_icd.x86_64.json" ignored because not selected by env var 'VK_LOADER_DRIVERS_SELECT'
[Vulkan Loader] WARNING | DRIVER: Driver "intel_icd.x86_64.json" ignored because not selected by env var 'VK_LOADER_DRIVERS_SELECT'
```
If no drivers are found with a manifest filename that matches any of the
@@ -190,7 +190,7 @@ will show for each driver that has been forcibly disabled.
This message will look like the following:
```
WARNING | DRIVER: Driver "radeon_icd.x86_64.json" ignored because it was disabled by env var 'VK_LOADER_DRIVERS_DISABLE'
[Vulkan Loader] WARNING | DRIVER: Driver "radeon_icd.x86_64.json" ignored because it was disabled by env var 'VK_LOADER_DRIVERS_DISABLE'
```
If no drivers are found with a manifest filename that matches any of the
@@ -360,7 +360,7 @@ AppX/MSIX packages.
If a package is found, the loader will scan the root directory of this installed
package for JSON manifest files. At this time, the only package that is known is
Microsoft's
[OpenCL™ and OpenGL® Compatibility Pack](https://apps.microsoft.com/store/detail/9NQPSL29BFFF?hl=en-us&gl=US).
[OpenCL™, OpenGL®, and Vulkan® Compatibility Pack](https://apps.microsoft.com/store/detail/9NQPSL29BFFF?hl=en-us&gl=US).
The Vulkan loader will open each enabled manifest file found to obtain the name
or pathname of a driver's shared library (".DLL") file.
+58 -6
View File
@@ -202,7 +202,7 @@ These files are found in different locations based on your platform:
</tr>
<tr>
<td>Vulkan Layer Settings</td>
<td>(registry) HKEY_CURRENT_USER\Software\Khronos\Vulkan\Settings</td>
<td>(registry) HKEY_CURRENT_USER\Software\Khronos\Vulkan\LoaderSettings</td>
</tr>
<tr>
<td>VkConfig Configuration Settings</td>
@@ -430,6 +430,8 @@ These behaviors also result in ignoring certain environment variables, such as:
* `VK_ADD_DRIVER_FILES`
* `VK_LAYER_PATH`
* `VK_ADD_LAYER_PATH`
* `VK_IMPLICIT_LAYER_PATH`
* `VK_ADD_IMPLICIT_LAYER_PATH`
* `XDG_CONFIG_HOME` (Linux/Mac-specific)
* `XDG_DATA_HOME` (Linux/Mac-specific)
@@ -606,8 +608,8 @@ discovery.
</small></td>
<td><small>
Provide a list of additional paths that the loader will use to search
for layers in addition to the loader's standard Layer library search
folder when looking for explicit layer manifest files.
for explicit layers in addition to the loader's standard layer library
search paths when looking for layer manifest files.
The paths will be added first, prior to the list of folders that would
be searched normally.
</small></td>
@@ -624,6 +626,31 @@ discovery.
&nbsp;&nbsp;VK_ADD_LAYER_PATH=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;;&lt;path_b&gt;</small>
</td>
</tr>
<tr>
<td><small>
<i>VK_ADD_IMPLICIT_LAYER_PATH</i>
</small></td>
<td><small>
Provide a list of additional paths that the loader will use to search
for implicit layers in addition to the loader's standard layer library
search paths when looking for layer manifest files.
The paths will be added first, prior to the list of folders that would
be searched normally.
</small></td>
<td><small>
<a href="#elevated-privilege-caveats">
Ignored when running Vulkan application with elevated privileges.
</a>
</small></td>
<td><small>
export<br/>
&nbsp;&nbsp;VK_ADD_IMPLICIT_LAYER_PATH=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;:&lt;path_b&gt;<br/><br/>
set<br/>
&nbsp;&nbsp;VK_ADD_IMPLICIT_LAYER_PATH=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;;&lt;path_b&gt;</small>
</td>
</tr>
<tr>
<td><small>
@@ -640,7 +667,11 @@ discovery.
continue to work.
</small></td>
<td><small>
If a relative path not used, issues may be encountered.
This functionality is only available with Loaders built with version
1.3.207 of the Vulkan headers and later.<br/>
It is recommended to use absolute paths to JSON files.
Relative paths may have issues due to how the loader transforms relative library
paths into absolute ones.
<br/> <br/>
<a href="#elevated-privilege-caveats">
Ignored when running Vulkan application with elevated privileges.
@@ -661,8 +692,8 @@ discovery.
<td><small>
<i>VK_LAYER_PATH</i></small></td>
<td><small>
Override the loader's standard Layer library search folders and use the
provided delimited file and/or folders to locate explicit layer manifest files.
Override the loader's standard explicit layer search paths and use the
provided delimited files and/or folders to locate layer manifest files.
</small></td>
<td><small>
<a href="#elevated-privilege-caveats">
@@ -678,6 +709,27 @@ discovery.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;;&lt;path_b&gt;
</small></td>
</tr>
<tr>
<td><small>
<i>VK_IMPLICIT_LAYER_PATH</i></small></td>
<td><small>
Override the loader's standard implicit layer search paths and use the
provided delimited files and/or folders to locate layer manifest files.
</small></td>
<td><small>
<a href="#elevated-privilege-caveats">
Ignored when running Vulkan application with elevated privileges.
</a>
</small></td>
<td><small>
export<br/>
&nbsp;&nbsp;VK_IMPLICIT_LAYER_PATH=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;:&lt;path_b&gt;<br/><br/>
set<br/>
&nbsp;&nbsp;VK_IMPLICIT_LAYER_PATH=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;;&lt;path_b&gt;
</small></td>
</tr>
<tr>
<td><small>
<i>VK_LOADER_DEBUG</i>
+57 -18
View File
@@ -233,6 +233,13 @@ distributed as part of a driver installation.
An application installer should not modify the device-specific registries,
while a device driver should not modify the system registries.
Additionally, the Vulkan loader will scan the system for well-known Windows
AppX/MSIX packages.
If a package is found, the loader will scan the root directory of this installed
package for JSON manifest files. At this time, the only package that is known is
Microsoft's
[OpenCL™, OpenGL®, and Vulkan® Compatibility Pack](https://apps.microsoft.com/store/detail/9NQPSL29BFFF?hl=en-us&gl=US).
The Vulkan loader will open each manifest file to obtain information about the
layer, including the name or pathname of a shared library (".dll") file.
@@ -249,8 +256,18 @@ of search folders and will therefore be searched first.
If `VK_LAYER_PATH` is present, then `VK_ADD_LAYER_PATH` will not be used by the
loader and any values will be ignored.
For security reasons, both `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored
if running with elevated privileges.
If `VK_IMPLICIT_LAYER_PATH` is defined, then the loader will look at the paths
defined by that variable for implicit layer manifest files instead of using the
information provided by the implicit layer registry keys.
If `VK_ADD_IMPLICIT_LAYER_PATH` is defined, then the loader will look at the provided
paths for implicit layer manifest files in addition to using the information
provided by the implicit layer registry keys.
The paths provided by `VK_ADD_IMPLICIT_LAYER_PATH` are added before the standard list
of search folders and will therefore be searched first.
For security reasons, `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`, `VK_IMPLICIT_LAYER_PATH`,
and `VK_ADD_IMPLICIT_LAYER_PATH` are ignored if running with elevated privileges.
See [Exception for Elevated Privileges](#exception-for-elevated-privileges)
for more info.
@@ -346,8 +363,21 @@ of search folders and will therefore be searched first.
If `VK_LAYER_PATH` is present, then `VK_ADD_LAYER_PATH` will not be used by the
loader and any values will be ignored.
For security reasons, both `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored
if running with elevated privileges.
If `VK_IMPLICIT_LAYER_PATH` is defined, then the loader will look at the paths
defined by that variable for implicit layer manifest files instead of using the
information provided by the standard implicit layer paths mentioned above.
If `VK_ADD_IMPLICIT_LAYER_PATH` is defined, then the loader will look at the
provided paths for implicit layer manifest files in addition to using the
information provided by the standard implicit layer paths mentioned above.
The paths provided by `VK_ADD_IMPLICIT_LAYER_PATH` are added before the standard
list of search folders and will therefore be searched first.
If `VK_IMPLICIT_LAYER_PATH` is present, then `VK_ADD_IMPLICIT_LAYER_PATH` will
not be used by the loader and any values will be ignored.
For security reasons, `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`, `VK_IMPLICIT_LAYER_PATH`,
and `VK_ADD_IMPLICIT_LAYER_PATH` are ignored if running with elevated privileges.
See [Exception for Elevated Privileges](#exception-for-elevated-privileges)
for more info.
@@ -360,10 +390,10 @@ See
in the [LoaderApplicationInterface.md document](LoaderApplicationInterface.md)
for more information on this.
It is also important to note that while both `VK_LAYER_PATH` and
`VK_ADD_LAYER_PATH` will point the loader paths to search for finding the
manifest files, it does not guarantee the library files mentioned by the
manifest will immediately be found.
It is also important to note that while `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`,
`VK_IMPLICIT_LAYER_PATH`, and `VK_ADD_IMPLICIT_LAYER_PATH` will point the
loader at paths to search for finding the manifest files, it does not guarantee
the library files mentioned by the manifest will immediately be found.
Often, the layer manifest file will point to the library file using a relative
or absolute path.
When a relative or absolute path is used, the loader can typically find the
@@ -431,8 +461,8 @@ following:
The loader supports filter environment variables which can forcibly enable and
disable known layers.
Known layers are those that are already found by the loader taking into account
default search paths and other environment variables
(like `VK_LAYER_PATH` or `VK_ADD_LAYER_PATH`).
default search paths and environment variables `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`,
`VK_IMPLICIT_LAYER_PATH`, and `VK_ADD_IMPLICIT_LAYER_PATH`.
The filter variables will be compared against the layer name provided in the
layer's manifest file.
@@ -456,7 +486,7 @@ will show for each layer that has been forced on.
This message will look like the following:
```
WARNING | LAYER: Layer "VK_LAYER_LUNARG_wrap_objects" force enabled due to env var 'VK_LOADER_LAYERS_ENABLE'
[Vulkan Loader] WARNING | LAYER: Layer "VK_LAYER_LUNARG_wrap_objects" force enabled due to env var 'VK_LOADER_LAYERS_ENABLE'
```
#### Layer Disable Filtering
@@ -478,7 +508,7 @@ will show for each layer that has been forcibly disabled.
This message will look like the following:
```
WARNING | LAYER: Layer "VK_LAYER_LUNARG_wrap_objects" disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'
[Vulkan Loader] WARNING | LAYER: Layer "VK_LAYER_LUNARG_wrap_objects" disabled because name matches filter of env var 'VK_LOADER_LAYERS_DISABLE'
```
#### Layer Special Case Disable
@@ -541,8 +571,9 @@ override any disables supplied in `VK_LOADER_LAYERS_DISABLE`.
### Exception for Elevated Privileges
For security reasons, `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored if
running the Vulkan application with elevated privileges.
For security reasons, `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`, `VK_IMPLICIT_LAYER_PATH`
and `VK_ADD_IMPLICIT_LAYER_PATH` are ignored if running the Vulkan application
with elevated privileges.
This is because they may insert new libraries into the executable process that
are not normally found by the loader.
Because of this, these environment variables can only be used for applications
@@ -979,7 +1010,15 @@ ignore `instance` when `pName` is `vkCreateDevice`.
- The specification **requires** `NULL` to be returned from
`vkGetInstanceProcAddr` and `vkGetDeviceProcAddr` for disabled functions.
- A layer may return `NULL` itself or rely on the following layers to do so.
- A layer's implementation `vkGetInstanceProcAddr` **should**, when querying for
`vkCreateInstance`, return a valid function pointer regardless of the value of the
`instance` parameter.
- The specification **requires** that the `instance` parameter **must** be NULL.
However, older versions of the specification did not have this requirement, allowing
for non-NULL `instance` handles to be passed in and return a valid `vkCreateInstance`
function pointer. The Vulkan-Loader itself does this and will continue to do so to
maintain compatibility with layers which were released before this specification
change was made.
## Layer Dispatch Initialization
@@ -2681,9 +2720,9 @@ Android Vulkan documentation</a>.
<tr>
<td><small><b>LLP_LOADER_13</b></small></td>
<td>A loader <b>must</b> not load from user-defined paths (including the
use of either <i>VK_LAYER_PATH</i> or <i>VK_ADD_LAYER_PATH</i>
environment variables) when running elevated (Administrator/Super-user)
applications.<br/>
use of <i>VK_LAYER_PATH</i>, <i>VK_ADD_LAYER_PATH</i>, <i>VK_IMPLICIT_LAYER_PATH</i>,
or <i>VK_ADD_IMPLICIT_LAYER_PATH</i> environment variables) when running
elevated (Administrator/Super-user) applications.<br/>
<b>This is for security reasons.</b>
</td>
<td>The behavior is undefined and may result in computer security lapses,
View File

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

View File

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 148 KiB

View File

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 164 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

View File

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View File

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

+143 -84
View File
@@ -31,18 +31,6 @@ if(WIN32)
set(CMAKE_C_STANDARD_LIBRARIES " ") # space is intentional
endif()
# ~~~
# Build dev_ext_trampoline.c and unknown_ext_chain.c with /O2 to allow tail-call optimization.
# Setup two CMake targets (loader-norm and loader-opt) for the different compilation flags.
# ~~~
set(MODIFIED_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
string(REPLACE "/Od" "/O2" MODIFIED_C_FLAGS_DEBUG ${MODIFIED_C_FLAGS_DEBUG})
string(REPLACE "/Ob0" "/Ob2" MODIFIED_C_FLAGS_DEBUG ${MODIFIED_C_FLAGS_DEBUG})
string(REGEX REPLACE "/RTC." "" MODIFIED_C_FLAGS_DEBUG ${MODIFIED_C_FLAGS_DEBUG}) #remove run-time error checks
separate_arguments(MODIFIED_C_FLAGS_DEBUG WINDOWS_COMMAND ${MODIFIED_C_FLAGS_DEBUG})
# ~~~
# Only generate the loader.rc file with CMake if BUILD_DLL_VERSIONINFO was set.
# This feature is for the Vulkan Runtime build
@@ -72,6 +60,9 @@ else()
if(HAVE_ALLOCA_H)
target_compile_definitions(loader_specific_options INTERFACE HAVE_ALLOCA_H)
endif()
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
endif()
set(NORMAL_LOADER_SRCS
@@ -91,6 +82,8 @@ set(NORMAL_LOADER_SRCS
loader.h
log.c
log.h
loader_json.c
loader_json.h
settings.c
settings.h
terminator.c
@@ -118,15 +111,13 @@ endif()
set(OPT_LOADER_SRCS dev_ext_trampoline.c phys_dev_ext.c)
# Check for assembler support
set(ASM_FAILURE_MSG "The build will fall back on building with C code\n")
set(ASM_FAILURE_MSG "${ASM_FAILURE_MSG}Note that this may be unsafe, as the C code requires tail-call optimizations to remove")
set(ASM_FAILURE_MSG "${ASM_FAILURE_MSG} the stack frame for certain calls. If the compiler does not do this, then unknown device")
set(ASM_FAILURE_MSG "${ASM_FAILURE_MSG} extensions will suffer from a corrupted stack.")
set(ASM_FAILURE_MSG "Support for unknown physical device and device functions is disabled due to missing the required assembly support code. \
To support unknown functions, assembly must be added for the platform.\n")
set(ARMASM_CMAKE_FAILURE_MSG "Support for unknown physical device and device functions is disabled due to the CMake version ${CMAKE_VERSION} \
being older than 3.26. Please update CMake to version 3.26 or newer.\n")
if (APPLE_UNIVERSAL_BINARY)
set(USE_ASSEMBLY_FALLBACK ON)
elseif(WIN32)
# Check for assembler support
if(WIN32 AND NOT USE_GAS)
option(USE_MASM "Use MASM" ON)
if(USE_MASM AND MINGW)
find_program(JWASM_FOUND NAMES jwasm uasm)
@@ -144,12 +135,42 @@ elseif(WIN32)
endif()
endif()
if (USE_MASM)
enable_language(ASM_MASM)
if(SYSTEM_PROCESSOR MATCHES "arm")
if(CMAKE_VERSION VERSION_LESS "3.26.0")
set(ASM_FAILURE_MSG ${ARMASM_CMAKE_FAILURE_MSG})
else()
enable_language(ASM_MARMASM)
set(LOADER_ASM_DIALECT "MARMASM")
endif()
else()
enable_language(ASM_MASM)
set(LOADER_ASM_DIALECT "MASM")
endif()
endif()
# Test if the detected compiler actually works.
# Unfortunately, CMake's detection of ASM_MASM is not reliable, so we need to do this ourselves.
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm [=[
if(SYSTEM_PROCESSOR MATCHES "arm")
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm [=[
test_func FUNCTION
mov r0, #0
bx lr
ENDFUNC
END
]=])
else()
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm [=[
test_func FUNCTION
mov x1, 26
ldr x0, [x0, x1]
ENDFUNC
END
]=])
endif()
else()
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm [=[
.model flat
.code
extrn _start:near
@@ -157,36 +178,48 @@ extrn _start:near
ret
end
]=])
else()
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm [=[
else()
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm [=[
.code
extrn start:near
xor rax, rax
ret
end
]=])
endif()
endif ()
if(MINGW)
set(CMAKE_ASM_MASM_FLAGS ${CMAKE_ASM_MASM_FLAGS} ${JWASM_FLAGS})
elseif(NOT CMAKE_CL_64 AND NOT JWASM_FOUND)
set(CMAKE_ASM_MASM_FLAGS ${CMAKE_ASM_MASM_FLAGS} /safeseh)
set(CMAKE_ASM_MARMASM_FLAGS ${CMAKE_ASM_MARMASM_FLAGS} ${JWASM_FLAGS})
elseif(NOT CMAKE_CL_64 AND NOT JWASM_FOUND AND CMAKE_SIZEOF_VOID_P EQUAL 4)
set(CMAKE_ASM_MASM_FLAGS ${CMAKE_ASM_MASM_FLAGS} /safeseh) # /safeseh is only needed in x86
endif()
# try_compile does not work here due to the same reasons as static above.
execute_process(COMMAND ${CMAKE_ASM_MASM_COMPILER} ${CMAKE_ASM_MASM_FLAGS} -c -Fo ${CMAKE_CURRENT_BINARY_DIR}/masm_check.obj ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm
RESULT_VARIABLE CMAKE_ASM_MASM_COMPILER_WORKS
OUTPUT_QUIET ERROR_QUIET)
# Convert the return code to a boolean
if(CMAKE_ASM_MASM_COMPILER_WORKS EQUAL 0)
set(CMAKE_ASM_MASM_COMPILER_WORKS true)
if(SYSTEM_PROCESSOR MATCHES "arm")
execute_process(COMMAND ${CMAKE_ASM_MARMASM_COMPILER} ${CMAKE_ASM_MARMASM_FLAGS} ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm
RESULT_VARIABLE ASM_COMPILER_WORKS
OUTPUT_QUIET ERROR_QUIET)
else()
set(CMAKE_ASM_MASM_COMPILER_WORKS false)
execute_process(COMMAND ${CMAKE_ASM_MASM_COMPILER} ${CMAKE_ASM_MASM_FLAGS} -c -Fo ${CMAKE_CURRENT_BINARY_DIR}/masm_check.obj ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm
RESULT_VARIABLE ASM_COMPILER_WORKS
OUTPUT_QUIET ERROR_QUIET)
endif()
if(CMAKE_ASM_MASM_COMPILER_WORKS)
# Convert the return code to a boolean
if(ASM_COMPILER_WORKS EQUAL 0)
set(ASM_COMPILER_WORKS true)
else()
set(ASM_COMPILER_WORKS false)
endif()
if(ASM_COMPILER_WORKS)
add_executable(asm_offset asm_offset.c)
target_link_libraries(asm_offset PRIVATE loader_specific_options)
# If am emulator is provided (Like Wine), or running on native, run asm_offset to generate gen_defines.asm
if (CMAKE_CROSSCOMPILING_EMULATOR OR NOT CMAKE_CROSSCOMPILING)
add_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset MASM)
add_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset ${LOADER_ASM_DIALECT})
else()
# Forces compiler to write the intermediate asm file, needed so that we can get sizeof/offset of info out of it.
target_compile_options(asm_offset PRIVATE "/Fa$<TARGET_FILE_DIR:asm_offset>/asm_offset.asm" /FA)
@@ -197,22 +230,23 @@ end
# Run parse_asm_values.py on asm_offset's assembly file to generate the gen_defines.asm, which the asm code depends on
add_custom_command(TARGET asm_offset POST_BUILD
COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/scripts/parse_asm_values.py "${CMAKE_CURRENT_BINARY_DIR}/gen_defines.asm"
"$<TARGET_FILE_DIR:asm_offset>/asm_offset.asm" "MASM" "${CMAKE_C_COMPILER_ID}" "${CMAKE_SYSTEM_PROCESSOR}"
"$<TARGET_FILE_DIR:asm_offset>/asm_offset.asm" "${LOADER_ASM_DIALECT}" "${CMAKE_C_COMPILER_ID}" "${SYSTEM_PROCESSOR}"
BYPRODUCTS gen_defines.asm
)
endif()
add_custom_target(loader_asm_gen_files DEPENDS gen_defines.asm)
set_target_properties(loader_asm_gen_files PROPERTIES FOLDER ${LOADER_HELPER_FOLDER})
add_library(loader-unknown-chain OBJECT unknown_ext_chain_masm.asm)
target_link_libraries(loader-unknown-chain Vulkan::Headers)
target_include_directories(loader-unknown-chain PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
add_dependencies(loader-unknown-chain loader_asm_gen_files)
if(SYSTEM_PROCESSOR MATCHES "arm")
list(APPEND OPT_LOADER_SRCS unknown_ext_chain_marmasm.asm)
else()
list(APPEND OPT_LOADER_SRCS unknown_ext_chain_masm.asm)
endif()
set(UNKNOWN_FUNCTIONS_SUPPORTED ON)
else()
set(USE_ASSEMBLY_FALLBACK ON)
message(WARNING "Could not find working MASM assembler\n${ASM_FAILURE_MSG}")
message(WARNING "Could not find working ${} assembler\n${ASM_FAILURE_MSG}")
endif()
elseif(UNIX) # i.e.: Linux & Apple
elseif(UNIX OR MINGW OR (WIN32 AND USE_GAS)) # i.e.: Linux & Apple & MinGW & Windows using Clang-CL
option(USE_GAS "Use GAS" ON)
if(USE_GAS)
@@ -225,13 +259,31 @@ elseif(UNIX) # i.e.: Linux & Apple
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64|arm64")
try_compile(ASSEMBLER_WORKS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/asm_test_aarch64.S)
if(WIN32 AND ${SYSTEM_PROCESSOR} MATCHES "arm64")
# In this particular case, we are using the same approach as for NASM
# This specifically avoids CMake issue #18889
execute_process(COMMAND ${CMAKE_ASM_COMPILER} ${CMAKE_ASM_FLAGS} -c -o ${CMAKE_CURRENT_BINARY_DIR}/asm_test_aarch64.obj ${CMAKE_CURRENT_SOURCE_DIR}/asm_test_aarch64.S
RESULT_VARIABLE WIN_ARM64_ASSEMBLER_WORKS
OUTPUT_QUIET ERROR_QUIET)
if(WIN_ARM64_ASSEMBLER_WORKS EQUAL 0)
set(ASSEMBLER_WORKS true)
endif()
if(ASSEMBLER_WORKS)
set(OPT_LOADER_SRCS ${OPT_LOADER_SRCS} unknown_ext_chain_gas_aarch64.S)
list(APPEND OPT_LOADER_SRCS unknown_ext_chain_gas_aarch.S)
endif()
elseif (${SYSTEM_PROCESSOR} MATCHES "aarch64|arm64")
try_compile(ASSEMBLER_WORKS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/asm_test_aarch64.S OUTPUT_VARIABLE TRY_COMPILE_OUTPUT)
if(ASSEMBLER_WORKS)
list(APPEND OPT_LOADER_SRCS unknown_ext_chain_gas_aarch.S)
endif()
elseif (${SYSTEM_PROCESSOR} MATCHES "aarch32|armhf|armv7l|armv8l")
try_compile(ASSEMBLER_WORKS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/asm_test_aarch32.S OUTPUT_VARIABLE TRY_COMPILE_OUTPUT)
if(ASSEMBLER_WORKS)
list(APPEND OPT_LOADER_SRCS unknown_ext_chain_gas_aarch.S)
endif()
# Covers x86_64, amd64, x86, i386, i686, I386, I686
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "amd64|86")
elseif(${SYSTEM_PROCESSOR} MATCHES "amd64|86")
check_include_file("cet.h" HAVE_CET_H)
if(HAVE_CET_H)
target_compile_definitions(loader_specific_options INTERFACE HAVE_CET_H)
@@ -239,18 +291,22 @@ elseif(UNIX) # i.e.: Linux & Apple
try_compile(ASSEMBLER_WORKS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/asm_test_x86.S)
if(ASSEMBLER_WORKS)
set(OPT_LOADER_SRCS ${OPT_LOADER_SRCS} unknown_ext_chain_gas_x86.S)
list(APPEND OPT_LOADER_SRCS unknown_ext_chain_gas_x86.S)
endif()
endif()
endif()
# When compiling for x86 on x64, we can't use CMAKE_SYSTEM_PROCESSOR to determine which architecture to use,
# Instead, check the size of void* and if its 4, set ASM_OFFSET_SYSTEM_PROCESSOR to x86
# Note - there is no 32 bit arm assembly code, so this only applies to x86 currently.
# Instead, check the size of void* and if its 4, set ASM_OFFSET_SYSTEM_PROCESSOR to x86 if we aren't on arm
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(ASM_OFFSET_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}) # x86_64 or aarch64/arm64
set(ASM_OFFSET_SYSTEM_PROCESSOR ${SYSTEM_PROCESSOR}) # x86_64 or aarch64/arm64
string(REPLACE amd64 x86_64 ASM_OFFSET_SYSTEM_PROCESSOR "${ASM_OFFSET_SYSTEM_PROCESSOR}")
else()
set(ASM_OFFSET_SYSTEM_PROCESSOR "x86")
if(${SYSTEM_PROCESSOR} MATCHES "86")
set(ASM_OFFSET_SYSTEM_PROCESSOR "x86")
else()
set(ASM_OFFSET_SYSTEM_PROCESSOR ${SYSTEM_PROCESSOR})
endif()
endif()
if(ASSEMBLER_WORKS)
@@ -261,7 +317,14 @@ elseif(UNIX) # i.e.: Linux & Apple
add_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset GAS)
else()
# Forces compiler to write the intermediate asm file, needed so that we can get sizeof/offset of info out of it.
target_compile_options(asm_offset PRIVATE -save-temps=obj)
# If with lto, compiler will output IR instead of asm, so we need to explicitly disable lto here.
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_compile_options(asm_offset PRIVATE -save-temps=obj -fno-lto)
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
target_compile_options(asm_offset PRIVATE -save-temps=obj -fno-lto -fno-whole-program-vtables -fno-virtual-function-elimination)
else()
target_compile_options(asm_offset PRIVATE -save-temps=obj)
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
set(ASM_OFFSET_EXECUTABLE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/gen_defines.asm")
set(ASM_OFFSET_INTERMEDIATE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/CMakeFiles/asm_offset.dir/asm_offset.c.s")
@@ -275,6 +338,7 @@ elseif(UNIX) # i.e.: Linux & Apple
else()
message(FATAL_ERROR "C_COMPILER_ID not supported!")
endif()
message(STATUS "CMAKE_CROSSCOMPILING FALSE")
find_package(Python3 REQUIRED QUIET)
# Run parse_asm_values.py on asm_offset's assembly file to generate the gen_defines.asm, which the asm code depends on
@@ -289,8 +353,8 @@ elseif(UNIX) # i.e.: Linux & Apple
if (APPLE)
set(MODIFY_UNKNOWN_FUNCTION_DECLS ON)
endif()
set(UNKNOWN_FUNCTIONS_SUPPORTED ON)
else()
set(USE_ASSEMBLY_FALLBACK ON)
if(USE_GAS)
message(WARNING "Could not find working ${ASM_OFFSET_SYSTEM_PROCESSOR} GAS assembler\n${ASM_FAILURE_MSG}")
else()
@@ -299,40 +363,24 @@ elseif(UNIX) # i.e.: Linux & Apple
endif()
endif()
if(USE_ASSEMBLY_FALLBACK)
add_custom_target(loader_asm_gen_files)
if (MSVC)
add_library(loader-unknown-chain OBJECT unknown_ext_chain.c)
target_link_libraries(loader-unknown-chain loader_specific_options)
set_target_properties(loader-unknown-chain PROPERTIES CMAKE_C_FLAGS_DEBUG "${MODIFIED_C_FLAGS_DEBUG}")
else()
set(OPT_LOADER_SRCS ${OPT_LOADER_SRCS} unknown_ext_chain.c)
set_source_files_properties(${OPT_LOADER_SRCS} PROPERTIES COMPILE_FLAGS -O)
endif()
if(UNKNOWN_FUNCTIONS_SUPPORTED)
list(APPEND NORMAL_LOADER_SRCS ${OPT_LOADER_SRCS})
endif()
if(WIN32)
add_library(loader-opt STATIC ${OPT_LOADER_SRCS})
target_link_libraries(loader-opt PUBLIC loader_specific_options)
add_dependencies(loader-opt loader_asm_gen_files)
set_target_properties(loader-opt PROPERTIES CMAKE_C_FLAGS_DEBUG "${MODIFIED_C_FLAGS_DEBUG}")
# If BUILD_DLL_VERSIONINFO was set, use the loader.rc in the build dir, otherwise use the checked in file
set(RC_FILE_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/loader.rc)
if (NOT "$CACHE{BUILD_DLL_VERSIONINFO}" STREQUAL "")
set(RC_FILE_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/loader.rc)
endif()
set(LOADER_UNKNOWN_CHAIN_LIBRARY $<$<TARGET_EXISTS:loader-unknown-chain>:$<TARGET_OBJECTS:loader-unknown-chain>>)
add_library(vulkan
SHARED
${NORMAL_LOADER_SRCS}
${LOADER_UNKNOWN_CHAIN_LIBRARY}
${CMAKE_CURRENT_SOURCE_DIR}/${API_TYPE}-1.def
${RC_FILE_LOCATION})
target_link_libraries(vulkan PRIVATE loader_specific_options loader-opt)
target_link_libraries(vulkan PRIVATE loader_specific_options)
# when adding the suffix the import and runtime library names must be consistent
# mingw: libvulkan-1.dll.a / vulkan-1.dll
@@ -354,8 +402,6 @@ if(WIN32)
target_link_libraries(vulkan PRIVATE cfgmgr32)
endif()
add_dependencies(vulkan loader_asm_gen_files)
else()
if(APPLE)
option(APPLE_STATIC_LOADER "Build a loader that can be statically linked. Intended for Chromium usage/testing.")
@@ -372,18 +418,13 @@ else()
add_library(vulkan SHARED)
endif()
target_sources(vulkan PRIVATE ${NORMAL_LOADER_SRCS} ${OPT_LOADER_SRCS})
add_dependencies(vulkan loader_asm_gen_files)
target_sources(vulkan PRIVATE ${NORMAL_LOADER_SRCS})
set_target_properties(vulkan PROPERTIES
SOVERSION "1"
VERSION "${VULKAN_LOADER_VERSION}"
)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(vulkan PRIVATE ${CMAKE_DL_LIBS} m Threads::Threads)
set_target_properties(vulkan PROPERTIES OUTPUT_NAME ${API_TYPE})
@@ -412,9 +453,12 @@ else()
file(GLOB_RECURSE CONFIGURE_DEPENDS FRAMEWORK_HEADERS ${VulkanHeaders_INCLUDE_DIRS})
add_library(vulkan-framework SHARED)
target_sources(vulkan-framework PRIVATE ${NORMAL_LOADER_SRCS} ${OPT_LOADER_SRCS} ${FRAMEWORK_HEADERS})
target_sources(vulkan-framework PRIVATE ${NORMAL_LOADER_SRCS} ${FRAMEWORK_HEADERS})
if (UNKNOWN_FUNCTIONS_SUPPORTED)
add_dependencies(vulkan-framework loader_asm_gen_files)
endif()
add_dependencies(vulkan-framework loader_asm_gen_files)
target_link_libraries(vulkan-framework ${CMAKE_DL_LIBS} Threads::Threads -lm "-framework CoreFoundation")
target_link_libraries(vulkan-framework loader_specific_options)
@@ -435,6 +479,8 @@ else()
FRAMEWORK TRUE
FRAMEWORK_VERSION A
VERSION "${VULKAN_LOADER_VERSION}"
MACOSX_FRAMEWORK_BUNDLE_VERSION "${VULKAN_LOADER_VERSION}"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${VULKAN_LOADER_VERSION}"
SOVERSION "1.0.0"
MACOSX_FRAMEWORK_IDENTIFIER com.lunarg.vulkanFramework
PUBLIC_HEADER "${FRAMEWORK_HEADERS}"
@@ -466,6 +512,15 @@ target_link_libraries(vulkan PRIVATE loader_specific_options)
target_link_libraries(vulkan PRIVATE Vulkan::Headers)
add_library(Vulkan::Loader ALIAS vulkan)
if (UNKNOWN_FUNCTIONS_SUPPORTED)
target_compile_definitions(vulkan PRIVATE UNKNOWN_FUNCTIONS_SUPPORTED)
add_dependencies(vulkan loader_asm_gen_files)
endif()
if (BUILD_TESTS)
target_compile_definitions(vulkan PRIVATE SHOULD_EXPORT_TEST_FUNCTIONS)
endif()
if (APPLE_STATIC_LOADER)
# TLDR: This feature only exists at the request of Google for Chromium. No other project should use this!
message(NOTICE "Apple STATIC lib: it will be built but not installed, and vulkan.pc and VulkanLoaderConfig.cmake won't be generated!")
@@ -511,3 +566,7 @@ if (PKG_CONFIG_FOUND)
configure_file("vulkan.pc.in" "vulkan.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/vulkan.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" RENAME "${API_TYPE}.pc")
endif()
if (CODE_COVERAGE)
target_code_coverage(vulkan AUTO ALL)
endif()
+1 -1
View File
@@ -15,5 +15,5 @@
This document has been renamed to
[LoaderInterfaceArchitecture.md](../docs/LoaderInterfaceArchitecture.md) and can be
found in the top-level docs folder of the Loader GitHb repo.
found in the top-level docs folder of the Loader GitHub repo.
Please refer to that document going forward.
+4
View File
@@ -98,6 +98,10 @@ void *loader_realloc(const VkAllocationCallbacks *pAllocator, void *pMemory, siz
#endif
} else {
pNewMem = realloc(pMemory, size);
// Clear out the newly allocated memory
if (size > orig_size) {
memset((uint8_t *)pNewMem + orig_size, 0, size - orig_size);
}
}
return pNewMem;
}
-1
View File
@@ -29,7 +29,6 @@
#pragma once
#include "loader_common.h"
#include "stack_allocation.h"
void *loader_instance_heap_alloc(const struct loader_instance *instance, size_t size, VkSystemAllocationScope allocation_scope);
void *loader_instance_heap_calloc(const struct loader_instance *instance, size_t size, VkSystemAllocationScope allocation_scope);
+36 -12
View File
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2017-2021 The Khronos Group Inc.
* Copyright (c) 2017-2021 Valve Corporation
* Copyright (c) 2017-2021 LunarG, Inc.
* Copyright (c) 2017-2024 The Khronos Group Inc.
* Copyright (c) 2017-2024 Valve Corporation
* Copyright (c) 2017-2024 LunarG, Inc.
* Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -78,19 +78,28 @@ struct ValueInfo {
const char *comment;
};
enum Assembler {
UNKNOWN = 0,
MASM = 1,
MARMASM = 2,
GAS = 3,
};
// This file can both be executed to produce gen_defines.asm and contains all the relevant data which
// the parse_asm_values.py script needs to write gen_defines.asm, necessary for cross compilation
int main(int argc, char **argv) {
const char *assembler = NULL;
enum Assembler assembler = UNKNOWN;
for (int i = 0; i < argc; ++i) {
if (!strcmp(argv[i], "MASM")) {
assembler = "MASM";
assembler = MASM;
} else if (!strcmp(argv[i], "MARMASM")) {
assembler = MARMASM;
} else if (!strcmp(argv[i], "GAS")) {
assembler = "GAS";
assembler = GAS;
}
}
if (assembler == NULL) {
return 1;
if (assembler == UNKNOWN) {
return -1;
}
struct ValueInfo values[] = {
@@ -98,7 +107,7 @@ int main(int argc, char **argv) {
{ .name = "VULKAN_LOADER_ERROR_BIT", .value = (size_t) VULKAN_LOADER_ERROR_BIT,
.comment = "The numerical value of the enum value 'VULKAN_LOADER_ERROR_BIT'" },
{ .name = "PTR_SIZE", .value = sizeof(void*),
.comment = "The size of a pointer" },
.comment = "The size of a pointer" },
{ .name = "CHAR_PTR_SIZE", .value = sizeof(char *),
.comment = "The size of a 'const char *' struct" },
{ .name = "FUNCTION_OFFSET_INSTANCE", .value = offsetof(struct loader_instance, phys_dev_ext_disp_functions),
@@ -122,19 +131,34 @@ int main(int argc, char **argv) {
FILE *file = loader_fopen("gen_defines.asm", "w");
fprintf(file, "\n");
if (!strcmp(assembler, "MASM")) {
if (assembler == MASM) {
for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) {
fprintf(file, "%-32s equ " SIZE_T_FMT "; %s\n", values[i].name, values[i].value, values[i].comment);
}
} else if (!strcmp(assembler, "GAS")) {
} else if (assembler == MARMASM) {
fprintf(file, " AREA loader_structs_details, DATA,READONLY\n");
#if defined(__aarch64__) || defined(_M_ARM64)
fprintf(file, "AARCH_64 EQU 1\n");
#else
fprintf(file, "AARCH_64 EQU 0\n");
#endif
for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) {
fprintf(file, "%-32s EQU " SIZE_T_FMT "; %s\n", values[i].name, values[i].value, values[i].comment);
}
fprintf(file, " END\n");
} else if (assembler == GAS) {
#if defined(__x86_64__) || defined(__i386__)
const char *comment_delimiter = "#";
#if defined(__x86_64__)
fprintf(file, ".set X86_64, 1\n");
#endif // defined(__x86_64__)
#elif defined(__aarch64__)
#elif defined(__aarch64__) || defined(__arm__)
const char *comment_delimiter = "//";
#if defined(__aarch64__)
fprintf(file, ".set AARCH_64, 1\n");
#else
fprintf(file, ".set AARCH_64, 0\n");
#endif
#else
// Default comment delimiter
const char *comment_delimiter = "#";
+25
View File
@@ -0,0 +1,25 @@
//
// Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// Copyright (c) 2024 Valve Corporation
// Copyright (c) 2024 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.
//
.text
.global sample
.set PHYS_DEV_OFFSET_INST_DISPATCH, 10
.set PTR_SIZE, 4
sample:
mov r1, #(PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * 4))
ldr r0, [r0, r1]
+1621 -928
View File
File diff suppressed because it is too large Load Diff
+174 -65
View File
@@ -1,8 +1,5 @@
/*
Copyright (c) 2009 Dave Gamble
Copyright (c) 2015-2021 The Khronos Group Inc.
Copyright (c) 2015-2021 Valve Corporation
Copyright (c) 2015-2021 LunarG, Inc.
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -23,89 +20,201 @@
THE SOFTWARE.
*/
#pragma once
#ifndef cJSON__h
#define cJSON__h
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <vulkan/vulkan_core.h>
#define CJSON_HIDE_SYMBOLS
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project
with a different default calling convention. For windows you have 3 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
#define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type CJSON_STDCALL
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
#endif
#else /* !__WINDOWS__ */
#define CJSON_CDECL
#define CJSON_STDCALL
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 18
#include <stddef.h>
#include <stdbool.h>
#include "vk_loader_platform.h"
/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* loader type declarations for allocation hooks */
typedef struct VkAllocationCallbacks VkAllocationCallbacks;
struct loader_instance;
/* The cJSON structure: */
typedef struct cJSON {
struct cJSON *next, *prev; /* next/prev allow you to walk array/object
chains. Alternatively, use
GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer
pointing to a chain of the items in the
array/object. */
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
int type; /* The type of the item, as above. */
/* The type of the item, as above. */
int type;
char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
char *string; /* The item's name string, if this item is the child of, or is
in the list of subitems of an object. */
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
/* pointer to the allocation callbacks to use */
VkAllocationCallbacks *pAllocator;
const VkAllocationCallbacks *pAllocator;
} cJSON;
/* Render a cJSON entity to text for transfer/storage. Free the char* when
* finished. */
char *loader_cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting.
* Free the char* when finished. */
char *loader_cJSON_PrintUnformatted(cJSON *item);
typedef int cJSON_bool;
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
/* Limits the length of circular references can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_CIRCULAR_LIMIT
#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
* loader_cJSON_Delete) and loader_loader_cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The
* exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) loader_cJSON_Parse(const VkAllocationCallbacks *pAllocator, const char *value, bool *out_of_memory);
CJSON_PUBLIC(cJSON *)
loader_cJSON_ParseWithLength(const VkAllocationCallbacks *pAllocator, const char *value, size_t buffer_length, bool *out_of_memory);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte
* parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will
* match cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *)
loader_cJSON_ParseWithOpts(const VkAllocationCallbacks *pAllocator, const char *value, const char **return_parse_end,
cJSON_bool require_null_terminated, bool *out_of_memory);
CJSON_PUBLIC(cJSON *)
loader_cJSON_ParseWithLengthOpts(const VkAllocationCallbacks *pAllocator, const char *value, size_t buffer_length,
const char **return_parse_end, cJSON_bool require_null_terminated, bool *out_of_memory);
/* Render a cJSON entity to text for transfer/storage. */
TEST_FUNCTION_EXPORT CJSON_PUBLIC(char *) loader_cJSON_Print(const cJSON *item, bool *out_of_memory);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) loader_cJSON_PrintUnformatted(const cJSON *item, bool *out_of_memory);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces
* reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char *)
loader_cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt, bool *out_of_memory);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on
* failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you
* actually need */
CJSON_PUBLIC(cJSON_bool)
loader_cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */
void loader_cJSON_Delete(cJSON *c);
TEST_FUNCTION_EXPORT CJSON_PUBLIC(void) loader_cJSON_Delete(cJSON *item);
/* Returns the number of items in an array (or object). */
int loader_cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful.
*/
cJSON *loader_cJSON_GetArrayItem(cJSON *array, int item);
CJSON_PUBLIC(int) loader_cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) loader_cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */
cJSON *loader_cJSON_GetObjectItem(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) loader_cJSON_GetObjectItem(const cJSON *const object, const char *const string);
CJSON_PUBLIC(cJSON *) loader_cJSON_GetObjectItemCaseSensitive(const cJSON *const object, const char *const string);
CJSON_PUBLIC(cJSON_bool) loader_cJSON_HasObjectItem(const cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make
* sense of it. Defined when loader_cJSON_Parse() returns 0. 0 when loader_cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* When assigning an integer value, it needs to be propagated to valuedouble
* too. */
#define cJSON_SetIntValue(object, val) ((object) ? (object)->valueint = (object)->valuedouble = (val) : (val))
#define cJSON_SetNumberValue(object, val) ((object) ? (object)->valueint = (object)->valuedouble = (val) : (val))
/* Check item type and return its value */
CJSON_PUBLIC(char *) loader_cJSON_GetStringValue(const cJSON *const item);
CJSON_PUBLIC(double) loader_cJSON_GetNumberValue(const cJSON *const item);
// Helper functions to using JSON
/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) loader_cJSON_IsInvalid(const cJSON *const item);
CJSON_PUBLIC(cJSON_bool) loader_cJSON_IsFalse(const cJSON *const item);
CJSON_PUBLIC(cJSON_bool) loader_cJSON_IsTrue(const cJSON *const item);
CJSON_PUBLIC(cJSON_bool) loader_cJSON_IsBool(const cJSON *const item);
CJSON_PUBLIC(cJSON_bool) loader_cJSON_IsNull(const cJSON *const item);
CJSON_PUBLIC(cJSON_bool) loader_cJSON_IsNumber(const cJSON *const item);
CJSON_PUBLIC(cJSON_bool) loader_cJSON_IsString(const cJSON *const item);
CJSON_PUBLIC(cJSON_bool) loader_cJSON_IsArray(const cJSON *const item);
CJSON_PUBLIC(cJSON_bool) loader_cJSON_IsObject(const cJSON *const item);
CJSON_PUBLIC(cJSON_bool) loader_cJSON_IsRaw(const cJSON *const item);
struct loader_instance;
struct loader_string_list;
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) \
for (element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
// Read a JSON file into a buffer.
//
// @return - A pointer to a cJSON object representing the JSON parse tree.
// This returned buffer should be freed by caller.
VkResult loader_get_json(const struct loader_instance *inst, const char *filename, cJSON **json);
#ifdef __cplusplus
}
#endif
// Given a cJSON object, find the string associated with the key and puts an pre-allocated string into out_string.
// Length is given by out_str_len, and this function truncates the string with a null terminator if it the provided space isn't
// large enough.
VkResult loader_parse_json_string_to_existing_str(const struct loader_instance *inst, cJSON *object, const char *key,
size_t out_str_len, char *out_string);
// Given a cJSON object, find the string associated with the key and puts an allocated string into out_string.
// It is the callers responsibility to free out_string.
VkResult loader_parse_json_string(cJSON *object, const char *key, char **out_string);
// Given a cJSON object, find the array of strings associated with they key and writes the count into out_count and data into
// out_array_of_strings. It is the callers responsibility to free out_array_of_strings.
VkResult loader_parse_json_array_of_strings(const struct loader_instance *inst, cJSON *object, const char *key,
struct loader_string_list *string_list);
#endif
+128 -91
View File
@@ -27,11 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if !defined(WIN32)
#include <signal.h>
#endif
#include "vulkan/vk_layer.h"
#include "vk_object_types.h"
#include "allocation.h"
@@ -92,7 +88,6 @@ VkBool32 util_SubmitDebugUtilsMessageEXT(const struct loader_instance *inst, VkD
if (0 < pCallbackData->objectCount) {
debug_utils_AnnotObjectToDebugReportObject(pCallbackData->pObjects, &object_type, &object_handle);
}
while (pTrav) {
if (pTrav->is_messenger && (pTrav->messenger.messageSeverity & messageSeverity) &&
(pTrav->messenger.messageType & messageTypes)) {
@@ -106,7 +101,6 @@ VkBool32 util_SubmitDebugUtilsMessageEXT(const struct loader_instance *inst, VkD
bail = true;
}
}
pTrav = pTrav->pNext;
}
}
@@ -136,7 +130,9 @@ VkResult util_CreateDebugUtilsMessengers(struct loader_instance *inst, const voi
const VkAllocationCallbacks *pAllocator) {
const void *pNext = pChain;
while (pNext) {
if (((const VkBaseInStructure *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
VkBaseInStructure in_structure = {0};
memcpy(&in_structure, pNext, sizeof(VkBaseInStructure));
if (in_structure.sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
// Assign a unique handle to each messenger (just use the address of the VkDebugUtilsMessengerCreateInfoEXT)
// This is only being used this way due to it being for an 'anonymous' callback during instance creation
VkDebugUtilsMessengerEXT messenger_handle = (VkDebugUtilsMessengerEXT)(uintptr_t)pNext;
@@ -146,7 +142,7 @@ VkResult util_CreateDebugUtilsMessengers(struct loader_instance *inst, const voi
return ret;
}
}
pNext = (void *)((VkBaseInStructure *)pNext)->pNext;
pNext = in_structure.pNext;
}
return VK_SUCCESS;
}
@@ -175,33 +171,44 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugUtilsMessengerEXT(VkInstanc
const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDebugUtilsMessengerEXT *pMessenger) {
VkDebugUtilsMessengerEXT *icd_info = NULL;
const struct loader_icd_term *icd_term;
struct loader_instance *inst = (struct loader_instance *)instance;
VkResult res = VK_SUCCESS;
uint32_t storage_idx;
VkLayerDbgFunctionNode *new_dbg_func_node = NULL;
uint32_t next_index = 0;
icd_info = (VkDebugUtilsMessengerEXT *)loader_calloc_with_instance_fallback(
pAllocator, inst, inst->total_icd_count * sizeof(VkDebugUtilsMessengerEXT), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!icd_info) {
uint32_t *pNextIndex = loader_instance_heap_alloc(inst, sizeof(uint32_t), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (NULL == pNextIndex) {
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
}
storage_idx = 0;
for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
if (!icd_term->dispatch.CreateDebugUtilsMessengerEXT) {
continue;
res = loader_get_next_available_entry(inst, &inst->debug_utils_messengers_list, &next_index, pAllocator);
if (res != VK_SUCCESS) {
goto out;
}
for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
if (icd_term->debug_utils_messenger_list.list == NULL) {
res = loader_init_generic_list(inst, (struct loader_generic_list *)&icd_term->debug_utils_messenger_list,
sizeof(VkDebugUtilsMessengerEXT));
if (res != VK_SUCCESS) {
goto out;
}
} else if (icd_term->debug_utils_messenger_list.capacity <= next_index * sizeof(VkDebugUtilsMessengerEXT)) {
res = loader_resize_generic_list(inst, (struct loader_generic_list *)&icd_term->debug_utils_messenger_list);
if (res != VK_SUCCESS) {
goto out;
}
}
res = icd_term->dispatch.CreateDebugUtilsMessengerEXT(icd_term->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
if (icd_term->dispatch.CreateDebugUtilsMessengerEXT) {
res = icd_term->dispatch.CreateDebugUtilsMessengerEXT(icd_term->instance, pCreateInfo, pAllocator,
&icd_term->debug_utils_messenger_list.list[next_index]);
if (res != VK_SUCCESS) {
goto out;
if (res != VK_SUCCESS) {
goto out;
}
}
storage_idx++;
}
// Setup the debug report callback in the terminator since a layer may want
@@ -221,27 +228,32 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugUtilsMessengerEXT(VkInstanc
new_dbg_func_node->pUserData = pCreateInfo->pUserData;
new_dbg_func_node->pNext = inst->current_dbg_function_head;
inst->current_dbg_function_head = new_dbg_func_node;
*pMessenger = (VkDebugUtilsMessengerEXT)(uintptr_t)icd_info;
*pNextIndex = next_index;
*pMessenger = (VkDebugUtilsMessengerEXT)(uintptr_t)pNextIndex;
new_dbg_func_node->messenger.messenger = *pMessenger;
out:
// Roll back on errors
if (VK_SUCCESS != res) {
storage_idx = 0;
for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
if (NULL == icd_term->dispatch.DestroyDebugUtilsMessengerEXT) {
continue;
if (pNextIndex) {
for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
if (icd_term->debug_utils_messenger_list.list && icd_term->debug_utils_messenger_list.list[next_index] &&
NULL != icd_term->dispatch.DestroyDebugUtilsMessengerEXT) {
icd_term->dispatch.DestroyDebugUtilsMessengerEXT(
icd_term->instance, icd_term->debug_utils_messenger_list.list[next_index], pAllocator);
}
}
if (icd_info && icd_info[storage_idx]) {
icd_term->dispatch.DestroyDebugUtilsMessengerEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
}
if (inst->debug_utils_messengers_list.list &&
inst->debug_utils_messengers_list.capacity > (*pNextIndex) * sizeof(struct loader_used_object_status)) {
inst->debug_utils_messengers_list.list[*pNextIndex].status = VK_FALSE;
if (NULL != pAllocator) {
inst->debug_utils_messengers_list.list[*pNextIndex].allocation_callbacks = *pAllocator;
}
storage_idx++;
}
loader_free_with_instance_fallback(pAllocator, inst, new_dbg_func_node);
loader_free_with_instance_fallback(pAllocator, inst, icd_info);
loader_free_with_instance_fallback(pAllocator, inst, pNextIndex);
}
return res;
@@ -250,27 +262,31 @@ out:
// This is the instance chain terminator function for DestroyDebugUtilsMessenger
VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
const VkAllocationCallbacks *pAllocator) {
uint32_t storage_idx;
VkDebugUtilsMessengerEXT *icd_info;
const struct loader_icd_term *icd_term;
struct loader_instance *inst = (struct loader_instance *)instance;
icd_info = (VkDebugUtilsMessengerEXT *)(uintptr_t)messenger;
storage_idx = 0;
for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
if (NULL == icd_term->dispatch.DestroyDebugUtilsMessengerEXT) {
continue;
}
uint32_t *debug_messenger_index = (uint32_t *)(uintptr_t)messenger;
// Make sure that messenger actually points to anything
if (NULL == debug_messenger_index) {
return;
}
if (icd_info && icd_info[storage_idx]) {
icd_term->dispatch.DestroyDebugUtilsMessengerEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
if (icd_term->debug_utils_messenger_list.list && icd_term->debug_utils_messenger_list.list[*debug_messenger_index] &&
NULL != icd_term->dispatch.DestroyDebugUtilsMessengerEXT) {
icd_term->dispatch.DestroyDebugUtilsMessengerEXT(
icd_term->instance, icd_term->debug_utils_messenger_list.list[*debug_messenger_index], pAllocator);
}
storage_idx++;
}
util_DestroyDebugUtilsMessenger(inst, messenger, pAllocator);
if (inst->debug_utils_messengers_list.list &&
inst->debug_utils_messengers_list.capacity > (*debug_messenger_index) * sizeof(struct loader_used_object_status)) {
inst->debug_utils_messengers_list.list[*debug_messenger_index].status = VK_FALSE;
if (NULL != pAllocator) {
inst->debug_utils_messengers_list.list[*debug_messenger_index].allocation_callbacks = *pAllocator;
}
}
loader_free_with_instance_fallback(pAllocator, inst, icd_info);
loader_free_with_instance_fallback(pAllocator, inst, debug_messenger_index);
}
// This is the instance chain terminator function for SubmitDebugUtilsMessageEXT
@@ -391,7 +407,9 @@ VkResult util_CreateDebugReportCallbacks(struct loader_instance *inst, const voi
const VkAllocationCallbacks *pAllocator) {
const void *pNext = pChain;
while (pNext) {
if (((VkBaseInStructure *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
VkBaseInStructure in_structure = {0};
memcpy(&in_structure, pNext, sizeof(VkBaseInStructure));
if (in_structure.sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
// Assign a unique handle to each callback (just use the address of the VkDebugReportCallbackCreateInfoEXT):
// This is only being used this way due to it being for an 'anonymous' callback during instance creation
VkDebugReportCallbackEXT report_handle = (VkDebugReportCallbackEXT)(uintptr_t)pNext;
@@ -401,7 +419,7 @@ VkResult util_CreateDebugReportCallbacks(struct loader_instance *inst, const voi
return ret;
}
}
pNext = (void *)((VkBaseInStructure *)pNext)->pNext;
pNext = in_structure.pNext;
}
return VK_SUCCESS;
}
@@ -431,32 +449,44 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallbackEXT(VkInstanc
const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDebugReportCallbackEXT *pCallback) {
VkDebugReportCallbackEXT *icd_info = NULL;
const struct loader_icd_term *icd_term;
struct loader_instance *inst = (struct loader_instance *)instance;
VkResult res = VK_SUCCESS;
uint32_t storage_idx;
VkLayerDbgFunctionNode *new_dbg_func_node = NULL;
uint32_t next_index = 0;
icd_info = ((VkDebugReportCallbackEXT *)loader_calloc_with_instance_fallback(
pAllocator, inst, inst->total_icd_count * sizeof(VkDebugReportCallbackEXT), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
if (!icd_info) {
uint32_t *pNextIndex = loader_instance_heap_alloc(inst, sizeof(uint32_t), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (NULL == pNextIndex) {
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
}
storage_idx = 0;
for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
if (!icd_term->dispatch.CreateDebugReportCallbackEXT) {
continue;
res = loader_get_next_available_entry(inst, &inst->debug_report_callbacks_list, &next_index, pAllocator);
if (res != VK_SUCCESS) {
goto out;
}
for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
if (icd_term->debug_report_callback_list.list == NULL) {
res = loader_init_generic_list(inst, (struct loader_generic_list *)&icd_term->debug_report_callback_list,
sizeof(VkDebugUtilsMessengerEXT));
if (res != VK_SUCCESS) {
goto out;
}
} else if (icd_term->debug_report_callback_list.capacity <= next_index * sizeof(VkDebugReportCallbackEXT)) {
res = loader_resize_generic_list(inst, (struct loader_generic_list *)&icd_term->debug_report_callback_list);
if (res != VK_SUCCESS) {
goto out;
}
}
res = icd_term->dispatch.CreateDebugReportCallbackEXT(icd_term->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
if (icd_term->dispatch.CreateDebugReportCallbackEXT) {
res = icd_term->dispatch.CreateDebugReportCallbackEXT(icd_term->instance, pCreateInfo, pAllocator,
&icd_term->debug_report_callback_list.list[next_index]);
if (res != VK_SUCCESS) {
goto out;
if (res != VK_SUCCESS) {
goto out;
}
}
storage_idx++;
}
// Setup the debug report callback in the terminator since a layer may want
@@ -476,27 +506,32 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallbackEXT(VkInstanc
new_dbg_func_node->pUserData = pCreateInfo->pUserData;
new_dbg_func_node->pNext = inst->current_dbg_function_head;
inst->current_dbg_function_head = new_dbg_func_node;
*pCallback = (VkDebugReportCallbackEXT)(uintptr_t)icd_info;
*pNextIndex = next_index;
*pCallback = (VkDebugReportCallbackEXT)(uintptr_t)pNextIndex;
new_dbg_func_node->report.msgCallback = *pCallback;
out:
// Roll back on errors
if (VK_SUCCESS != res) {
storage_idx = 0;
for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
if (NULL == icd_term->dispatch.DestroyDebugReportCallbackEXT) {
continue;
if (pNextIndex) {
for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
if (icd_term->debug_report_callback_list.list && icd_term->debug_report_callback_list.list[next_index] &&
NULL != icd_term->dispatch.DestroyDebugReportCallbackEXT) {
icd_term->dispatch.DestroyDebugReportCallbackEXT(
icd_term->instance, icd_term->debug_report_callback_list.list[next_index], pAllocator);
}
}
if (icd_info && icd_info[storage_idx]) {
icd_term->dispatch.DestroyDebugReportCallbackEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
}
if (inst->debug_report_callbacks_list.list &&
inst->debug_report_callbacks_list.capacity > (*pNextIndex) * sizeof(struct loader_used_object_status)) {
inst->debug_report_callbacks_list.list[*pNextIndex].status = VK_FALSE;
if (NULL != pAllocator) {
inst->debug_report_callbacks_list.list[*pNextIndex].allocation_callbacks = *pAllocator;
}
storage_idx++;
}
loader_free_with_instance_fallback(pAllocator, inst, new_dbg_func_node);
loader_free_with_instance_fallback(pAllocator, inst, icd_info);
loader_free_with_instance_fallback(pAllocator, inst, pNextIndex);
}
return res;
@@ -505,27 +540,29 @@ out:
// This is the instance chain terminator function for DestroyDebugReportCallback
VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks *pAllocator) {
uint32_t storage_idx;
VkDebugReportCallbackEXT *icd_info;
const struct loader_icd_term *icd_term;
struct loader_instance *inst = (struct loader_instance *)instance;
icd_info = (VkDebugReportCallbackEXT *)(uintptr_t)callback;
storage_idx = 0;
for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
if (NULL == icd_term->dispatch.DestroyDebugReportCallbackEXT) {
continue;
uint32_t *debug_report_index = (uint32_t *)(uintptr_t)callback;
// Make sure that callback actually points to anything
if (NULL == debug_report_index) {
return;
}
for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
if (icd_term->debug_report_callback_list.list && icd_term->debug_report_callback_list.list[*debug_report_index] &&
NULL != icd_term->dispatch.DestroyDebugReportCallbackEXT) {
icd_term->dispatch.DestroyDebugReportCallbackEXT(
icd_term->instance, icd_term->debug_report_callback_list.list[*debug_report_index], pAllocator);
}
if (icd_info[storage_idx]) {
icd_term->dispatch.DestroyDebugReportCallbackEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
}
storage_idx++;
}
util_DestroyDebugReportCallback(inst, callback, pAllocator);
loader_free_with_instance_fallback(pAllocator, inst, icd_info);
if (inst->debug_report_callbacks_list.list &&
inst->debug_report_callbacks_list.capacity > (*debug_report_index) * sizeof(struct loader_used_object_status)) {
inst->debug_report_callbacks_list.list[*debug_report_index].status = VK_FALSE;
if (NULL != pAllocator) {
inst->debug_report_callbacks_list.list[*debug_report_index].allocation_callbacks = *pAllocator;
}
}
loader_free_with_instance_fallback(pAllocator, inst, debug_report_index);
}
// This is the instance chain terminator function for DebugReportMessage
+1 -1
View File
@@ -19,7 +19,7 @@
* Author: Lenny Komow <lenny@lunarg.com>
*/
#include "loader.h"
#include <vulkan/vulkan_core.h>
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC optimize(3) // force gcc to use tail-calls
#endif
+4
View File
@@ -92,6 +92,10 @@ struct dirent *readdir(DIR *dir) {
result = &dir->result;
result->d_name = dir->info.name;
}
// _findnext sets errno to ENOENT when no more matching files could be found, does not indicate an error
if (errno == ENOENT) {
errno = 0;
}
} else {
errno = EBADF;
}
+29 -23
View File
@@ -27,7 +27,6 @@
#include <string.h>
#include "allocation.h"
#include "debug_utils.h"
#include "loader.h"
#include "log.h"
#include "wsi.h"
@@ -107,12 +106,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2E
struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface);
uint8_t icd_index = phys_dev_term->icd_index;
// Unwrap the surface if needed
VkSurfaceKHR unwrapped_surface = surface;
if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
unwrapped_surface = icd_surface->real_icd_surfaces[icd_index];
if (NULL != phys_dev_term->this_icd_term->surface_list.list &&
phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) {
unwrapped_surface = phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index];
}
if (NULL != icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT) {
@@ -274,15 +274,18 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModes2E
"ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceSurfacePresentModes2EXT");
abort();
}
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
uint8_t icd_index = phys_dev_term->icd_index;
if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)icd_surface->real_icd_surfaces[icd_index]) {
VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy;
surface_info_copy.sType = pSurfaceInfo->sType;
surface_info_copy.pNext = pSurfaceInfo->pNext;
surface_info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, &surface_info_copy,
pPresentModeCount, pPresentModes);
if (VK_NULL_HANDLE != pSurfaceInfo->surface) {
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
if (NULL != icd_surface && NULL != icd_term->surface_list.list &&
icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
icd_term->surface_list.list[icd_surface->surface_index]) {
VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy;
surface_info_copy.sType = pSurfaceInfo->sType;
surface_info_copy.pNext = pSurfaceInfo->pNext;
surface_info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index];
return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, &surface_info_copy,
pPresentModeCount, pPresentModes);
}
}
return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, pSurfaceInfo, pPresentModeCount,
pPresentModes);
@@ -304,9 +307,8 @@ VKAPI_ATTR VkResult VKAPI_CALL GetDeviceGroupSurfacePresentModes2EXT(VkDevice de
VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModes2EXT(VkDevice device,
const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
VkDeviceGroupPresentModeFlagsKHR *pModes) {
uint32_t icd_index = 0;
struct loader_device *dev;
struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev);
if (NULL == icd_term || NULL == dev ||
NULL == dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT) {
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
@@ -321,14 +323,18 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModes2EXT(
"[VUID-vkGetDeviceGroupSurfacePresentModes2EXT-pSurfaceInfo-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface;
if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)icd_surface->real_icd_surfaces[icd_index]) {
VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy;
surface_info_copy.sType = pSurfaceInfo->sType;
surface_info_copy.pNext = pSurfaceInfo->pNext;
surface_info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, &surface_info_copy,
pModes);
if (VK_NULL_HANDLE != pSurfaceInfo->surface) {
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
if (NULL != icd_surface && NULL != icd_term->surface_list.list &&
icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
icd_term->surface_list.list[icd_surface->surface_index]) {
VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy;
surface_info_copy.sType = pSurfaceInfo->sType;
surface_info_copy.pNext = pSurfaceInfo->pNext;
surface_info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index];
return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(
device, &surface_info_copy, pModes);
}
}
return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes);
}
+82 -3
View File
@@ -27,6 +27,8 @@
// clang-format off
#pragma once
#include <vulkan/vulkan.h>
#if !defined(PFN_GetPhysicalDeviceProcAddr)
typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName);
#endif
@@ -293,6 +295,12 @@ typedef struct VkLayerInstanceDispatchTable_ {
#ifdef VK_USE_PLATFORM_OHOS
PFN_vkCreateSurfaceOHOS CreateSurfaceOHOS;
#endif // VK_USE_PLATFORM_OHOS
// ---- VK_NV_cooperative_vector extension commands
PFN_vkGetPhysicalDeviceCooperativeVectorPropertiesNV GetPhysicalDeviceCooperativeVectorPropertiesNV;
// ---- VK_NV_cooperative_matrix2 extension commands
PFN_vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV;
} VkLayerInstanceDispatchTable;
// Device function pointer dispatch table
@@ -494,6 +502,27 @@ typedef struct VkLayerDispatchTable_ {
PFN_vkGetDeviceImageMemoryRequirements GetDeviceImageMemoryRequirements;
PFN_vkGetDeviceImageSparseMemoryRequirements GetDeviceImageSparseMemoryRequirements;
// ---- Core Vulkan 1.4 commands
PFN_vkCmdSetLineStipple CmdSetLineStipple;
PFN_vkMapMemory2 MapMemory2;
PFN_vkUnmapMemory2 UnmapMemory2;
PFN_vkCmdBindIndexBuffer2 CmdBindIndexBuffer2;
PFN_vkGetRenderingAreaGranularity GetRenderingAreaGranularity;
PFN_vkGetDeviceImageSubresourceLayout GetDeviceImageSubresourceLayout;
PFN_vkGetImageSubresourceLayout2 GetImageSubresourceLayout2;
PFN_vkCmdPushDescriptorSet CmdPushDescriptorSet;
PFN_vkCmdPushDescriptorSetWithTemplate CmdPushDescriptorSetWithTemplate;
PFN_vkCmdSetRenderingAttachmentLocations CmdSetRenderingAttachmentLocations;
PFN_vkCmdSetRenderingInputAttachmentIndices CmdSetRenderingInputAttachmentIndices;
PFN_vkCmdBindDescriptorSets2 CmdBindDescriptorSets2;
PFN_vkCmdPushConstants2 CmdPushConstants2;
PFN_vkCmdPushDescriptorSet2 CmdPushDescriptorSet2;
PFN_vkCmdPushDescriptorSetWithTemplate2 CmdPushDescriptorSetWithTemplate2;
PFN_vkCopyMemoryToImage CopyMemoryToImage;
PFN_vkCopyImageToMemory CopyImageToMemory;
PFN_vkCopyImageToImage CopyImageToImage;
PFN_vkTransitionImageLayout TransitionImageLayout;
// ---- VK_KHR_swapchain extension commands
PFN_vkCreateSwapchainKHR CreateSwapchainKHR;
PFN_vkDestroySwapchainKHR DestroySwapchainKHR;
@@ -620,6 +649,10 @@ typedef struct VkLayerDispatchTable_ {
// ---- VK_KHR_fragment_shading_rate extension commands
PFN_vkCmdSetFragmentShadingRateKHR CmdSetFragmentShadingRateKHR;
// ---- VK_KHR_dynamic_rendering_local_read extension commands
PFN_vkCmdSetRenderingAttachmentLocationsKHR CmdSetRenderingAttachmentLocationsKHR;
PFN_vkCmdSetRenderingInputAttachmentIndicesKHR CmdSetRenderingInputAttachmentIndicesKHR;
// ---- VK_KHR_present_wait extension commands
PFN_vkWaitForPresentKHR WaitForPresentKHR;
@@ -655,8 +688,6 @@ typedef struct VkLayerDispatchTable_ {
PFN_vkCmdPipelineBarrier2KHR CmdPipelineBarrier2KHR;
PFN_vkCmdWriteTimestamp2KHR CmdWriteTimestamp2KHR;
PFN_vkQueueSubmit2KHR QueueSubmit2KHR;
PFN_vkCmdWriteBufferMarker2AMD CmdWriteBufferMarker2AMD;
PFN_vkGetQueueCheckpointData2NV GetQueueCheckpointData2NV;
// ---- VK_KHR_copy_commands2 extension commands
PFN_vkCmdCopyBuffer2KHR CmdCopyBuffer2KHR;
@@ -680,6 +711,16 @@ typedef struct VkLayerDispatchTable_ {
PFN_vkGetDeviceImageSubresourceLayoutKHR GetDeviceImageSubresourceLayoutKHR;
PFN_vkGetImageSubresourceLayout2KHR GetImageSubresourceLayout2KHR;
// ---- VK_KHR_pipeline_binary extension commands
PFN_vkCreatePipelineBinariesKHR CreatePipelineBinariesKHR;
PFN_vkDestroyPipelineBinaryKHR DestroyPipelineBinaryKHR;
PFN_vkGetPipelineKeyKHR GetPipelineKeyKHR;
PFN_vkGetPipelineBinaryDataKHR GetPipelineBinaryDataKHR;
PFN_vkReleaseCapturedPipelineDataKHR ReleaseCapturedPipelineDataKHR;
// ---- VK_KHR_line_rasterization extension commands
PFN_vkCmdSetLineStippleKHR CmdSetLineStippleKHR;
// ---- VK_KHR_calibrated_timestamps extension commands
PFN_vkGetCalibratedTimestampsKHR GetCalibratedTimestampsKHR;
@@ -715,6 +756,7 @@ typedef struct VkLayerDispatchTable_ {
// ---- VK_NVX_image_view_handle extension commands
PFN_vkGetImageViewHandleNVX GetImageViewHandleNVX;
PFN_vkGetImageViewHandle64NVX GetImageViewHandle64NVX;
PFN_vkGetImageViewAddressNVX GetImageViewAddressNVX;
// ---- VK_AMD_draw_indirect_count extension commands
@@ -832,6 +874,7 @@ typedef struct VkLayerDispatchTable_ {
// ---- VK_AMD_buffer_marker extension commands
PFN_vkCmdWriteBufferMarkerAMD CmdWriteBufferMarkerAMD;
PFN_vkCmdWriteBufferMarker2AMD CmdWriteBufferMarker2AMD;
// ---- VK_EXT_calibrated_timestamps extension commands
PFN_vkGetCalibratedTimestampsEXT GetCalibratedTimestampsEXT;
@@ -848,6 +891,7 @@ typedef struct VkLayerDispatchTable_ {
// ---- VK_NV_device_diagnostic_checkpoints extension commands
PFN_vkCmdSetCheckpointNV CmdSetCheckpointNV;
PFN_vkGetQueueCheckpointDataNV GetQueueCheckpointDataNV;
PFN_vkGetQueueCheckpointData2NV GetQueueCheckpointData2NV;
// ---- VK_INTEL_performance_query extension commands
PFN_vkInitializePerformanceApiINTEL InitializePerformanceApiINTEL;
@@ -1060,7 +1104,6 @@ typedef struct VkLayerDispatchTable_ {
PFN_vkGetPipelineIndirectDeviceAddressNV GetPipelineIndirectDeviceAddressNV;
// ---- VK_EXT_extended_dynamic_state3 extension commands
PFN_vkCmdSetTessellationDomainOriginEXT CmdSetTessellationDomainOriginEXT;
PFN_vkCmdSetDepthClampEnableEXT CmdSetDepthClampEnableEXT;
PFN_vkCmdSetPolygonModeEXT CmdSetPolygonModeEXT;
PFN_vkCmdSetRasterizationSamplesEXT CmdSetRasterizationSamplesEXT;
@@ -1071,6 +1114,7 @@ typedef struct VkLayerDispatchTable_ {
PFN_vkCmdSetColorBlendEnableEXT CmdSetColorBlendEnableEXT;
PFN_vkCmdSetColorBlendEquationEXT CmdSetColorBlendEquationEXT;
PFN_vkCmdSetColorWriteMaskEXT CmdSetColorWriteMaskEXT;
PFN_vkCmdSetTessellationDomainOriginEXT CmdSetTessellationDomainOriginEXT;
PFN_vkCmdSetRasterizationStreamEXT CmdSetRasterizationStreamEXT;
PFN_vkCmdSetConservativeRasterizationModeEXT CmdSetConservativeRasterizationModeEXT;
PFN_vkCmdSetExtraPrimitiveOverestimationSizeEXT CmdSetExtraPrimitiveOverestimationSizeEXT;
@@ -1102,16 +1146,24 @@ typedef struct VkLayerDispatchTable_ {
PFN_vkBindOpticalFlowSessionImageNV BindOpticalFlowSessionImageNV;
PFN_vkCmdOpticalFlowExecuteNV CmdOpticalFlowExecuteNV;
// ---- VK_AMD_anti_lag extension commands
PFN_vkAntiLagUpdateAMD AntiLagUpdateAMD;
// ---- VK_EXT_shader_object extension commands
PFN_vkCreateShadersEXT CreateShadersEXT;
PFN_vkDestroyShaderEXT DestroyShaderEXT;
PFN_vkGetShaderBinaryDataEXT GetShaderBinaryDataEXT;
PFN_vkCmdBindShadersEXT CmdBindShadersEXT;
PFN_vkCmdSetDepthClampRangeEXT CmdSetDepthClampRangeEXT;
// ---- VK_QCOM_tile_properties extension commands
PFN_vkGetFramebufferTilePropertiesQCOM GetFramebufferTilePropertiesQCOM;
PFN_vkGetDynamicRenderingTilePropertiesQCOM GetDynamicRenderingTilePropertiesQCOM;
// ---- VK_NV_cooperative_vector extension commands
PFN_vkConvertCooperativeVectorMatrixNV ConvertCooperativeVectorMatrixNV;
PFN_vkCmdConvertCooperativeVectorMatrixNV CmdConvertCooperativeVectorMatrixNV;
// ---- VK_NV_low_latency2 extension commands
PFN_vkSetLatencySleepModeNV SetLatencySleepModeNV;
PFN_vkLatencySleepNV LatencySleepNV;
@@ -1127,6 +1179,33 @@ typedef struct VkLayerDispatchTable_ {
PFN_vkGetScreenBufferPropertiesQNX GetScreenBufferPropertiesQNX;
#endif // VK_USE_PLATFORM_SCREEN_QNX
// ---- VK_NV_cluster_acceleration_structure extension commands
PFN_vkGetClusterAccelerationStructureBuildSizesNV GetClusterAccelerationStructureBuildSizesNV;
PFN_vkCmdBuildClusterAccelerationStructureIndirectNV CmdBuildClusterAccelerationStructureIndirectNV;
// ---- VK_NV_partitioned_acceleration_structure extension commands
PFN_vkGetPartitionedAccelerationStructuresBuildSizesNV GetPartitionedAccelerationStructuresBuildSizesNV;
PFN_vkCmdBuildPartitionedAccelerationStructuresNV CmdBuildPartitionedAccelerationStructuresNV;
// ---- VK_EXT_device_generated_commands extension commands
PFN_vkGetGeneratedCommandsMemoryRequirementsEXT GetGeneratedCommandsMemoryRequirementsEXT;
PFN_vkCmdPreprocessGeneratedCommandsEXT CmdPreprocessGeneratedCommandsEXT;
PFN_vkCmdExecuteGeneratedCommandsEXT CmdExecuteGeneratedCommandsEXT;
PFN_vkCreateIndirectCommandsLayoutEXT CreateIndirectCommandsLayoutEXT;
PFN_vkDestroyIndirectCommandsLayoutEXT DestroyIndirectCommandsLayoutEXT;
PFN_vkCreateIndirectExecutionSetEXT CreateIndirectExecutionSetEXT;
PFN_vkDestroyIndirectExecutionSetEXT DestroyIndirectExecutionSetEXT;
PFN_vkUpdateIndirectExecutionSetPipelineEXT UpdateIndirectExecutionSetPipelineEXT;
PFN_vkUpdateIndirectExecutionSetShaderEXT UpdateIndirectExecutionSetShaderEXT;
// ---- VK_EXT_external_memory_metal extension commands
#if defined(VK_USE_PLATFORM_METAL_EXT)
PFN_vkGetMemoryMetalHandleEXT GetMemoryMetalHandleEXT;
#endif // VK_USE_PLATFORM_METAL_EXT
#if defined(VK_USE_PLATFORM_METAL_EXT)
PFN_vkGetMemoryMetalHandlePropertiesEXT GetMemoryMetalHandlePropertiesEXT;
#endif // VK_USE_PLATFORM_METAL_EXT
// ---- VK_KHR_acceleration_structure extension commands
PFN_vkCreateAccelerationStructureKHR CreateAccelerationStructureKHR;
PFN_vkDestroyAccelerationStructureKHR DestroyAccelerationStructureKHR;
File diff suppressed because it is too large Load Diff
+21
View File
@@ -27,6 +27,12 @@
// clang-format off
#pragma once
#include <stdbool.h>
#include <vulkan/vulkan.h>
#include <vulkan/vk_layer.h>
#include "vk_layer_dispatch_table.h"
// Structures defined externally, but used here
struct loader_instance;
struct loader_device;
@@ -131,6 +137,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDevice(
const VkAllocationCallbacks* pAllocator,
VkDevice* pDevice);
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateInstanceExtensionProperties(
const char* pLayerName,
uint32_t* pPropertyCount,
VkExtensionProperties* pProperties);
VKAPI_ATTR VkResult VKAPI_CALL terminator_pre_instance_EnumerateInstanceExtensionProperties(
const VkEnumerateInstanceExtensionPropertiesChain* chain,
const char* pLayerName,
uint32_t* pPropertyCount,
@@ -141,6 +151,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties(
uint32_t* pPropertyCount,
VkExtensionProperties* pProperties);
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateInstanceLayerProperties(
uint32_t* pPropertyCount,
VkLayerProperties* pProperties);
VKAPI_ATTR VkResult VKAPI_CALL terminator_pre_instance_EnumerateInstanceLayerProperties(
const VkEnumerateInstanceLayerPropertiesChain* chain,
uint32_t* pPropertyCount,
VkLayerProperties* pProperties);
@@ -158,6 +171,8 @@ VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperti
uint32_t* pPropertyCount,
VkSparseImageFormatProperties* pProperties);
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateInstanceVersion(
uint32_t* pApiVersion);
VKAPI_ATTR VkResult VKAPI_CALL terminator_pre_instance_EnumerateInstanceVersion(
const VkEnumerateInstanceVersionChain* chain,
uint32_t* pApiVersion);
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
@@ -466,6 +481,12 @@ struct loader_icd_term_dispatch {
#ifdef VK_USE_PLATFORM_OHOS
PFN_vkCreateSurfaceOHOS CreateSurfaceOHOS;
#endif // VK_USE_PLATFORM_OHOS
// ---- VK_NV_cooperative_vector extension commands
PFN_vkGetPhysicalDeviceCooperativeVectorPropertiesNV GetPhysicalDeviceCooperativeVectorPropertiesNV;
// ---- VK_NV_cooperative_matrix2 extension commands
PFN_vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV;
};
struct loader_instance_extension_enables {
+28 -16
View File
@@ -73,22 +73,25 @@ typedef enum VulkanObjectType {
kVulkanObjectTypeVideoSessionKHR = 33,
kVulkanObjectTypeVideoSessionParametersKHR = 34,
kVulkanObjectTypeDeferredOperationKHR = 35,
kVulkanObjectTypeDebugReportCallbackEXT = 36,
kVulkanObjectTypeCuModuleNVX = 37,
kVulkanObjectTypeCuFunctionNVX = 38,
kVulkanObjectTypeDebugUtilsMessengerEXT = 39,
kVulkanObjectTypeValidationCacheEXT = 40,
kVulkanObjectTypeAccelerationStructureNV = 41,
kVulkanObjectTypePerformanceConfigurationINTEL = 42,
kVulkanObjectTypeIndirectCommandsLayoutNV = 43,
kVulkanObjectTypeCudaModuleNV = 44,
kVulkanObjectTypeCudaFunctionNV = 45,
kVulkanObjectTypeAccelerationStructureKHR = 46,
kVulkanObjectTypeBufferCollectionFUCHSIA = 47,
kVulkanObjectTypeMicromapEXT = 48,
kVulkanObjectTypeOpticalFlowSessionNV = 49,
kVulkanObjectTypeShaderEXT = 50,
kVulkanObjectTypeMax = 51,
kVulkanObjectTypePipelineBinaryKHR = 36,
kVulkanObjectTypeDebugReportCallbackEXT = 37,
kVulkanObjectTypeCuModuleNVX = 38,
kVulkanObjectTypeCuFunctionNVX = 39,
kVulkanObjectTypeDebugUtilsMessengerEXT = 40,
kVulkanObjectTypeValidationCacheEXT = 41,
kVulkanObjectTypeAccelerationStructureNV = 42,
kVulkanObjectTypePerformanceConfigurationINTEL = 43,
kVulkanObjectTypeIndirectCommandsLayoutNV = 44,
kVulkanObjectTypeCudaModuleNV = 45,
kVulkanObjectTypeCudaFunctionNV = 46,
kVulkanObjectTypeAccelerationStructureKHR = 47,
kVulkanObjectTypeBufferCollectionFUCHSIA = 48,
kVulkanObjectTypeMicromapEXT = 49,
kVulkanObjectTypeOpticalFlowSessionNV = 50,
kVulkanObjectTypeShaderEXT = 51,
kVulkanObjectTypeIndirectExecutionSetEXT = 52,
kVulkanObjectTypeIndirectCommandsLayoutEXT = 53,
kVulkanObjectTypeMax = 54,
// Aliases for backwards compatibilty of "promoted" types
kVulkanObjectTypeDescriptorUpdateTemplateKHR = kVulkanObjectTypeDescriptorUpdateTemplate,
kVulkanObjectTypeSamplerYcbcrConversionKHR = kVulkanObjectTypeSamplerYcbcrConversion,
@@ -133,6 +136,7 @@ static const char * const object_string[kVulkanObjectTypeMax] = {
"VideoSessionKHR",
"VideoSessionParametersKHR",
"DeferredOperationKHR",
"PipelineBinaryKHR",
"DebugReportCallbackEXT",
"CuModuleNVX",
"CuFunctionNVX",
@@ -148,6 +152,8 @@ static const char * const object_string[kVulkanObjectTypeMax] = {
"MicromapEXT",
"OpticalFlowSessionNV",
"ShaderEXT",
"IndirectExecutionSetEXT",
"IndirectCommandsLayoutEXT",
};
// Helper array to get Vulkan VK_EXT_debug_report object type enum from the internal layers version
@@ -188,6 +194,7 @@ const VkDebugReportObjectTypeEXT get_debug_report_enum[] = {
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeVideoSessionKHR
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeVideoSessionParametersKHR
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeDeferredOperationKHR
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypePipelineBinaryKHR
VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, // kVulkanObjectTypeDebugReportCallbackEXT
VK_DEBUG_REPORT_OBJECT_TYPE_CU_MODULE_NVX_EXT, // kVulkanObjectTypeCuModuleNVX
VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT, // kVulkanObjectTypeCuFunctionNVX
@@ -203,6 +210,8 @@ const VkDebugReportObjectTypeEXT get_debug_report_enum[] = {
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeMicromapEXT
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeOpticalFlowSessionNV
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeShaderEXT
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeIndirectExecutionSetEXT
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeIndirectCommandsLayoutEXT
};
// Helper array to get Official Vulkan VkObjectType enum from the internal layers version
@@ -243,6 +252,7 @@ const VkObjectType get_object_type_enum[] = {
VK_OBJECT_TYPE_VIDEO_SESSION_KHR, // kVulkanObjectTypeVideoSessionKHR
VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR, // kVulkanObjectTypeVideoSessionParametersKHR
VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR, // kVulkanObjectTypeDeferredOperationKHR
VK_OBJECT_TYPE_PIPELINE_BINARY_KHR, // kVulkanObjectTypePipelineBinaryKHR
VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT, // kVulkanObjectTypeDebugReportCallbackEXT
VK_OBJECT_TYPE_CU_MODULE_NVX, // kVulkanObjectTypeCuModuleNVX
VK_OBJECT_TYPE_CU_FUNCTION_NVX, // kVulkanObjectTypeCuFunctionNVX
@@ -258,6 +268,8 @@ const VkObjectType get_object_type_enum[] = {
VK_OBJECT_TYPE_MICROMAP_EXT, // kVulkanObjectTypeMicromapEXT
VK_OBJECT_TYPE_OPTICAL_FLOW_SESSION_NV, // kVulkanObjectTypeOpticalFlowSessionNV
VK_OBJECT_TYPE_SHADER_EXT, // kVulkanObjectTypeShaderEXT
VK_OBJECT_TYPE_INDIRECT_EXECUTION_SET_EXT, // kVulkanObjectTypeIndirectExecutionSetEXT
VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_EXT, // kVulkanObjectTypeIndirectCommandsLayoutEXT
};
// Helper function to convert from VkDebugReportObjectTypeEXT to VkObjectType
+24 -4
View File
@@ -1,8 +1,8 @@
/*
*
* Copyright (c) 2015-2021 The Khronos Group Inc.
* Copyright (c) 2015-2021 Valve Corporation
* Copyright (c) 2015-2021 LunarG, Inc.
* Copyright (c) 2015-2024 The Khronos Group Inc.
* Copyright (c) 2015-2024 Valve Corporation
* Copyright (c) 2015-2024 LunarG, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@
#include <string.h>
#include "loader.h"
#include "debug_utils.h"
#include "unknown_function_handling.h"
#include "wsi.h"
@@ -250,6 +249,27 @@ void *trampoline_get_proc_addr(struct loader_instance *inst, const char *funcNam
if (!strcmp(funcName, "vkGetDeviceImageMemoryRequirements")) return vkGetDeviceImageMemoryRequirements;
if (!strcmp(funcName, "vkGetDeviceImageSparseMemoryRequirements")) return vkGetDeviceImageSparseMemoryRequirements;
// Core 1.4 functions
if (!strcmp(funcName, "vkCmdSetLineStipple")) return vkCmdSetLineStipple;
if (!strcmp(funcName, "vkMapMemory2")) return vkMapMemory2;
if (!strcmp(funcName, "vkUnmapMemory2")) return vkUnmapMemory2;
if (!strcmp(funcName, "vkCmdBindIndexBuffer2")) return vkCmdBindIndexBuffer2;
if (!strcmp(funcName, "vkGetRenderingAreaGranularity")) return vkGetRenderingAreaGranularity;
if (!strcmp(funcName, "vkGetDeviceImageSubresourceLayout")) return vkGetDeviceImageSubresourceLayout;
if (!strcmp(funcName, "vkGetImageSubresourceLayout2")) return vkGetImageSubresourceLayout2;
if (!strcmp(funcName, "vkCmdPushDescriptorSet")) return vkCmdPushDescriptorSet;
if (!strcmp(funcName, "vkCmdPushDescriptorSetWithTemplate")) return vkCmdPushDescriptorSetWithTemplate;
if (!strcmp(funcName, "vkCmdSetRenderingAttachmentLocations")) return vkCmdSetRenderingAttachmentLocations;
if (!strcmp(funcName, "vkCmdSetRenderingInputAttachmentIndices")) return vkCmdSetRenderingInputAttachmentIndices;
if (!strcmp(funcName, "vkCmdBindDescriptorSets2")) return vkCmdBindDescriptorSets2;
if (!strcmp(funcName, "vkCmdPushConstants2")) return vkCmdPushConstants2;
if (!strcmp(funcName, "vkCmdPushDescriptorSet2")) return vkCmdPushDescriptorSet2;
if (!strcmp(funcName, "vkCmdPushDescriptorSetWithTemplate2")) return vkCmdPushDescriptorSetWithTemplate2;
if (!strcmp(funcName, "vkCopyMemoryToImage")) return vkCopyMemoryToImage;
if (!strcmp(funcName, "vkCopyImageToMemory")) return vkCopyImageToMemory;
if (!strcmp(funcName, "vkCopyImageToImage")) return vkCopyImageToImage;
if (!strcmp(funcName, "vkTransitionImageLayout")) return vkTransitionImageLayout;
// Instance extensions
void *addr;
if (debug_extensions_InstanceGpa(inst, funcName, &addr)) return addr;
+649 -300
View File
File diff suppressed because it is too large Load Diff
+16 -4
View File
@@ -95,7 +95,11 @@ VkResult loader_validate_instance_extensions(struct loader_instance *inst, const
const struct loader_envvar_all_filters *layer_filters,
const VkInstanceCreateInfo *pCreateInfo);
#if defined(_WIN32)
BOOL __stdcall loader_initialize(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context);
#else
void loader_initialize(void);
#endif
void loader_release(void);
void loader_preload_icds(void);
void loader_unload_preloaded_icds(void);
@@ -120,6 +124,10 @@ VkResult copy_str_to_string_list(const struct loader_instance *inst, struct load
void free_string_list(const struct loader_instance *inst, struct loader_string_list *string_list);
VkResult loader_init_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info, size_t element_size);
VkResult loader_resize_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info);
VkResult loader_get_next_available_entry(const struct loader_instance *inst, struct loader_used_object_list *list_info,
uint32_t *free_index, const VkAllocationCallbacks *pAllocator);
void loader_release_object_from_list(struct loader_used_object_list *list_info, uint32_t index_to_free);
bool has_vk_extension_property_array(const VkExtensionProperties *vk_ext_prop, const uint32_t count,
const VkExtensionProperties *ext_array);
bool has_vk_extension_property(const VkExtensionProperties *vk_ext_prop, const struct loader_extension_list *ext_list);
@@ -147,13 +155,15 @@ VkResult loader_add_device_extensions(const struct loader_instance *inst,
VkResult loader_init_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info, size_t element_size);
void loader_destroy_generic_list(const struct loader_instance *inst, struct loader_generic_list *list);
void loader_destroy_pointer_layer_list(const struct loader_instance *inst, struct loader_pointer_layer_list *layer_list);
void loader_delete_layer_list_and_properties(const struct loader_instance *inst, struct loader_layer_list *layer_list);
TEST_FUNCTION_EXPORT void loader_delete_layer_list_and_properties(const struct loader_instance *inst,
struct loader_layer_list *layer_list);
void loader_remove_layer_in_list(const struct loader_instance *inst, struct loader_layer_list *layer_list,
uint32_t layer_to_remove);
VkResult loader_scanned_icd_init(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list);
void loader_scanned_icd_clear(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list);
VkResult loader_init_scanned_icd_list(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list);
void loader_clear_scanned_icd_list(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list);
VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
const VkInstanceCreateInfo *pCreateInfo, bool *skipped_portability_drivers);
void loader_icd_close_objects(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term);
void loader_icd_destroy(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term,
const VkAllocationCallbacks *pAllocator);
VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers,
@@ -162,8 +172,9 @@ VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct lo
const struct loader_envvar_all_filters *layer_filters);
VkResult loader_get_icd_loader_instance_extensions(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
struct loader_extension_list *inst_exts);
struct loader_icd_term *loader_get_icd_and_device(const void *device, struct loader_device **found_dev, uint32_t *icd_index);
struct loader_icd_term *loader_get_icd_and_device(const void *device, struct loader_device **found_dev);
struct loader_instance *loader_get_instance(const VkInstance instance);
loader_platform_dl_handle loader_open_layer_file(const struct loader_instance *inst, struct loader_layer_properties *prop);
struct loader_device *loader_create_logical_device(const struct loader_instance *inst, const VkAllocationCallbacks *pAllocator);
void loader_add_logical_device(struct loader_icd_term *icd_term, struct loader_device *found_dev);
void loader_remove_logical_device(struct loader_icd_term *icd_term, struct loader_device *found_dev,
@@ -200,6 +211,7 @@ VkResult loader_validate_device_extensions(struct loader_instance *this_instance
VkResult setup_loader_tramp_phys_devs(struct loader_instance *inst, uint32_t phys_dev_count, VkPhysicalDevice *phys_devs);
VkResult setup_loader_tramp_phys_dev_groups(struct loader_instance *inst, uint32_t group_count,
VkPhysicalDeviceGroupProperties *groups);
void unload_drivers_without_physical_devices(struct loader_instance *inst);
VkStringErrorFlags vk_string_validate(const int max_length, const char *char_array);
char *loader_get_next_path(char *path);
+6 -6
View File
@@ -1,7 +1,7 @@
//
// Copyright (c) 2014-2024 The Khronos Group Inc.
// Copyright (c) 2014-2024 Valve Corporation
// Copyright (c) 2014-2024 LunarG, Inc.
// Copyright (c) 2014-2025 The Khronos Group Inc.
// Copyright (c) 2014-2025 Valve Corporation
// Copyright (c) 2014-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.
@@ -22,10 +22,10 @@
#include "winres.h"
// All set through CMake
#define VER_FILE_VERSION 1, 3, 275, 0
#define VER_FILE_DESCRIPTION_STR "1.3.275.Dev Build"
#define VER_FILE_VERSION 1, 4, 309, 0
#define VER_FILE_DESCRIPTION_STR "1.4.309.Dev Build"
#define VER_FILE_VERSION_STR "Vulkan Loader - Dev Build"
#define VER_COPYRIGHT_STR "Copyright (C) 2015-2024"
#define VER_COPYRIGHT_STR "Copyright (C) 2015-2025"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILE_VERSION
+61 -5
View File
@@ -90,6 +90,40 @@ struct loader_device_extension_list {
struct loader_dev_ext_props *list;
};
struct loader_used_object_status {
VkBool32 status;
VkAllocationCallbacks allocation_callbacks;
};
struct loader_used_object_list {
size_t capacity;
uint32_t padding; // count variable isn't used
struct loader_used_object_status *list;
};
struct loader_surface_allocation {
VkSurfaceKHR surface;
VkAllocationCallbacks allocation_callbacks;
};
struct loader_surface_list {
size_t capacity;
uint32_t padding; // count variable isn't used
VkSurfaceKHR *list;
};
struct loader_debug_utils_messenger_list {
size_t capacity;
uint32_t padding; // count variable isn't used
VkDebugUtilsMessengerEXT *list;
};
struct loader_debug_report_callback_list {
size_t capacity;
uint32_t padding; // count variable isn't used
VkDebugReportCallbackEXT *list;
};
struct loader_name_value {
char *name;
char *value;
@@ -129,6 +163,16 @@ enum layer_type_flags {
VK_LAYER_TYPE_FLAG_META_LAYER = 0x4, // If not set, indicates standard layer
};
enum loader_layer_enabled_by_what {
ENABLED_BY_WHAT_UNSET, // default value indicates this field hasn't been filled in
ENABLED_BY_WHAT_LOADER_SETTINGS_FILE,
ENABLED_BY_WHAT_IMPLICIT_LAYER,
ENABLED_BY_WHAT_VK_INSTANCE_LAYERS,
ENABLED_BY_WHAT_VK_LOADER_LAYERS_ENABLE,
ENABLED_BY_WHAT_IN_APPLICATION_API,
ENABLED_BY_WHAT_META_LAYER,
};
struct loader_layer_properties {
VkLayerProperties info;
enum layer_type_flags type_flags;
@@ -138,6 +182,7 @@ struct loader_layer_properties {
char *manifest_file_name;
char *lib_name;
enum loader_layer_library_status lib_status;
enum loader_layer_enabled_by_what enabled_by_what;
loader_platform_dl_handle lib_handle;
struct loader_layer_functions functions;
struct loader_extension_list instance_extension_list;
@@ -205,6 +250,9 @@ struct loader_device {
bool ext_debug_marker_enabled;
bool ext_debug_utils_enabled;
bool ext_full_screen_exclusive_enabled;
bool version_1_1_enabled;
bool version_1_2_enabled;
bool version_1_3_enabled;
} driver_extensions;
struct loader_device *next;
@@ -229,6 +277,13 @@ struct loader_icd_term {
PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS];
bool supports_get_dev_prop_2;
bool supports_ext_surface_maintenance_1;
uint32_t physical_device_count;
struct loader_surface_list surface_list;
struct loader_debug_utils_messenger_list debug_utils_messenger_list;
struct loader_debug_report_callback_list debug_report_callback_list;
};
// Per ICD library structure
@@ -276,7 +331,7 @@ struct loader_instance {
struct loader_instance *next;
uint32_t total_icd_count;
uint32_t icd_terms_count;
struct loader_icd_term *icd_terms;
struct loader_icd_tramp_list icd_tramp_list;
@@ -307,6 +362,11 @@ struct loader_instance {
struct loader_extension_list ext_list; // icds and loaders extensions
struct loader_instance_extension_enables enabled_known_extensions;
// Indicates which indices in the array are in-use and which are free to be reused
struct loader_used_object_list surfaces_list;
struct loader_used_object_list debug_utils_messengers_list;
struct loader_used_object_list debug_report_callbacks_list;
// Stores debug callbacks - used in the log.
VkLayerDbgFunctionNode *current_dbg_function_head; // Current head
VkLayerDbgFunctionNode *instance_only_dbg_function_head; // Only used for instance create/destroy
@@ -400,7 +460,6 @@ struct loader_physical_device_tramp {
struct loader_physical_device_term {
struct loader_instance_dispatch_table *disp; // must be first entry in structure
struct loader_icd_term *this_icd_term;
uint8_t icd_index;
VkPhysicalDevice phys_dev; // object from ICD
};
@@ -414,7 +473,6 @@ struct LinuxSortedDeviceInfo {
bool default_device;
// Loader specific items about the driver providing support for this physical device
uint32_t icd_index;
struct loader_icd_term *icd_term;
// Some generic device properties
@@ -435,7 +493,6 @@ struct LinuxSortedDeviceInfo {
// Per enumerated PhysicalDeviceGroup structure, used to wrap in terminator code
struct loader_physical_device_group_term {
struct loader_icd_term *this_icd_term;
uint8_t icd_index;
VkPhysicalDeviceGroupProperties group_props;
#if defined(LOADER_ENABLE_LINUX_SORT)
struct LinuxSortedDeviceInfo internal_device_info[VK_MAX_DEVICE_GROUP_SIZE];
@@ -470,7 +527,6 @@ enum loader_data_files_type {
struct loader_icd_physical_devices {
uint32_t device_count;
VkPhysicalDevice *physical_devices;
uint32_t icd_index;
struct loader_icd_term *icd_term;
#if defined(WIN32)
LUID windows_adapter_luid;
+4 -1
View File
@@ -31,6 +31,7 @@
#include "allocation.h"
#include "loader.h"
#include "log.h"
#include "stack_allocation.h"
#include <ctype.h>
#include "param/sys_param.h"
@@ -38,7 +39,7 @@
// Environment variables
#if COMMON_UNIX_PLATFORMS
bool is_high_integrity() { return geteuid() != getuid() || getegid() != getgid(); }
bool is_high_integrity(void) { return geteuid() != getuid() || getegid() != getgid(); }
char *loader_getenv(const char *name, const struct loader_instance *inst) {
if (NULL == name) return NULL;
@@ -491,6 +492,7 @@ VkResult loader_add_environment_layers(struct loader_instance *inst, const enum
// Only add it if it doesn't already appear in the layer list
if (!loader_find_layer_name_in_list(source_prop->info.layerName, target_list)) {
if (0 == (source_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
source_prop->enabled_by_what = ENABLED_BY_WHAT_VK_INSTANCE_LAYERS;
res = loader_add_layer_properties_to_list(inst, target_list, source_prop);
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
res = loader_add_layer_properties_to_list(inst, expanded_target_list, source_prop);
@@ -557,6 +559,7 @@ VkResult loader_add_environment_layers(struct loader_instance *inst, const enum
// If not a meta-layer, simply add it.
if (0 == (source_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
source_prop->enabled_by_what = ENABLED_BY_WHAT_VK_LOADER_LAYERS_ENABLE;
res = loader_add_layer_properties_to_list(inst, target_list, source_prop);
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
res = loader_add_layer_properties_to_list(inst, expanded_target_list, source_prop);
+1 -1
View File
@@ -37,7 +37,7 @@ void loader_free_getenv(char *val, const struct loader_instance *inst);
#if defined(WIN32) || COMMON_UNIX_PLATFORMS
bool is_high_integrity();
bool is_high_integrity(void);
char *loader_secure_getenv(const char *name, const struct loader_instance *inst);
+258
View File
@@ -0,0 +1,258 @@
/*
Copyright (c) 2015-2021 The Khronos Group Inc.
Copyright (c) 2015-2021 Valve Corporation
Copyright (c) 2015-2021 LunarG, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "loader_json.h"
#include <assert.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"
#include "allocation.h"
#include "loader.h"
#include "log.h"
#if COMMON_UNIX_PLATFORMS
#include <fcntl.h>
#include <sys/stat.h>
#endif
#ifdef _WIN32
static VkResult loader_read_entire_file(const struct loader_instance *inst, const char *filename, size_t *out_len,
char **out_buff) {
HANDLE file_handle = INVALID_HANDLE_VALUE;
DWORD len = 0, read_len = 0;
VkResult res = VK_SUCCESS;
BOOL read_ok = false;
int filename_utf16_size = MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
if (filename_utf16_size > 0) {
wchar_t *filename_utf16 = (wchar_t *)loader_stack_alloc(filename_utf16_size * sizeof(wchar_t));
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filename_utf16, filename_utf16_size) == filename_utf16_size) {
file_handle =
CreateFileW(filename_utf16, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
}
if (INVALID_HANDLE_VALUE == file_handle) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Failed to open JSON file %s", filename);
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
}
len = GetFileSize(file_handle, NULL);
if (INVALID_FILE_SIZE == len) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Failed to read file size of JSON file %s", filename);
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
}
*out_buff = (char *)loader_instance_heap_calloc(inst, len + 1, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
if (NULL == *out_buff) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Failed to allocate memory to read JSON file %s", filename);
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
}
read_ok = ReadFile(file_handle, *out_buff, len, &read_len, NULL);
if (len != read_len || false == read_ok) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Failed to read entire JSON file %s", filename);
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
}
*out_len = len + 1;
(*out_buff)[len] = '\0';
out:
if (INVALID_HANDLE_VALUE != file_handle) {
CloseHandle(file_handle);
}
return res;
}
#elif COMMON_UNIX_PLATFORMS
static VkResult loader_read_entire_file(const struct loader_instance *inst, const char *filename, size_t *out_len,
char **out_buff) {
FILE *file = NULL;
struct stat stats = {0};
VkResult res = VK_SUCCESS;
file = fopen(filename, "rb");
if (NULL == file) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Failed to open JSON file %s", filename);
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
}
if (-1 == fstat(fileno(file), &stats)) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Failed to read file size of JSON file %s", filename);
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
}
*out_buff = (char *)loader_instance_heap_calloc(inst, stats.st_size + 1, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
if (NULL == *out_buff) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Failed to allocate memory to read JSON file %s", filename);
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
}
if (stats.st_size != (long int)fread(*out_buff, sizeof(char), stats.st_size, file)) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Failed to read entire JSON file %s", filename);
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
}
*out_len = stats.st_size + 1;
(*out_buff)[stats.st_size] = '\0';
out:
if (NULL != file) {
fclose(file);
}
return res;
}
#else
#warning fopen not available on this platform
VkResult loader_read_entire_file(const struct loader_instance *inst, const char *filename, size_t *out_len, char **out_buff) {
return VK_ERROR_INITIALIZATION_FAILED;
}
#endif
TEST_FUNCTION_EXPORT VkResult loader_get_json(const struct loader_instance *inst, const char *filename, cJSON **json) {
char *json_buf = NULL;
VkResult res = VK_SUCCESS;
assert(json != NULL);
size_t json_len = 0;
*json = NULL;
res = loader_read_entire_file(inst, filename, &json_len, &json_buf);
if (VK_SUCCESS != res) {
goto out;
}
bool out_of_memory = false;
// Parse text from file
*json = loader_cJSON_ParseWithLength(inst ? &inst->alloc_callbacks : NULL, json_buf, json_len, &out_of_memory);
if (out_of_memory) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Out of Memory error occurred while parsing JSON file %s.",
filename);
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
} else if (*json == NULL) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Invalid JSON file %s.", filename);
goto out;
}
out:
loader_instance_heap_free(inst, json_buf);
if (res != VK_SUCCESS && *json != NULL) {
loader_cJSON_Delete(*json);
*json = NULL;
}
return res;
}
VkResult loader_parse_json_string_to_existing_str(cJSON *object, const char *key, size_t out_str_len, char *out_string) {
if (NULL == key) {
return VK_ERROR_INITIALIZATION_FAILED;
}
cJSON *item = loader_cJSON_GetObjectItem(object, key);
if (NULL == item) {
return VK_ERROR_INITIALIZATION_FAILED;
}
if (item->type != cJSON_String || item->valuestring == NULL) {
return VK_ERROR_INITIALIZATION_FAILED;
}
bool out_of_memory = false;
bool success = loader_cJSON_PrintPreallocated(item, out_string, (int)out_str_len, cJSON_False);
if (out_of_memory) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
if (!success) {
return VK_ERROR_INITIALIZATION_FAILED;
}
return VK_SUCCESS;
}
VkResult loader_parse_json_string(cJSON *object, const char *key, char **out_string) {
if (NULL == key) {
return VK_ERROR_INITIALIZATION_FAILED;
}
cJSON *item = loader_cJSON_GetObjectItem(object, key);
if (NULL == item || NULL == item->valuestring) {
return VK_ERROR_INITIALIZATION_FAILED;
}
bool out_of_memory = false;
char *str = loader_cJSON_Print(item, &out_of_memory);
if (out_of_memory || NULL == str) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
if (NULL != out_string) {
*out_string = str;
}
return VK_SUCCESS;
}
VkResult loader_parse_json_array_of_strings(const struct loader_instance *inst, cJSON *object, const char *key,
struct loader_string_list *string_list) {
if (NULL == key) {
return VK_ERROR_INITIALIZATION_FAILED;
}
cJSON *item = loader_cJSON_GetObjectItem(object, key);
if (NULL == item) {
return VK_ERROR_INITIALIZATION_FAILED;
}
uint32_t count = loader_cJSON_GetArraySize(item);
if (count == 0) {
return VK_SUCCESS;
}
VkResult res = create_string_list(inst, count, string_list);
if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
goto out;
}
cJSON *element = NULL;
cJSON_ArrayForEach(element, item) {
if (element->type != cJSON_String) {
return VK_ERROR_INITIALIZATION_FAILED;
}
bool out_of_memory = false;
char *out_data = loader_cJSON_Print(element, &out_of_memory);
if (out_of_memory) {
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
}
res = append_str_to_string_list(inst, string_list, out_data);
if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
goto out;
}
}
out:
if (res == VK_ERROR_OUT_OF_HOST_MEMORY && NULL != string_list->list) {
free_string_list(inst, string_list);
}
return res;
}
+55
View File
@@ -0,0 +1,55 @@
/*
Copyright (c) 2015-2021 The Khronos Group Inc.
Copyright (c) 2015-2021 Valve Corporation
Copyright (c) 2015-2021 LunarG, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#pragma once
#include <stddef.h>
#include <vulkan/vulkan_core.h>
#include <cJSON.h>
// Forward decls
struct loader_instance;
struct loader_string_list;
// Read a JSON file into a buffer.
//
// @return - A pointer to a cJSON object representing the JSON parse tree.
// This returned buffer should be freed by caller.
TEST_FUNCTION_EXPORT VkResult loader_get_json(const struct loader_instance *inst, const char *filename, cJSON **json);
// Given a cJSON object, find the string associated with the key and puts an pre-allocated string into out_string.
// Length is given by out_str_len, and this function truncates the string with a null terminator if it the provided space isn't
// large enough.
VkResult loader_parse_json_string_to_existing_str(cJSON *object, const char *key, size_t out_str_len, char *out_string);
// Given a cJSON object, find the string associated with the key and puts an allocated string into out_string.
// It is the callers responsibility to free out_string.
VkResult loader_parse_json_string(cJSON *object, const char *key, char **out_string);
// Given a cJSON object, find the array of strings associated with they key and writes the count into out_count and data into
// out_array_of_strings. It is the callers responsibility to free out_array_of_strings.
VkResult loader_parse_json_array_of_strings(const struct loader_instance *inst, cJSON *object, const char *key,
struct loader_string_list *string_list);
+5 -6
View File
@@ -33,6 +33,7 @@
#include "loader_environment.h"
#include "loader.h"
#include "log.h"
#include "stack_allocation.h"
// Determine a priority based on device type with the higher value being higher priority.
uint32_t determine_priority_type_value(VkPhysicalDeviceType type) {
@@ -256,7 +257,6 @@ VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32
VkPhysicalDeviceProperties dev_props = {};
sorted_device_info[index].physical_device = icd_devices[icd_idx].physical_devices[phys_dev];
sorted_device_info[index].icd_index = icd_idx;
sorted_device_info[index].icd_term = icd_term;
sorted_device_info[index].has_pci_bus_info = false;
@@ -293,8 +293,8 @@ VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32
if (sorted_device_info[index].has_pci_bus_info) {
VkPhysicalDevicePCIBusInfoPropertiesEXT pci_props = (VkPhysicalDevicePCIBusInfoPropertiesEXT){
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT};
VkPhysicalDeviceProperties2 dev_props2 = (VkPhysicalDeviceProperties2){
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = (VkBaseInStructure *)&pci_props};
VkPhysicalDeviceProperties2 dev_props2 =
(VkPhysicalDeviceProperties2){.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &pci_props};
PFN_vkGetPhysicalDeviceProperties2 GetPhysDevProps2 = NULL;
if (app_is_vulkan_1_1 && device_is_1_1_capable) {
@@ -330,7 +330,6 @@ VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32
// Add all others after (they've already been sorted)
for (uint32_t dev = 0; dev < phys_dev_count; ++dev) {
sorted_device_term[dev]->this_icd_term = sorted_device_info[dev].icd_term;
sorted_device_term[dev]->icd_index = sorted_device_info[dev].icd_index;
sorted_device_term[dev]->phys_dev = sorted_device_info[dev].physical_device;
loader_set_dispatch((void *)sorted_device_term[dev], inst->disp);
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " [%u] %s %s", dev,
@@ -396,8 +395,8 @@ VkResult linux_sort_physical_device_groups(struct loader_instance *inst, uint32_
if (sorted_group_term[group].internal_device_info[gpu].has_pci_bus_info) {
VkPhysicalDevicePCIBusInfoPropertiesEXT pci_props = (VkPhysicalDevicePCIBusInfoPropertiesEXT){
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT};
VkPhysicalDeviceProperties2 dev_props2 = (VkPhysicalDeviceProperties2){
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = (VkBaseInStructure *)&pci_props};
VkPhysicalDeviceProperties2 dev_props2 =
(VkPhysicalDeviceProperties2){.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &pci_props};
PFN_vkGetPhysicalDeviceProperties2 GetPhysDevProps2 = NULL;
if (app_is_vulkan_1_1 && device_is_1_1_capable) {
+72 -67
View File
@@ -79,7 +79,7 @@ void windows_initialization(void) {
// This is needed to ensure that newer APIs are available right away
// and not after the first call that has been statically linked
LoadLibrary("gdi32.dll");
LoadLibraryEx("gdi32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
wchar_t systemPath[MAX_PATH] = L"";
GetSystemDirectoryW(systemPath, MAX_PATH);
@@ -99,7 +99,11 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
(void)hinst;
switch (reason) {
case DLL_PROCESS_ATTACH:
loader_initialize();
// Only initialize necessary sync primitives
loader_platform_thread_create_mutex(&loader_lock);
loader_platform_thread_create_mutex(&loader_preload_icd_lock);
loader_platform_thread_create_mutex(&loader_global_instance_list_lock);
init_global_loader_settings();
break;
case DLL_PROCESS_DETACH:
if (NULL == reserved) {
@@ -141,7 +145,7 @@ bool windows_add_json_entry(const struct loader_instance *inst,
loader_instance_heap_realloc(inst, *reg_data, *total_size, *total_size * 2, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
if (NULL == new_ptr) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
"windows_add_json_entry: Failed to reallocate space for registry value of size %d for key %s",
"windows_add_json_entry: Failed to reallocate space for registry value of size %ld for key %s",
*total_size * 2, json_path);
*result = VK_ERROR_OUT_OF_HOST_MEMORY;
return false;
@@ -179,7 +183,7 @@ bool windows_get_device_registry_entry(const struct loader_instance *inst, char
CONFIGRET status = CM_Open_DevNode_Key(dev_id, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &hkrKey, CM_REGISTRY_SOFTWARE);
if (status != CR_SUCCESS) {
loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
"windows_get_device_registry_entry: Failed to open registry key for DeviceID(%d)", dev_id);
"windows_get_device_registry_entry: Failed to open registry key for DeviceID(%ld)", dev_id);
*result = VK_ERROR_INCOMPATIBLE_DRIVER;
return false;
}
@@ -190,10 +194,10 @@ bool windows_get_device_registry_entry(const struct loader_instance *inst, char
if (ret != ERROR_SUCCESS) {
if (ret == ERROR_FILE_NOT_FOUND) {
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
"windows_get_device_registry_entry: Device ID(%d) Does not contain a value for \"%s\"", dev_id, value_name);
"windows_get_device_registry_entry: Device ID(%ld) Does not contain a value for \"%s\"", dev_id, value_name);
} else {
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
"windows_get_device_registry_entry: DeviceID(%d) Failed to obtain %s size", dev_id, value_name);
"windows_get_device_registry_entry: DeviceID(%ld) Failed to obtain %s size", dev_id, value_name);
}
goto out;
}
@@ -210,7 +214,7 @@ bool windows_get_device_registry_entry(const struct loader_instance *inst, char
if (ret != ERROR_SUCCESS) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
"windows_get_device_registry_entry: DeviceID(%d) Failed to obtain %s", value_name);
"windows_get_device_registry_entry: DeviceID(%ld) Failed to obtain %s", dev_id, value_name);
*result = VK_ERROR_INCOMPATIBLE_DRIVER;
goto out;
}
@@ -304,7 +308,7 @@ VkResult windows_get_device_registry_files(const struct loader_instance *inst, u
status = CM_Get_Child(&childID, devID, 0);
if (status != CR_SUCCESS) {
loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
"windows_get_device_registry_files: unable to open child-device error:%d", status);
"windows_get_device_registry_files: unable to open child-device error:%ld", status);
continue;
}
@@ -313,12 +317,12 @@ VkResult windows_get_device_registry_files(const struct loader_instance *inst, u
CM_Get_Device_IDW(childID, buffer, MAX_DEVICE_ID_LEN, 0);
loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
"windows_get_device_registry_files: Opening child device %d - %ls", childID, buffer);
"windows_get_device_registry_files: Opening child device %ld - %ls", childID, buffer);
status = CM_Get_DevNode_Registry_PropertyW(childID, CM_DRP_CLASSGUID, NULL, &childGuid, &childGuidSize, 0);
if (status != CR_SUCCESS) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
"windows_get_device_registry_files: unable to obtain GUID for:%d error:%d", childID, status);
"windows_get_device_registry_files: unable to obtain GUID for:%ld error:%ld", childID, status);
result = VK_ERROR_INCOMPATIBLE_DRIVER;
continue;
@@ -326,7 +330,7 @@ VkResult windows_get_device_registry_files(const struct loader_instance *inst, u
if (wcscmp(childGuid, softwareComponentGUID) != 0) {
loader_log(inst, VULKAN_LOADER_DEBUG_BIT | log_target_flag, 0,
"windows_get_device_registry_files: GUID for %d is not SoftwareComponent skipping", childID);
"windows_get_device_registry_files: GUID for %ld is not SoftwareComponent skipping", childID);
continue;
}
@@ -447,7 +451,7 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
if (NULL == new_ptr) {
loader_log(
inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
"windows_get_registry_files: Failed to reallocate space for registry value of size %d for key %s",
"windows_get_registry_files: Failed to reallocate space for registry value of size %ld for key %s",
*reg_data_size * 2, name);
RegCloseKey(key);
result = VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -793,21 +797,19 @@ out:
return vk_result;
}
VkResult enumerate_adapter_physical_devices(struct loader_instance *inst, struct loader_icd_term *icd_term, uint32_t icd_idx,
LUID luid, uint32_t *icd_phys_devs_array_count,
VkResult enumerate_adapter_physical_devices(struct loader_instance *inst, struct loader_icd_term *icd_term, LUID luid,
uint32_t *icd_phys_devs_array_count,
struct loader_icd_physical_devices *icd_phys_devs_array) {
uint32_t count = 0;
VkResult res = icd_term->scanned_icd->EnumerateAdapterPhysicalDevices(icd_term->instance, luid, &count, NULL);
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
return res;
} else if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
} else if (res == VK_ERROR_INCOMPATIBLE_DRIVER || res == VK_ERROR_INITIALIZATION_FAILED || 0 == count) {
return VK_SUCCESS; // This driver doesn't support the adapter
} else if (res != VK_SUCCESS) {
loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
"Failed to convert DXGI adapter into Vulkan physical device with unexpected error code");
return res;
} else if (0 == count) {
return VK_SUCCESS; // This driver doesn't support the adapter
"Failed to convert DXGI adapter into Vulkan physical device with unexpected error code: %d", res);
return VK_SUCCESS;
}
// Take a pointer to the last element of icd_phys_devs_array to simplify usage
@@ -856,10 +858,14 @@ VkResult enumerate_adapter_physical_devices(struct loader_instance *inst, struct
}
if (!already_enumerated) {
next_icd_phys_devs->device_count = count;
next_icd_phys_devs->icd_index = icd_idx;
next_icd_phys_devs->icd_term = icd_term;
next_icd_phys_devs->windows_adapter_luid = luid;
(*icd_phys_devs_array_count)++;
} else {
// Avoid memory leak in case of the already_enumerated hitting true
// at the last enumerate_adapter_physical_devices call in the outer loop
loader_instance_heap_free(inst, next_icd_phys_devs->physical_devices);
next_icd_phys_devs->physical_devices = NULL;
}
return VK_SUCCESS;
@@ -962,33 +968,35 @@ VkResult windows_read_sorted_physical_devices(struct loader_instance *inst, uint
continue;
}
if (icd_phys_devs_array_size <= i) {
uint32_t old_size = icd_phys_devs_array_size * sizeof(struct loader_icd_physical_devices);
*icd_phys_devs_array = loader_instance_heap_realloc(inst, *icd_phys_devs_array, old_size, 2 * old_size,
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
if (*icd_phys_devs_array == NULL) {
adapter->lpVtbl->Release(adapter);
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
}
icd_phys_devs_array_size *= 2;
}
(*icd_phys_devs_array)[*icd_phys_devs_array_count].device_count = 0;
(*icd_phys_devs_array)[*icd_phys_devs_array_count].physical_devices = NULL;
icd_term = inst->icd_terms;
for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) {
while (NULL != icd_term) {
// This is the new behavior, which cannot be run unless the ICD provides EnumerateAdapterPhysicalDevices
if (icd_term->scanned_icd->EnumerateAdapterPhysicalDevices == NULL) {
icd_term = icd_term->next;
continue;
}
res = enumerate_adapter_physical_devices(inst, icd_term, icd_idx, description.AdapterLuid, icd_phys_devs_array_count,
if (icd_phys_devs_array_size <= *icd_phys_devs_array_count) {
uint32_t old_size = icd_phys_devs_array_size * sizeof(struct loader_icd_physical_devices);
*icd_phys_devs_array = loader_instance_heap_realloc(inst, *icd_phys_devs_array, old_size, 2 * old_size,
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
if (*icd_phys_devs_array == NULL) {
adapter->lpVtbl->Release(adapter);
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
}
icd_phys_devs_array_size *= 2;
}
(*icd_phys_devs_array)[*icd_phys_devs_array_count].device_count = 0;
(*icd_phys_devs_array)[*icd_phys_devs_array_count].physical_devices = NULL;
res = enumerate_adapter_physical_devices(inst, icd_term, description.AdapterLuid, icd_phys_devs_array_count,
*icd_phys_devs_array);
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
adapter->lpVtbl->Release(adapter);
goto out;
}
icd_term = icd_term->next;
}
adapter->lpVtbl->Release(adapter);
@@ -1103,10 +1111,8 @@ 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 and OpenGL Compatibility Pack
* (so named at the time this is being added), which contains OpenGLOn12 and OpenCLOn12 mapping
* layers, and will contain VulkanOn12 (aka Dozen) going forward.
*/
// This literal string identifies the Microsoft-published OpenCL, OpenGL, and Vulkan Compatibility Pack, which contains
// OpenGLOn12, OpenCLOn12, and VulkanOn12 (aka Dozen) mappinglayers
PCWSTR familyName = L"Microsoft.D3DMappingLayers_8wekyb3d8bbwe";
if (ERROR_INSUFFICIENT_BUFFER != fpGetPackagesByPackageFamily(familyName, &numPackages, NULL, &bufferLength, NULL) ||
numPackages == 0 || bufferLength == 0) {
@@ -1188,12 +1194,15 @@ VkResult get_settings_path_if_exists_in_registry_key(const struct loader_instanc
}
}
// Make sure the path exists first
if (*out_path && !loader_platform_file_exists(name)) {
return VK_ERROR_INITIALIZATION_FAILED;
}
if (strcmp(VK_LOADER_SETTINGS_FILENAME, &(name[start_of_path_filename])) == 0) {
// Make sure the path exists first
if (!loader_platform_file_exists(name)) {
loader_log(
inst, VULKAN_LOADER_DEBUG_BIT, 0,
"Registry contained entry to vk_loader_settings.json but the corresponding file does not exist, ignoring");
return VK_ERROR_INITIALIZATION_FAILED;
}
*out_path = loader_instance_heap_calloc(inst, name_size + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
if (*out_path == NULL) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -1211,41 +1220,37 @@ VkResult get_settings_path_if_exists_in_registry_key(const struct loader_instanc
VkResult windows_get_loader_settings_file_path(const struct loader_instance *inst, char **out_path) {
VkResult result = VK_SUCCESS;
DWORD access_flags = KEY_QUERY_VALUE;
LONG rtn_value = 0;
HKEY key = NULL;
*out_path = NULL;
// if we are running with admin privileges, only check HKEY_LOCAL_MACHINE.
// Otherwise check HKEY_CURRENT_USER, and if nothing is there, look in HKEY_LOCAL_MACHINE
// Search in HKEY_CURRENT_USER first if we are running without admin privileges
// Exit if a settings file was found.
// Otherwise check in HKEY_LOCAL_MACHINE.
if (is_high_integrity()) {
LONG rtn_value = RegOpenKeyEx(HKEY_LOCAL_MACHINE, VK_SETTINGS_INFO_REGISTRY_LOC, 0, access_flags, &key);
if (ERROR_SUCCESS != rtn_value) {
result = VK_ERROR_FEATURE_NOT_PRESENT;
goto out;
}
result = get_settings_path_if_exists_in_registry_key(inst, out_path, key);
} else {
LONG rtn_value = RegOpenKeyEx(HKEY_CURRENT_USER, VK_SETTINGS_INFO_REGISTRY_LOC, 0, access_flags, &key);
if (!is_high_integrity()) {
rtn_value = RegOpenKeyEx(HKEY_CURRENT_USER, VK_SETTINGS_INFO_REGISTRY_LOC, 0, access_flags, &key);
if (ERROR_SUCCESS == rtn_value) {
result = get_settings_path_if_exists_in_registry_key(inst, out_path, key);
RegCloseKey(key);
// Either we got OOM and *must* exit or we successfully found the settings file and can exit
if (result == VK_ERROR_OUT_OF_HOST_MEMORY || result == VK_SUCCESS) {
goto out;
}
RegCloseKey(key);
key = NULL;
}
}
rtn_value = RegOpenKeyEx(HKEY_LOCAL_MACHINE, VK_SETTINGS_INFO_REGISTRY_LOC, 0, access_flags, &key);
if (ERROR_SUCCESS != rtn_value) {
result = VK_ERROR_FEATURE_NOT_PRESENT;
goto out;
}
rtn_value = RegOpenKeyEx(HKEY_LOCAL_MACHINE, VK_SETTINGS_INFO_REGISTRY_LOC, 0, access_flags, &key);
if (ERROR_SUCCESS != rtn_value) {
result = VK_ERROR_FEATURE_NOT_PRESENT;
goto out;
}
result = get_settings_path_if_exists_in_registry_key(inst, out_path, key);
if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
goto out;
}
result = get_settings_path_if_exists_in_registry_key(inst, out_path, key);
if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
goto out;
}
out:
+90 -41
View File
@@ -91,7 +91,54 @@ void loader_init_global_debug_level(void) {
void loader_set_global_debug_level(uint32_t new_loader_debug) { g_loader_debug = new_loader_debug; }
void loader_log(const struct loader_instance *inst, VkFlags msg_type, int32_t msg_code, const char *format, ...) {
void generate_debug_flag_str(VkFlags msg_type, size_t cmd_line_size, char *cmd_line_msg) {
cmd_line_msg[0] = '\0';
if ((msg_type & VULKAN_LOADER_ERROR_BIT) != 0) {
loader_strncat(cmd_line_msg, cmd_line_size, "ERROR", sizeof("ERROR"));
}
if ((msg_type & VULKAN_LOADER_WARN_BIT) != 0) {
if (strlen(cmd_line_msg) > 0) {
loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
}
loader_strncat(cmd_line_msg, cmd_line_size, "WARNING", sizeof("WARNING"));
}
if ((msg_type & VULKAN_LOADER_INFO_BIT) != 0) {
if (strlen(cmd_line_msg) > 0) {
loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
}
loader_strncat(cmd_line_msg, cmd_line_size, "INFO", sizeof("INFO"));
}
if ((msg_type & VULKAN_LOADER_DEBUG_BIT) != 0) {
if (strlen(cmd_line_msg) > 0) {
loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
}
loader_strncat(cmd_line_msg, cmd_line_size, "DEBUG", sizeof("DEBUG"));
}
if ((msg_type & VULKAN_LOADER_PERF_BIT) != 0) {
if (strlen(cmd_line_msg) > 0) {
loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
}
loader_strncat(cmd_line_msg, cmd_line_size, "PERF", sizeof("PERF"));
}
if ((msg_type & VULKAN_LOADER_DRIVER_BIT) != 0) {
if (strlen(cmd_line_msg) > 0) {
loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
}
loader_strncat(cmd_line_msg, cmd_line_size, "DRIVER", sizeof("DRIVER"));
}
if ((msg_type & VULKAN_LOADER_LAYER_BIT) != 0) {
if (strlen(cmd_line_msg) > 0) {
loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
}
loader_strncat(cmd_line_msg, cmd_line_size, "LAYER", sizeof("LAYER"));
}
#undef STRNCAT_TO_BUFFER
}
void DECORATE_PRINTF(4, 5)
loader_log(const struct loader_instance *inst, VkFlags msg_type, int32_t msg_code, const char *format, ...) {
(void)msg_code;
char msg[512] = {0};
@@ -146,70 +193,72 @@ void loader_log(const struct loader_instance *inst, VkFlags msg_type, int32_t ms
// Always log to stderr if this is a fatal error
if (0 == (msg_type & VULKAN_LOADER_FATAL_ERROR_BIT)) {
// Exit early if the current instance settings do not ask for logging to stderr
if (inst && inst->settings.settings_active && 0 == (msg_type & inst->settings.debug_level)) {
return;
if (inst && inst->settings.settings_active && inst->settings.debug_level > 0) {
// Exit early if the current instance settings have some debugging options but do match the current msg_type
if (0 == (msg_type & inst->settings.debug_level)) {
return;
}
// Check the global settings and if that doesn't say to skip, check the environment variable
} else if (0 == (msg_type & g_loader_debug)) {
return;
}
}
#if defined(DEBUG)
int debug_flag_mask =
msg_type & (VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DEBUG_BIT);
assert((debug_flag_mask == 0 || debug_flag_mask == VULKAN_LOADER_ERROR_BIT || debug_flag_mask == VULKAN_LOADER_WARN_BIT ||
debug_flag_mask == VULKAN_LOADER_INFO_BIT || debug_flag_mask == VULKAN_LOADER_DEBUG_BIT) &&
"This log has more than one exclusive debug flags (error, warn, info, debug) set");
#endif
// Only need enough space to create the filter description header for log messages
// Also use the same header for all output
char cmd_line_msg[64];
char cmd_line_msg[64] = {0};
size_t cmd_line_size = sizeof(cmd_line_msg);
size_t num_used = 0;
cmd_line_msg[0] = '\0';
// Helper macro which strncat's the given string literal, then updates num_used & cmd_line_end
// Assumes that we haven't used the entire buffer - must manually check this when adding new filter types
// We concat at the end of cmd_line_msg, so that strncat isn't a victim of Schlemiel the Painter
// We write to the end - 1 of cmd_line_msg, as the end is actually a null terminator
#define STRNCAT_TO_BUFFER(string_literal_to_cat) \
loader_strncat(cmd_line_msg + num_used, cmd_line_size - num_used, string_literal_to_cat, sizeof(string_literal_to_cat)); \
num_used += sizeof(string_literal_to_cat) - 1; // subtract one to remove the null terminator in the string literal
loader_strncat(cmd_line_msg, cmd_line_size, "[Vulkan Loader] ", sizeof("[Vulkan Loader] "));
bool need_separator = false;
if ((msg_type & VULKAN_LOADER_ERROR_BIT) != 0) {
STRNCAT_TO_BUFFER("ERROR");
loader_strncat(cmd_line_msg, cmd_line_size, "ERROR", sizeof("ERROR"));
need_separator = true;
} else if ((msg_type & VULKAN_LOADER_WARN_BIT) != 0) {
STRNCAT_TO_BUFFER("WARNING");
loader_strncat(cmd_line_msg, cmd_line_size, "WARNING", sizeof("WARNING"));
need_separator = true;
} else if ((msg_type & VULKAN_LOADER_INFO_BIT) != 0) {
STRNCAT_TO_BUFFER("INFO");
loader_strncat(cmd_line_msg, cmd_line_size, "INFO", sizeof("INFO"));
need_separator = true;
} else if ((msg_type & VULKAN_LOADER_DEBUG_BIT) != 0) {
STRNCAT_TO_BUFFER("DEBUG");
loader_strncat(cmd_line_msg, cmd_line_size, "DEBUG", sizeof("DEBUG"));
need_separator = true;
}
if ((msg_type & VULKAN_LOADER_PERF_BIT) != 0) {
if (num_used > 1) {
STRNCAT_TO_BUFFER(" | ");
if (need_separator) {
loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
}
STRNCAT_TO_BUFFER("PERF");
}
if ((msg_type & VULKAN_LOADER_DRIVER_BIT) != 0) {
if (num_used > 1) {
STRNCAT_TO_BUFFER(" | ");
loader_strncat(cmd_line_msg, cmd_line_size, "PERF", sizeof("PERF"));
} else if ((msg_type & VULKAN_LOADER_DRIVER_BIT) != 0) {
if (need_separator) {
loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
}
STRNCAT_TO_BUFFER("DRIVER");
}
if ((msg_type & VULKAN_LOADER_LAYER_BIT) != 0) {
if (num_used > 1) {
STRNCAT_TO_BUFFER(" | ");
loader_strncat(cmd_line_msg, cmd_line_size, "DRIVER", sizeof("DRIVER"));
} else if ((msg_type & VULKAN_LOADER_LAYER_BIT) != 0) {
if (need_separator) {
loader_strncat(cmd_line_msg, cmd_line_size, " | ", sizeof(" | "));
}
STRNCAT_TO_BUFFER("LAYER");
loader_strncat(cmd_line_msg, cmd_line_size, "LAYER", sizeof("LAYER"));
}
// Add a ": " to separate the filters from the message
STRNCAT_TO_BUFFER(": ");
#undef STRNCAT_TO_BUFFER
loader_strncat(cmd_line_msg, cmd_line_size, ": ", sizeof(": "));
size_t num_used = strlen(cmd_line_msg);
// Justifies the output to at least 19 spaces
if (num_used < 19) {
const char *space_buffer = " ";
// Only write (19 - num_used) spaces
loader_strncat(cmd_line_msg + num_used, cmd_line_size - num_used, space_buffer, 19 - num_used);
num_used += sizeof(space_buffer) - 1 - num_used;
// Justifies the output to at least 29 spaces
if (num_used < 32) {
const char space_buffer[] = " ";
// Only write (32 - num_used) spaces
loader_strncat(cmd_line_msg, cmd_line_size, space_buffer, sizeof(space_buffer) - 1 - num_used);
}
// Assert that we didn't write more than what is available in cmd_line_msg
assert(cmd_line_size > num_used);
+13 -2
View File
@@ -54,6 +54,9 @@ void loader_init_global_debug_level(void);
// Sets the global debug level - used by global settings files
void loader_set_global_debug_level(uint32_t new_loader_debug);
// Writes a stringified version of enum vulkan_loader_debug_flags into a char array cmd_line_msg of length cmd_line_size
void generate_debug_flag_str(VkFlags msg_type, size_t cmd_line_size, char *cmd_line_msg);
// The asm declaration prevents name mangling which is necessary for macOS
#if defined(MODIFY_UNKNOWN_FUNCTION_DECLS)
#define ASM_NAME(name) __asm(name)
@@ -61,10 +64,18 @@ void loader_set_global_debug_level(uint32_t new_loader_debug);
#define ASM_NAME(name)
#endif
#if defined(__clang__)
#define DECORATE_PRINTF(_fmt_argnum, _first_param_num) __attribute__((format(printf, _fmt_argnum, _first_param_num)))
#elif defined(__GNUC__)
#define DECORATE_PRINTF(_fmt_argnum, _first_param_num) __attribute__((format(gnu_printf, _fmt_argnum, _first_param_num)))
#else
#define DECORATE_PRINTF(_fmt_num, _first_param_num)
#endif
// Logs a message to stderr
// May output to DebugUtils if the instance isn't null and the extension is enabled.
void loader_log(const struct loader_instance *inst, VkFlags msg_type, int32_t msg_code, const char *format, ...)
ASM_NAME("loader_log");
void DECORATE_PRINTF(4, 5) loader_log(const struct loader_instance *inst, VkFlags msg_type, int32_t msg_code, const char *format,
...) ASM_NAME("loader_log");
// Used for the assembly code to emit an specific error message
// This is a work around for linux 32 bit error handling not passing relocatable strings correctly
+1 -1
View File
@@ -28,7 +28,7 @@
// unknown to the loader, it will use this code. Technically, this is not trampoline
// code since we don't want to optimize it out.
#include "loader.h"
#include <vulkan/vulkan.h>
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC optimize(3) // force gcc to use tail-calls
+161 -100
View File
@@ -27,7 +27,10 @@
#include "cJSON.h"
#include "loader.h"
#include "loader_environment.h"
#include "loader_json.h"
#if defined(WIN32)
#include "loader_windows.h"
#endif
#include "log.h"
#include "stack_allocation.h"
#include "vk_loader_platform.h"
@@ -106,17 +109,15 @@ uint32_t parse_log_filters_from_strings(struct loader_string_list* log_filters)
return filters;
}
bool parse_json_enable_disable_option(const struct loader_instance* inst, cJSON* object, const char* key) {
char* str = NULL;
VkResult res = loader_parse_json_string(object, key, &str);
if (res != VK_SUCCESS || NULL == str) {
bool parse_json_enable_disable_option(cJSON* object) {
char* str = loader_cJSON_GetStringValue(object);
if (NULL == str) {
return false;
}
bool enable = false;
if (strcmp(str, "enabled") == 0) {
enable = true;
}
loader_instance_heap_free(inst, str);
return enable;
}
@@ -160,8 +161,9 @@ VkResult parse_layer_configurations(const struct loader_instance* inst, cJSON* s
VkResult res = VK_SUCCESS;
cJSON* layer_configurations = loader_cJSON_GetObjectItem(settings_object, "layers");
// If the layers object isn't present, return early with success to allow the settings file to still apply
if (NULL == layer_configurations) {
return VK_ERROR_INITIALIZATION_FAILED;
return VK_SUCCESS;
}
uint32_t layer_configurations_count = loader_cJSON_GetArraySize(layer_configurations);
@@ -178,13 +180,14 @@ VkResult parse_layer_configurations(const struct loader_instance* inst, cJSON* s
goto out;
}
for (uint32_t i = 0; i < layer_configurations_count; i++) {
cJSON* layer = loader_cJSON_GetArrayItem(layer_configurations, i);
if (NULL == layer) {
cJSON* layer = NULL;
size_t i = 0;
cJSON_ArrayForEach(layer, layer_configurations) {
if (layer->type != cJSON_Object) {
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
}
res = parse_layer_configuration(inst, layer, &(loader_settings->layer_configurations[i]));
res = parse_layer_configuration(inst, layer, &(loader_settings->layer_configurations[i++]));
if (VK_SUCCESS != res) {
goto out;
}
@@ -192,8 +195,8 @@ VkResult parse_layer_configurations(const struct loader_instance* inst, cJSON* s
out:
if (res != VK_SUCCESS) {
if (loader_settings->layer_configurations) {
for (uint32_t i = 0; i < loader_settings->layer_configuration_count; i++) {
free_layer_configuration(inst, &(loader_settings->layer_configurations[i]));
for (size_t index = 0; index < loader_settings->layer_configuration_count; index++) {
free_layer_configuration(inst, &(loader_settings->layer_configurations[index]));
}
loader_settings->layer_configuration_count = 0;
loader_instance_heap_free(inst, loader_settings->layer_configurations);
@@ -204,7 +207,8 @@ out:
return res;
}
VkResult check_if_settings_path_exists(const struct loader_instance* inst, char* base, char* suffix, char** settings_file_path) {
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;
}
@@ -276,12 +280,24 @@ void log_settings(const struct loader_instance* inst, loader_settings* settings)
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "Using layer configurations found in loader settings from %s",
settings->settings_file_path);
char cmd_line_msg[64] = {0};
size_t cmd_line_size = sizeof(cmd_line_msg);
cmd_line_msg[0] = '\0';
generate_debug_flag_str(settings->debug_level, cmd_line_size, cmd_line_msg);
if (strlen(cmd_line_msg)) {
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Loader Settings Filters for Logging to Standard Error: %s", cmd_line_msg);
}
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Layer Configurations count = %d", settings->layer_configuration_count);
for (uint32_t i = 0; i < settings->layer_configuration_count; i++) {
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "---- Layer Configuration [%d] ----", i);
if (settings->layer_configurations[i].control != LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION) {
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Name: %s", settings->layer_configurations[i].name);
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Path: %s", settings->layer_configurations[i].path);
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Layer Type: %s",
settings->layer_configurations[i].treat_as_implicit_manifest ? "Implicit" : "Explicit");
}
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Control: %s",
loader_settings_layer_control_to_string(settings->layer_configurations[i].control));
@@ -300,12 +316,16 @@ VkResult get_loader_settings(const struct loader_instance* inst, loader_settings
#if defined(WIN32)
res = windows_get_loader_settings_file_path(inst, &settings_file_path);
if (res != VK_SUCCESS) {
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
"No valid vk_loader_settings.json file found, no loader settings will be active");
goto out;
}
#elif COMMON_UNIX_PLATFORMS
res = get_unix_settings_path(inst, &settings_file_path);
if (res != VK_SUCCESS) {
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
"No valid vk_loader_settings.json file found, no loader settings will be active");
goto out;
}
#else
@@ -314,93 +334,101 @@ VkResult get_loader_settings(const struct loader_instance* inst, loader_settings
res = loader_get_json(inst, settings_file_path, &json);
// Make sure sure the top level json value is an object
if (res != VK_SUCCESS || NULL == json || json->type != 6) {
if (res != VK_SUCCESS || NULL == json || json->type != cJSON_Object) {
goto out;
}
res = loader_parse_json_string(json, "file_format_version", &file_format_version_string);
if (res != VK_SUCCESS) {
if (res != VK_ERROR_OUT_OF_HOST_MEMORY) {
loader_log(
inst, VULKAN_LOADER_DEBUG_BIT, 0,
"Loader settings file from %s missing required field file_format_version - no loader settings will be active",
settings_file_path);
}
goto out;
}
uint32_t settings_array_count = 0;
bool has_multi_setting_file = false;
// Because the file may contain either a "settings_array" or a single "settings" object, we need to create a cJSON so that we
// can iterate on both cases with common code
cJSON settings_iter_parent = {0};
cJSON* settings_array = loader_cJSON_GetObjectItem(json, "settings_array");
cJSON* single_settings_object = loader_cJSON_GetObjectItem(json, "settings");
if (NULL != settings_array) {
has_multi_setting_file = true;
settings_array_count = loader_cJSON_GetArraySize(settings_array);
memcpy(&settings_iter_parent, settings_array, sizeof(cJSON));
} else if (NULL != single_settings_object) {
settings_array_count = 1;
settings_iter_parent.child = single_settings_object;
} else if (settings_array == NULL && single_settings_object) {
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
"Loader settings file from %s missing required settings objects: Either one of the \"settings\" or "
"\"settings_array\" objects must be present - no loader settings will be active",
settings_file_path);
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
}
// Corresponds to the settings object that has no app keys
int global_settings_index = -1;
cJSON* global_settings = NULL;
// Corresponds to the settings object which has a matching app key
int index_to_use = -1;
cJSON* settings_to_use = NULL;
char current_process_path[1024];
bool valid_exe_path = NULL != loader_platform_executable_path(current_process_path, 1024);
for (int i = 0; i < (int)settings_array_count; i++) {
if (has_multi_setting_file) {
single_settings_object = loader_cJSON_GetArrayItem(settings_array, i);
cJSON* settings_object_iter = NULL;
cJSON_ArrayForEach(settings_object_iter, &settings_iter_parent) {
if (settings_object_iter->type != cJSON_Object) {
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
"Loader settings file from %s has a settings element that is not an object", settings_file_path);
break;
}
cJSON* app_keys = loader_cJSON_GetObjectItem(single_settings_object, "app_keys");
cJSON* app_keys = loader_cJSON_GetObjectItem(settings_object_iter, "app_keys");
if (NULL == app_keys) {
if (global_settings_index == -1) {
global_settings_index = i; // use the first 'global' settings that has no app keys as the global one
// use the first 'global' settings that has no app keys as the global one
if (global_settings == NULL) {
global_settings = settings_object_iter;
}
continue;
} else if (valid_exe_path) {
int app_key_count = loader_cJSON_GetArraySize(app_keys);
if (app_key_count == 0) {
continue; // empty array
}
// No sense iterating if we couldn't get the executable path
if (!valid_exe_path) {
break;
}
cJSON* app_key = NULL;
cJSON_ArrayForEach(app_key, app_keys) {
char* app_key_str = loader_cJSON_GetStringValue(app_key);
if (app_key_str && strcmp(current_process_path, app_key_str) == 0) {
settings_to_use = settings_object_iter;
break;
}
for (int j = 0; j < app_key_count; j++) {
cJSON* app_key_json = loader_cJSON_GetArrayItem(app_keys, j);
if (NULL == app_key_json) {
continue;
}
char* app_key = loader_cJSON_Print(app_key_json);
if (NULL == app_key) {
continue;
}
}
if (strcmp(current_process_path, app_key) == 0) {
index_to_use = i;
}
loader_instance_heap_free(inst, app_key);
if (index_to_use == i) {
break; // break only after freeing the app key
}
}
// Break if we have found a matching current_process_path
if (NULL != settings_to_use) {
break;
}
}
// No app specific settings match - either use global settings or exit
if (index_to_use == -1) {
if (global_settings_index == -1) {
if (settings_to_use == NULL) {
if (global_settings == NULL) {
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
"Loader settings file from %s missing global settings and none of the app specific settings matched the "
"current application - no loader settings will be active",
settings_file_path);
goto out; // No global settings were found - exit
} else {
index_to_use = global_settings_index; // Global settings are present - use it
}
}
// Now get the actual settings object to use - already have it if there is only one settings object
// If there are multiple settings, just need to set single_settings_object to the desired settings object
if (has_multi_setting_file) {
single_settings_object = loader_cJSON_GetArrayItem(settings_array, index_to_use);
if (NULL == single_settings_object) {
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
settings_to_use = global_settings; // Global settings are present - use it
}
}
// optional
cJSON* stderr_filter = loader_cJSON_GetObjectItem(single_settings_object, "stderr_log");
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, single_settings_object, "stderr_log", &stderr_log);
res = loader_parse_json_array_of_strings(inst, settings_to_use, "stderr_log", &stderr_log);
if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
goto out;
}
@@ -409,30 +437,27 @@ VkResult get_loader_settings(const struct loader_instance* inst, loader_settings
}
// optional
cJSON* logs_to_use = loader_cJSON_GetObjectItem(single_settings_object, "log_locations");
cJSON* logs_to_use = loader_cJSON_GetObjectItem(settings_to_use, "log_locations");
if (NULL != logs_to_use) {
int log_count = loader_cJSON_GetArraySize(logs_to_use);
for (int i = 0; i < log_count; i++) {
cJSON* log_element = loader_cJSON_GetArrayItem(logs_to_use, i);
cJSON* log_element = NULL;
cJSON_ArrayForEach(log_element, logs_to_use) {
// bool is_valid = true;
if (NULL != log_element) {
struct loader_string_list log_destinations = {0};
res = loader_parse_json_array_of_strings(inst, log_element, "destinations", &log_destinations);
if (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) {
// is_valid = false;
}
free_string_list(inst, &log_filters);
struct loader_string_list log_destinations = {0};
res = loader_parse_json_array_of_strings(inst, log_element, "destinations", &log_destinations);
if (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) {
// is_valid = false;
}
free_string_list(inst, &log_filters);
}
}
res = parse_layer_configurations(inst, single_settings_object, loader_settings);
res = parse_layer_configurations(inst, settings_to_use, loader_settings);
if (res != VK_SUCCESS) {
goto out;
}
@@ -460,7 +485,7 @@ out:
return res;
}
VkResult update_global_loader_settings(void) {
TEST_FUNCTION_EXPORT VkResult update_global_loader_settings(void) {
loader_settings settings = {0};
VkResult res = get_loader_settings(NULL, &settings);
loader_platform_thread_lock_mutex(&global_loader_settings_lock);
@@ -472,7 +497,7 @@ VkResult update_global_loader_settings(void) {
}
memcpy(&global_loader_settings, &settings, sizeof(loader_settings));
if (global_loader_settings.settings_active) {
if (global_loader_settings.settings_active && global_loader_settings.debug_level > 0) {
loader_set_global_debug_level(global_loader_settings.debug_level);
}
}
@@ -514,8 +539,8 @@ void release_current_settings_lock(const struct loader_instance* inst) {
}
}
VkResult get_settings_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
bool* should_search_for_other_layers) {
TEST_FUNCTION_EXPORT VkResult get_settings_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
bool* should_search_for_other_layers) {
VkResult res = VK_SUCCESS;
*should_search_for_other_layers = true; // default to true
@@ -577,6 +602,9 @@ VkResult get_settings_layers(const struct loader_instance* inst, struct loader_l
continue;
}
// Makes it possible to know if a new layer was added or not, since the only return value is VkResult
size_t count_before_adding = settings_layers->count;
local_res =
loader_add_layer_properties(inst, settings_layers, json, layer_config->treat_as_implicit_manifest, layer_config->path);
loader_cJSON_Delete(json);
@@ -585,10 +613,15 @@ VkResult get_settings_layers(const struct loader_instance* inst, struct loader_l
if (VK_ERROR_OUT_OF_HOST_MEMORY == local_res) {
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
} else if (local_res != VK_SUCCESS || count_before_adding == settings_layers->count) {
// Indicates something was wrong with the layer, can't add it to the list
continue;
}
struct loader_layer_properties* newly_added_layer = &settings_layers->list[settings_layers->count - 1];
newly_added_layer->settings_control_value = layer_config->control;
// If the manifest file found has a name that differs from the one in the settings, remove this layer from consideration
// If the manifest file found has a name that differs from the one in the settings, remove this layer from
// consideration
bool should_remove = false;
if (strncmp(newly_added_layer->info.layerName, layer_config->name, VK_MAX_EXTENSION_NAME_SIZE) != 0) {
should_remove = true;
@@ -616,16 +649,24 @@ out:
}
// Check if layers has an element with the same name.
// LAYER_CONTROL_OFF layers are missing some fields, just make sure the layerName is the same
// If layer_property is a meta layer, just make sure the layerName is the same
// Skip comparing to UNORDERED_LAYER_LOCATION
// If layer_property is a regular layer, check if the lib_path is the same.
// If layer_property is a meta layer, just use the layerName
// Make sure that the lib_name pointers are non-null before calling strcmp.
bool check_if_layer_is_in_list(struct loader_layer_list* layer_list, struct loader_layer_properties* layer_property) {
// If the layer is a meta layer, just check against the name
for (uint32_t i = 0; i < layer_list->count; i++) {
if (0 == strncmp(layer_list->list[i].info.layerName, layer_property->info.layerName, VK_MAX_EXTENSION_NAME_SIZE)) {
if (0 == (layer_property->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER) &&
strcmp(layer_list->list[i].lib_name, layer_property->lib_name) == 0) {
if (layer_list->list[i].settings_control_value == LOADER_SETTINGS_LAYER_CONTROL_OFF) {
return true;
}
if (VK_LAYER_TYPE_FLAG_META_LAYER == (layer_property->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
return true;
}
if (layer_list->list[i].lib_name && layer_property->lib_name) {
return strcmp(layer_list->list[i].lib_name, layer_property->lib_name) == 0;
}
}
}
return false;
@@ -724,6 +765,7 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst,
if (vk_instance_layers_env != NULL) {
vk_instance_layers_env_len = strlen(vk_instance_layers_env) + 1;
vk_instance_layers_env_copy = loader_stack_alloc(vk_instance_layers_env_len);
memset(vk_instance_layers_env_copy, 0, vk_instance_layers_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, vk_instance_layers_env);
@@ -732,6 +774,11 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst,
bool enable_layer = false;
struct loader_layer_properties* props = &instance_layers->list[i];
// Skip the sentinel unordered layer location
if (props->settings_control_value == LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION) {
continue;
}
// Do not enable the layer if the settings have it set as off
if (props->settings_control_value == LOADER_SETTINGS_LAYER_CONTROL_OFF) {
continue;
@@ -739,33 +786,45 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst,
// Force enable it based on settings
if (props->settings_control_value == LOADER_SETTINGS_LAYER_CONTROL_ON) {
enable_layer = true;
}
props->enabled_by_what = ENABLED_BY_WHAT_LOADER_SETTINGS_FILE;
} else {
// Check if disable filter needs to skip the layer
if ((filters->disable_filter.disable_all || filters->disable_filter.disable_all_implicit ||
check_name_matches_filter_environment_var(props->info.layerName, &filters->disable_filter.additional_filters)) &&
!check_name_matches_filter_environment_var(props->info.layerName, &filters->allow_filter)) {
// Report a message that we've forced off a layer if it would have been enabled normally.
loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0,
"Layer \"%s\" forced disabled because name matches filter of env var \'%s\'.", props->info.layerName,
VK_LAYERS_DISABLE_ENV_VAR);
// Check if disable filter needs to skip the layer
if ((filters->disable_filter.disable_all || filters->disable_filter.disable_all_implicit ||
check_name_matches_filter_environment_var(props->info.layerName, &filters->disable_filter.additional_filters)) &&
!check_name_matches_filter_environment_var(props->info.layerName, &filters->allow_filter)) {
continue;
continue;
}
}
// Check the enable filter
if (!enable_layer && check_name_matches_filter_environment_var(props->info.layerName, &filters->enable_filter)) {
enable_layer = true;
props->enabled_by_what = ENABLED_BY_WHAT_VK_LOADER_LAYERS_ENABLE;
loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0,
"Layer \"%s\" forced enabled due to env var \'%s\'.", props->info.layerName, VK_LAYERS_ENABLE_ENV_VAR);
}
// First look for the old-fashion layers forced on with VK_INSTANCE_LAYERS
if (!enable_layer && vk_instance_layers_env && vk_instance_layers_env_copy && vk_instance_layers_env_len > 0) {
// Copy the env-var on each iteration, so that loader_get_next_path can correctly find the separators
// This solution only needs one stack allocation ahead of time rather than an allocation per layer in the env-var
// This solution only needs one stack allocation ahead of time rather than an allocation per layer in the
// env-var
loader_strncpy(vk_instance_layers_env_copy, vk_instance_layers_env_len, vk_instance_layers_env,
vk_instance_layers_env_len);
while (vk_instance_layers_env_copy && *vk_instance_layers_env_copy) {
char* next = loader_get_next_path(vk_instance_layers_env_copy);
if (0 == strcmp(vk_instance_layers_env_copy, props->info.layerName)) {
char* instance_layers_env_iter = vk_instance_layers_env_copy;
while (instance_layers_env_iter && *instance_layers_env_iter) {
char* next = loader_get_next_path(instance_layers_env_iter);
if (0 == strcmp(instance_layers_env_iter, props->info.layerName)) {
enable_layer = true;
props->enabled_by_what = ENABLED_BY_WHAT_VK_INSTANCE_LAYERS;
break;
}
vk_instance_layers_env_copy = next;
instance_layers_env_iter = next;
}
}
@@ -774,6 +833,7 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst,
for (uint32_t j = 0; j < app_enabled_name_count; j++) {
if (strcmp(props->info.layerName, app_enabled_names[j]) == 0) {
enable_layer = true;
props->enabled_by_what = ENABLED_BY_WHAT_IN_APPLICATION_API;
break;
}
}
@@ -783,6 +843,7 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst,
if (!enable_layer && (0 == (props->type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER)) &&
loader_implicit_layer_is_enabled(inst, filters, props)) {
enable_layer = true;
props->enabled_by_what = ENABLED_BY_WHAT_IMPLICIT_LAYER;
}
if (enable_layer) {
+4 -4
View File
@@ -23,7 +23,6 @@
#pragma once
#include <stdio.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
@@ -31,6 +30,7 @@
#include "vulkan/vulkan_core.h"
#include "log.h"
#include "vk_loader_platform.h"
struct loader_instance;
struct loader_layer_list;
@@ -84,7 +84,7 @@ void free_loader_settings(const struct loader_instance* inst, loader_settings* l
void log_settings(const struct loader_instance* inst, loader_settings* settings);
// Every global function needs to call this at startup to insure that
VkResult update_global_loader_settings(void);
TEST_FUNCTION_EXPORT VkResult update_global_loader_settings(void);
// Needs to be called during startup -
void init_global_loader_settings(void);
@@ -95,8 +95,8 @@ bool should_skip_logging_global_messages(VkFlags msg_type);
// Query the current settings (either global or per-instance) and return the list of layers contained within.
// should_search_for_other_layers tells the caller if the settings file should be used exclusively for layer searching or not
VkResult get_settings_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
bool* should_search_for_other_layers);
TEST_FUNCTION_EXPORT VkResult get_settings_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
bool* should_search_for_other_layers);
// Take the provided list of settings_layers and add in the layers from regular search paths
// Only adds layers that aren't already present in the settings_layers and in the location of the
+2
View File
@@ -28,6 +28,8 @@
#pragma once
#include "vk_loader_platform.h"
#if defined(_WIN32)
#include <malloc.h>
#elif defined(HAVE_ALLOCA_H)
+11 -7
View File
@@ -31,10 +31,10 @@
// Terminators which have simple logic belong here, since they are mostly "pass through"
// Function declarations are in vk_loader_extensions.h, thus not needed here
#include "allocation.h"
#include "loader_common.h"
#include "loader.h"
#include "log.h"
#include "stack_allocation.h"
// Terminators for 1.0 functions
@@ -156,9 +156,11 @@ VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures2(VkPhysicalDevic
// Write to the VkPhysicalDeviceFeatures2 struct
icd_term->dispatch.GetPhysicalDeviceFeatures(phys_dev_term->phys_dev, &pFeatures->features);
const VkBaseInStructure *pNext = pFeatures->pNext;
void *pNext = pFeatures->pNext;
while (pNext != NULL) {
switch (pNext->sType) {
VkBaseOutStructure pNext_in_structure = {0};
memcpy(&pNext_in_structure, pNext, sizeof(VkBaseOutStructure));
switch (pNext_in_structure.sType) {
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: {
// Skip the check if VK_KHR_multiview is enabled because it's a device extension
// Write to the VkPhysicalDeviceMultiviewFeaturesKHR struct
@@ -175,7 +177,7 @@ VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures2(VkPhysicalDevic
"vkGetPhysicalDeviceFeatures2: Emulation found unrecognized structure type in pFeatures->pNext - "
"this struct will be ignored");
pNext = pNext->pNext;
pNext = pNext_in_structure.pNext;
break;
}
}
@@ -212,9 +214,11 @@ VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties2(VkPhysicalDev
// Write to the VkPhysicalDeviceProperties2 struct
icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &pProperties->properties);
const VkBaseInStructure *pNext = pProperties->pNext;
void *pNext = pProperties->pNext;
while (pNext != NULL) {
switch (pNext->sType) {
VkBaseOutStructure pNext_in_structure = {0};
memcpy(&pNext_in_structure, pNext, sizeof(VkBaseOutStructure));
switch (pNext_in_structure.sType) {
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {
VkPhysicalDeviceIDPropertiesKHR *id_properties = (VkPhysicalDeviceIDPropertiesKHR *)pNext;
@@ -238,7 +242,7 @@ VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties2(VkPhysicalDev
"vkGetPhysicalDeviceProperties2KHR: Emulation found unrecognized structure type in "
"pProperties->pNext - this struct will be ignored");
pNext = pNext->pNext;
pNext = pNext_in_structure.pNext;
break;
}
}
+495 -69
View File
@@ -138,8 +138,7 @@ LOADER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDev
// sufficient
if (!strcmp(name, "GetDeviceQueue2")) {
struct loader_device *dev = NULL;
uint32_t index = 0;
struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &index);
struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev);
if (NULL != icd_term && dev != NULL) {
const struct loader_instance *inst = icd_term->this_instance;
uint32_t api_version =
@@ -178,15 +177,13 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionPropert
.version = VK_CURRENT_CHAIN_VERSION,
.size = sizeof(chain_tail),
},
.pfnNextLayer = &terminator_EnumerateInstanceExtensionProperties,
.pfnNextLayer = &terminator_pre_instance_EnumerateInstanceExtensionProperties,
.pNextLink = NULL,
};
VkEnumerateInstanceExtensionPropertiesChain *chain_head = &chain_tail;
// Get the implicit layers
struct loader_layer_list layers = {0};
loader_platform_dl_handle *libs = NULL;
size_t lib_count = 0;
memset(&layers, 0, sizeof(layers));
struct loader_envvar_all_filters layer_filters = {0};
@@ -200,11 +197,6 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionPropert
return res;
}
res = loader_init_library_list(&layers, &libs);
if (VK_SUCCESS != res) {
return res;
}
// Prepend layers onto the chain if they implement this entry point
for (uint32_t i = 0; i < layers.count; ++i) {
// Skip this layer if it doesn't expose the entry-point
@@ -212,15 +204,12 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionPropert
continue;
}
loader_platform_dl_handle layer_lib = loader_platform_open_library(layers.list[i].lib_name);
if (layer_lib == NULL) {
loader_log(NULL, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0,
"%s: Unable to load implicit layer library \"%s\"", __FUNCTION__, layers.list[i].lib_name);
loader_open_layer_file(NULL, &layers.list[i]);
if (layers.list[i].lib_handle == NULL) {
continue;
}
libs[lib_count++] = layer_lib;
void *pfn = loader_platform_get_proc_address(layer_lib,
void *pfn = loader_platform_get_proc_address(layers.list[i].lib_handle,
layers.list[i].pre_instance_functions.enumerate_instance_extension_properties);
if (pfn == NULL) {
loader_log(NULL, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0,
@@ -260,12 +249,6 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionPropert
loader_free(NULL, holder);
}
// Close the dl handles
for (size_t i = 0; i < lib_count; ++i) {
loader_platform_close_library(libs[i]);
}
loader_free(NULL, libs);
return res;
}
@@ -284,15 +267,13 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
.version = VK_CURRENT_CHAIN_VERSION,
.size = sizeof(chain_tail),
},
.pfnNextLayer = &terminator_EnumerateInstanceLayerProperties,
.pfnNextLayer = &terminator_pre_instance_EnumerateInstanceLayerProperties,
.pNextLink = NULL,
};
VkEnumerateInstanceLayerPropertiesChain *chain_head = &chain_tail;
// Get the implicit layers
struct loader_layer_list layers;
loader_platform_dl_handle *libs = NULL;
size_t lib_count = 0;
memset(&layers, 0, sizeof(layers));
struct loader_envvar_all_filters layer_filters = {0};
@@ -306,11 +287,6 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
return res;
}
res = loader_init_library_list(&layers, &libs);
if (VK_SUCCESS != res) {
return res;
}
// Prepend layers onto the chain if they implement this entry point
for (uint32_t i = 0; i < layers.count; ++i) {
// Skip this layer if it doesn't expose the entry-point
@@ -318,16 +294,13 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
continue;
}
loader_platform_dl_handle layer_lib = loader_platform_open_library(layers.list[i].lib_name);
if (layer_lib == NULL) {
loader_log(NULL, VULKAN_LOADER_WARN_BIT, 0, "%s: Unable to load implicit layer library \"%s\"", __FUNCTION__,
layers.list[i].lib_name);
loader_open_layer_file(NULL, &layers.list[i]);
if (layers.list[i].lib_handle == NULL) {
continue;
}
libs[lib_count++] = layer_lib;
void *pfn =
loader_platform_get_proc_address(layer_lib, layers.list[i].pre_instance_functions.enumerate_instance_layer_properties);
void *pfn = loader_platform_get_proc_address(layers.list[i].lib_handle,
layers.list[i].pre_instance_functions.enumerate_instance_layer_properties);
if (pfn == NULL) {
loader_log(NULL, VULKAN_LOADER_WARN_BIT, 0, "%s: Unable to resolve symbol \"%s\" in implicit layer library \"%s\"",
__FUNCTION__, layers.list[i].pre_instance_functions.enumerate_instance_layer_properties,
@@ -366,12 +339,6 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
loader_free(NULL, holder);
}
// Close the dl handles
for (size_t i = 0; i < lib_count; ++i) {
loader_platform_close_library(libs[i]);
}
loader_free(NULL, libs);
return res;
}
@@ -397,15 +364,13 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(uint32_t
.version = VK_CURRENT_CHAIN_VERSION,
.size = sizeof(chain_tail),
},
.pfnNextLayer = &terminator_EnumerateInstanceVersion,
.pfnNextLayer = &terminator_pre_instance_EnumerateInstanceVersion,
.pNextLink = NULL,
};
VkEnumerateInstanceVersionChain *chain_head = &chain_tail;
// Get the implicit layers
struct loader_layer_list layers;
loader_platform_dl_handle *libs = NULL;
size_t lib_count = 0;
memset(&layers, 0, sizeof(layers));
struct loader_envvar_all_filters layer_filters = {0};
@@ -419,11 +384,6 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(uint32_t
return res;
}
res = loader_init_library_list(&layers, &libs);
if (VK_SUCCESS != res) {
return res;
}
// Prepend layers onto the chain if they implement this entry point
for (uint32_t i = 0; i < layers.count; ++i) {
// Skip this layer if it doesn't expose the entry-point
@@ -431,15 +391,13 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(uint32_t
continue;
}
loader_platform_dl_handle layer_lib = loader_platform_open_library(layers.list[i].lib_name);
if (layer_lib == NULL) {
loader_log(NULL, VULKAN_LOADER_WARN_BIT, 0, "%s: Unable to load implicit layer library \"%s\"", __FUNCTION__,
layers.list[i].lib_name);
loader_open_layer_file(NULL, &layers.list[i]);
if (layers.list[i].lib_handle == NULL) {
continue;
}
libs[lib_count++] = layer_lib;
void *pfn = loader_platform_get_proc_address(layer_lib, layers.list[i].pre_instance_functions.enumerate_instance_version);
void *pfn = loader_platform_get_proc_address(layers.list[i].lib_handle,
layers.list[i].pre_instance_functions.enumerate_instance_version);
if (pfn == NULL) {
loader_log(NULL, VULKAN_LOADER_WARN_BIT, 0, "%s: Unable to resolve symbol \"%s\" in implicit layer library \"%s\"",
__FUNCTION__, layers.list[i].pre_instance_functions.enumerate_instance_version, layers.list[i].lib_name);
@@ -477,12 +435,6 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(uint32_t
loader_free(NULL, holder);
}
// Close the dl handles
for (size_t i = 0; i < lib_count; ++i) {
loader_platform_close_library(libs[i]);
}
loader_free(NULL, libs);
return res;
}
@@ -598,7 +550,8 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCr
}
// Providing an apiVersion less than VK_API_VERSION_1_0 but greater than zero prevents the validation layers from starting
if (pCreateInfo->pApplicationInfo && pCreateInfo->pApplicationInfo->apiVersion < VK_API_VERSION_1_0) {
if (pCreateInfo->pApplicationInfo && pCreateInfo->pApplicationInfo->apiVersion != 0u &&
pCreateInfo->pApplicationInfo->apiVersion < VK_API_VERSION_1_0) {
loader_log(ptr_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
"VkInstanceCreateInfo::pApplicationInfo::apiVersion has value of %u which is not permitted. If apiVersion is "
"not 0, then it must be "
@@ -768,6 +721,10 @@ out:
free_loader_settings(ptr_instance, &ptr_instance->settings);
loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->surfaces_list);
loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->debug_utils_messengers_list);
loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->debug_report_callbacks_list);
loader_instance_heap_free(ptr_instance, ptr_instance->disp);
// Remove any created VK_EXT_debug_report or VK_EXT_debug_utils items
destroy_debug_callbacks_chain(ptr_instance, pAllocator);
@@ -776,7 +733,7 @@ out:
loader_destroy_pointer_layer_list(ptr_instance, &ptr_instance->app_activated_layer_list);
loader_delete_layer_list_and_properties(ptr_instance, &ptr_instance->instance_layer_list);
loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_tramp_list);
loader_clear_scanned_icd_list(ptr_instance, &ptr_instance->icd_tramp_list);
loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->ext_list);
// Free any icd_terms that were created.
@@ -788,6 +745,7 @@ out:
// Call destroy Instance on each driver in case we successfully called down the chain but failed on
// our way back out of it.
if (icd_term->instance) {
loader_icd_close_objects(ptr_instance, icd_term);
icd_term->dispatch.DestroyInstance(icd_term->instance, pAllocator);
}
icd_term->instance = VK_NULL_HANDLE;
@@ -841,6 +799,10 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance,
free_loader_settings(ptr_instance, &ptr_instance->settings);
loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->surfaces_list);
loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->debug_utils_messengers_list);
loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->debug_report_callbacks_list);
loader_destroy_pointer_layer_list(ptr_instance, &ptr_instance->expanded_activated_layer_list);
loader_destroy_pointer_layer_list(ptr_instance, &ptr_instance->app_activated_layer_list);
@@ -898,11 +860,15 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstan
if (VK_SUCCESS != update_res) {
res = update_res;
}
// Unloads any drivers that do not expose any physical devices - should save some address space
unload_drivers_without_physical_devices(inst);
}
out:
loader_platform_thread_unlock_mutex(&loader_lock);
return res;
}
@@ -2606,15 +2572,14 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups(
inst = loader_get_instance(instance);
if (NULL == inst) {
loader_log(
NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
"vkEnumeratePhysicalDeviceGroupsKHR: Invalid instance [VUID-vkEnumeratePhysicalDeviceGroups-instance-parameter]");
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
"vkEnumeratePhysicalDeviceGroups: Invalid instance [VUID-vkEnumeratePhysicalDeviceGroups-instance-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
if (NULL == pPhysicalDeviceGroupCount) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
"vkEnumeratePhysicalDeviceGroupsKHR: Received NULL pointer for physical "
"vkEnumeratePhysicalDeviceGroups: Received NULL pointer for physical "
"device group count return value.");
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
@@ -3182,6 +3147,12 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolProperties(V
VkPhysicalDeviceToolProperties *pToolProperties) {
VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
if (NULL == disp) {
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
"vkGetPhysicalDeviceToolProperties: Invalid physicalDevice "
"[VUID-vkGetPhysicalDeviceToolProperties-physicalDevice-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
return disp->GetPhysicalDeviceToolProperties(unwrapped_phys_dev, pToolCount, pToolProperties);
}
@@ -3190,6 +3161,12 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolProperties(V
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBeginRendering(VkCommandBuffer commandBuffer, const VkRenderingInfo *pRenderingInfo) {
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,
"vkCmdBeginRendering: Invalid commandBuffer "
"[VUID-vkCmdBeginRendering-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdBeginRendering(commandBuffer, pRenderingInfo);
}
@@ -3198,122 +3175,254 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2(VkCommandBuffer
const VkDeviceSize *pOffsets, const VkDeviceSize *pSizes,
const VkDeviceSize *pStrides) {
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,
"vkCmdBindVertexBuffers2: Invalid commandBuffer "
"[VUID-vkCmdBindVertexBuffers2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdBindVertexBuffers2(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes, pStrides);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2(VkCommandBuffer commandBuffer, const VkBlitImageInfo2 *pBlitImageInfo) {
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,
"vkCmdBlitImage2: Invalid commandBuffer "
"[VUID-vkCmdBlitImage2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdBlitImage2(commandBuffer, pBlitImageInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2 *pCopyBufferInfo) {
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,
"vkCmdCopyBuffer2: Invalid commandBuffer "
"[VUID-vkCmdCopyBuffer2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdCopyBuffer2(commandBuffer, pCopyBufferInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2(VkCommandBuffer commandBuffer,
const VkCopyBufferToImageInfo2 *pCopyBufferToImageInfo) {
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,
"vkCmdCopyBufferToImage2: Invalid commandBuffer "
"[VUID-vkCmdCopyBufferToImage2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdCopyBufferToImage2(commandBuffer, pCopyBufferToImageInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2(VkCommandBuffer commandBuffer, const VkCopyImageInfo2 *pCopyImageInfo) {
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,
"vkCmdCopyImage2: Invalid commandBuffer "
"[VUID-vkCmdCopyImage2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdCopyImage2(commandBuffer, pCopyImageInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2(VkCommandBuffer commandBuffer,
const VkCopyImageToBufferInfo2 *pCopyImageToBufferInfo) {
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,
"vkCmdCopyImageToBuffer2: Invalid commandBuffer "
"[VUID-vkCmdCopyImageToBuffer2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdCopyImageToBuffer2(commandBuffer, pCopyImageToBufferInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdEndRendering(VkCommandBuffer commandBuffer) {
const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
if (NULL == disp) {
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
"vkCmdEndRendering: Invalid commandBuffer "
"[VUID-vkCmdEndRendering-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdEndRendering(commandBuffer);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2(VkCommandBuffer commandBuffer,
const VkDependencyInfo *pDependencyInfo) {
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,
"vkCmdPipelineBarrier2: Invalid commandBuffer "
"[VUID-vkCmdPipelineBarrier2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdPipelineBarrier2(commandBuffer, pDependencyInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2(VkCommandBuffer commandBuffer, VkEvent event,
VkPipelineStageFlags2 stageMask) {
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,
"vkCmdResetEvent2: Invalid commandBuffer "
"[VUID-vkCmdResetEvent2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdResetEvent2(commandBuffer, event, stageMask);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2(VkCommandBuffer commandBuffer,
const VkResolveImageInfo2 *pResolveImageInfo) {
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,
"vkCmdResolveImage2: Invalid commandBuffer "
"[VUID-vkCmdResolveImage2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdResolveImage2(commandBuffer, pResolveImageInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetCullMode(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode) {
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,
"vkCmdSetCullMode: Invalid commandBuffer "
"[VUID-vkCmdSetCullMode-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetCullMode(commandBuffer, cullMode);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnable(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable) {
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,
"vkCmdSetDepthBiasEnable: Invalid commandBuffer "
"[VUID-vkCmdSetDepthBiasEnable-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetDepthBiasEnable(commandBuffer, depthBiasEnable);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnable(VkCommandBuffer commandBuffer,
VkBool32 depthBoundsTestEnable) {
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,
"vkCmdSetDepthBoundsTestEnable: Invalid commandBuffer "
"[VUID-vkCmdSetDepthBoundsTestEnable-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetDepthBoundsTestEnable(commandBuffer, depthBoundsTestEnable);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOp(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp) {
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,
"vkCmdSetDepthCompareOp: Invalid commandBuffer "
"[VUID-vkCmdSetDepthCompareOp-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetDepthCompareOp(commandBuffer, depthCompareOp);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnable(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable) {
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,
"vkCmdSetDepthTestEnable: Invalid commandBuffer "
"[VUID-vkCmdSetDepthTestEnable-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetDepthTestEnable(commandBuffer, depthTestEnable);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnable(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable) {
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,
"vkCmdSetDepthWriteEnable: Invalid commandBuffer "
"[VUID-vkCmdSetDepthWriteEnable-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetDepthWriteEnable(commandBuffer, depthWriteEnable);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2(VkCommandBuffer commandBuffer, VkEvent event,
const VkDependencyInfo *pDependencyInfo) {
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,
"vkCmdSetEvent2: Invalid commandBuffer "
"[VUID-vkCmdSetEvent2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetEvent2(commandBuffer, event, pDependencyInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFace(VkCommandBuffer commandBuffer, VkFrontFace frontFace) {
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,
"vkCmdSetFrontFace: Invalid commandBuffer "
"[VUID-vkCmdSetFrontFace-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetFrontFace(commandBuffer, frontFace);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnable(VkCommandBuffer commandBuffer,
VkBool32 primitiveRestartEnable) {
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,
"vkCmdSetPrimitiveRestartEnable: Invalid commandBuffer "
"[VUID-vkCmdSetPrimitiveRestartEnable-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetPrimitiveRestartEnable(commandBuffer, primitiveRestartEnable);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopology(VkCommandBuffer commandBuffer,
VkPrimitiveTopology primitiveTopology) {
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,
"vkCmdSetPrimitiveTopology: Invalid commandBuffer "
"[VUID-vkCmdSetPrimitiveTopology-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetPrimitiveTopology(commandBuffer, primitiveTopology);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnable(VkCommandBuffer commandBuffer,
VkBool32 rasterizerDiscardEnable) {
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,
"vkCmdSetRasterizerDiscardEnable: Invalid commandBuffer "
"[VUID-vkCmdSetRasterizerDiscardEnable-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetRasterizerDiscardEnable(commandBuffer, rasterizerDiscardEnable);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCount(VkCommandBuffer commandBuffer, uint32_t scissorCount,
const VkRect2D *pScissors) {
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,
"vkCmdSetScissorWithCount: Invalid commandBuffer "
"[VUID-vkCmdSetScissorWithCount-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetScissorWithCount(commandBuffer, scissorCount, pScissors);
}
@@ -3321,29 +3430,59 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOp(VkCommandBuffer comma
VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp,
VkCompareOp compareOp) {
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,
"vkCmdSetStencilOp: Invalid commandBuffer "
"[VUID-vkCmdSetStencilOp-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetStencilOp(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnable(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable) {
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,
"vkCmdSetStencilTestEnable: Invalid commandBuffer "
"[VUID-vkCmdSetStencilTestEnable-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetStencilTestEnable(commandBuffer, stencilTestEnable);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCount(VkCommandBuffer commandBuffer, uint32_t viewportCount,
const VkViewport *pViewports) {
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,
"vkCmdSetViewportWithCount: Invalid commandBuffer "
"[VUID-vkCmdSetViewportWithCount-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetViewportWithCount(commandBuffer, viewportCount, pViewports);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2(VkCommandBuffer commandBuffer, uint32_t eventCount,
const VkEvent *pEvents, const VkDependencyInfo *pDependencyInfos) {
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,
"vkCmdWaitEvents2: Invalid commandBuffer "
"[VUID-vkCmdWaitEvents2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdWaitEvents2(commandBuffer, eventCount, pEvents, pDependencyInfos);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage,
VkQueryPool queryPool, uint32_t query) {
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,
"vkCmdWriteTimestamp2: Invalid commandBuffer "
"[VUID-vkCmdWriteTimestamp2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdWriteTimestamp2(commandBuffer, stage, queryPool, query);
}
@@ -3352,12 +3491,24 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlot(VkDevice de
const VkAllocationCallbacks *pAllocator,
VkPrivateDataSlot *pPrivateDataSlot) {
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,
"vkCreatePrivateDataSlot: Invalid device "
"[VUID-vkCreatePrivateDataSlot-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
return disp->CreatePrivateDataSlot(device, pCreateInfo, pAllocator, pPrivateDataSlot);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlot(VkDevice device, VkPrivateDataSlot privateDataSlot,
const VkAllocationCallbacks *pAllocator) {
const VkLayerDispatchTable *disp = loader_get_dispatch(device);
if (NULL == disp) {
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
"vkDestroyPrivateDataSlot: Invalid device "
"[VUID-vkDestroyPrivateDataSlot-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->DestroyPrivateDataSlot(device, privateDataSlot, pAllocator);
}
@@ -3365,6 +3516,12 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirements(VkD
const VkDeviceBufferMemoryRequirements *pInfo,
VkMemoryRequirements2 *pMemoryRequirements) {
const VkLayerDispatchTable *disp = loader_get_dispatch(device);
if (NULL == disp) {
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
"vkGetDeviceBufferMemoryRequirements: Invalid device "
"[VUID-vkGetDeviceBufferMemoryRequirements-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->GetDeviceBufferMemoryRequirements(device, pInfo, pMemoryRequirements);
}
@@ -3372,6 +3529,12 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirements(VkDe
const VkDeviceImageMemoryRequirements *pInfo,
VkMemoryRequirements2 *pMemoryRequirements) {
const VkLayerDispatchTable *disp = loader_get_dispatch(device);
if (NULL == disp) {
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
"vkGetDeviceImageMemoryRequirements: Invalid device "
"[VUID-vkGetDeviceImageMemoryRequirements-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->GetDeviceImageMemoryRequirements(device, pInfo, pMemoryRequirements);
}
@@ -3379,23 +3542,286 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirement
VkDevice device, const VkDeviceImageMemoryRequirements *pInfo, uint32_t *pSparseMemoryRequirementCount,
VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) {
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,
"vkGetDeviceImageSparseMemoryRequirements: Invalid device "
"[VUID-vkGetDeviceImageSparseMemoryRequirements-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->GetDeviceImageSparseMemoryRequirements(device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPrivateData(VkDevice device, VkObjectType objectType, uint64_t objectHandle,
VkPrivateDataSlot privateDataSlot, uint64_t *pData) {
const VkLayerDispatchTable *disp = loader_get_dispatch(device);
if (NULL == disp) {
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
"vkGetPrivateData: Invalid device "
"[VUID-vkGetPrivateData-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->GetPrivateData(device, objectType, objectHandle, privateDataSlot, pData);
}
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateData(VkDevice device, VkObjectType objectType, uint64_t objectHandle,
VkPrivateDataSlot privateDataSlot, uint64_t data) {
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,
"vkSetPrivateData: Invalid device "
"[VUID-vkSetPrivateData-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
return disp->SetPrivateData(device, objectType, objectHandle, privateDataSlot, data);
}
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits,
VkFence fence) {
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,
"vkQueueSubmit2: Invalid queue "
"[VUID-vkQueueSubmit2-queue-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
return disp->QueueSubmit2(queue, submitCount, pSubmits, fence);
}
// ---- Vulkan core 1.4 trampolines
// Instance
// Device
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetRenderingAreaGranularity(VkDevice device,
const VkRenderingAreaInfo *pRenderingAreaInfo,
VkExtent2D *pGranularity) {
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,
"vkGetRenderingAreaGranularity: Invalid device "
"[VUID-vkGetRenderingAreaGranularity-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->GetRenderingAreaGranularity(device, pRenderingAreaInfo, pGranularity);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSet(VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
uint32_t set, uint32_t descriptorWriteCount,
const VkWriteDescriptorSet *pDescriptorWrites) {
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,
"vkCmdPushDescriptorSet: Invalid commandBuffer "
"[VUID-vkCmdPushDescriptorSet-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdPushDescriptorSet(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount, pDescriptorWrites);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplate(VkCommandBuffer commandBuffer,
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
VkPipelineLayout layout, uint32_t set,
const void *pData) {
const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
if (NULL == disp) {
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
"vkCmdPushDescriptorSetWithTemplate: Invalid commandBuffer "
"[VUID-vkCmdPushDescriptorSetWithTemplate-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdPushDescriptorSetWithTemplate(commandBuffer, descriptorUpdateTemplate, layout, set, pData);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetLineStipple(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor,
uint16_t lineStipplePattern) {
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,
"vkCmdSetLineStipple: Invalid commandBuffer "
"[VUID-vkCmdSetLineStipple-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetLineStipple(commandBuffer, lineStippleFactor, lineStipplePattern);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer2(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
VkDeviceSize size, VkIndexType indexType) {
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,
"vkCmdBindIndexBuffer2: Invalid commandBuffer "
"[VUID-vkCmdBindIndexBuffer2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdBindIndexBuffer2(commandBuffer, buffer, offset, size, indexType);
}
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToImage(VkDevice device,
const VkCopyMemoryToImageInfo *pCopyMemoryToImageInfo) {
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,
"vkCopyMemoryToImage: Invalid device "
"[VUID-vkCopyMemoryToImage-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
return disp->CopyMemoryToImage(device, pCopyMemoryToImageInfo);
}
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCopyImageToMemory(VkDevice device,
const VkCopyImageToMemoryInfo *pCopyImageToMemoryInfo) {
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,
"vkCopyImageToMemory: Invalid device "
"[VUID-vkCopyImageToMemory-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
return disp->CopyImageToMemory(device, pCopyImageToMemoryInfo);
}
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCopyImageToImage(VkDevice device,
const VkCopyImageToImageInfo *pCopyImageToImageInfo) {
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,
"vkCopyImageToImage: Invalid device "
"[VUID-vkCopyImageToImage-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
return disp->CopyImageToImage(device, pCopyImageToImageInfo);
}
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkTransitionImageLayout(VkDevice device, uint32_t transitionCount,
const VkHostImageLayoutTransitionInfo *pTransitions) {
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,
"vkTransitionImageLayout: Invalid device "
"[VUID-vkTransitionImageLayout-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
return disp->TransitionImageLayout(device, transitionCount, pTransitions);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSubresourceLayout(VkDevice device,
const VkDeviceImageSubresourceInfo *pInfo,
VkSubresourceLayout2 *pLayout) {
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,
"vkGetDeviceImageSubresourceLayout: Invalid device "
"[VUID-vkGetDeviceImageSubresourceLayout-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->GetDeviceImageSubresourceLayout(device, pInfo, pLayout);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout2(VkDevice device, VkImage image,
const VkImageSubresource2 *pSubresource,
VkSubresourceLayout2 *pLayout) {
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,
"vkGetImageSubresourceLayout2: Invalid device "
"[VUID-vkGetImageSubresourceLayout2-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->GetImageSubresourceLayout2(device, image, pSubresource, pLayout);
}
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory2(VkDevice device, const VkMemoryMapInfo *pMemoryMapInfo, void **ppData) {
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,
"vkMapMemory2: Invalid device "
"[VUID-vkMapMemory2-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
return disp->MapMemory2(device, pMemoryMapInfo, ppData);
}
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkUnmapMemory2(VkDevice device, const VkMemoryUnmapInfo *pMemoryUnmapInfo) {
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,
"vkUnmapMemory2: Invalid device "
"[VUID-vkUnmapMemory2-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
return disp->UnmapMemory2(device, pMemoryUnmapInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets2(VkCommandBuffer commandBuffer,
const VkBindDescriptorSetsInfo *pBindDescriptorSetsInfo) {
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,
"vkCmdBindDescriptorSets2: Invalid commandBuffer "
"[VUID-vkCmdBindDescriptorSets2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdBindDescriptorSets2(commandBuffer, pBindDescriptorSetsInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants2(VkCommandBuffer commandBuffer,
const VkPushConstantsInfo *pPushConstantsInfo) {
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,
"vkCmdPushConstants2: Invalid commandBuffer "
"[VUID-vkCmdPushConstants2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdPushConstants2(commandBuffer, pPushConstantsInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSet2(VkCommandBuffer commandBuffer,
const VkPushDescriptorSetInfo *pPushDescriptorSetInfo) {
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,
"vkCmdPushDescriptorSet2: Invalid commandBuffer "
"[VUID-vkCmdPushDescriptorSet2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdPushDescriptorSet2(commandBuffer, pPushDescriptorSetInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplate2(
VkCommandBuffer commandBuffer, const VkPushDescriptorSetWithTemplateInfo *pPushDescriptorSetWithTemplateInfo) {
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,
"vkCmdPushDescriptorSetWithTemplate2: Invalid commandBuffer "
"[VUID-vkCmdPushDescriptorSetWithTemplate2-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdPushDescriptorSetWithTemplate2(commandBuffer, pPushDescriptorSetWithTemplateInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
vkCmdSetRenderingAttachmentLocations(VkCommandBuffer commandBuffer, const VkRenderingAttachmentLocationInfo *pLocationInfo) {
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,
"vkCmdSetRenderingAttachmentLocations: Invalid commandBuffer "
"[VUID-vkCmdSetRenderingAttachmentLocations-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetRenderingAttachmentLocations(commandBuffer, pLocationInfo);
}
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetRenderingInputAttachmentIndices(
VkCommandBuffer commandBuffer, const VkRenderingInputAttachmentIndexInfo *pInputAttachmentIndexInfo) {
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,
"vkCmdSetRenderingInputAttachmentIndices: Invalid commandBuffer "
"[VUID-vkCmdSetRenderingInputAttachmentIndices-commandBuffer-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
disp->CmdSetRenderingInputAttachmentIndices(commandBuffer, pInputAttachmentIndexInfo);
}
-820
View File
@@ -1,820 +0,0 @@
/*
* Copyright (c) 2017-2021 The Khronos Group Inc.
* Copyright (c) 2017-2021 Valve Corporation
* Copyright (c) 2017-2021 LunarG, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Author Jon Ashburn <jon@lunarg.com>
* Author: Lenny Komow <lenny@lunarg.com>
* Author: Charles Giessen <charles@lunarg.com>
*/
// This code is used to pass on physical device extensions through the call chain. It must do this without creating a stack frame,
// because the actual parameters of the call are not known. Since the first parameter is known to be a VkPhysicalDevice, it can
// unwrap the physical device, overwriting the wrapped device, and then jump to the next function in the call chain. This code
// attempts to accomplish this by relying on tail-call optimizations, but there is no guarantee that this will work. As a result,
// this code is only compiled on systems where an assembly alternative has not been written.
#include "loader.h"
#include "log.h"
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC optimize(3) // force gcc to use tail-calls
#endif
// Trampoline function macro for unknown physical device extension command.
#define PhysDevExtTramp(num) \
VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp##num(VkPhysicalDevice physical_device) { \
const struct loader_instance_dispatch_table *disp; \
disp = loader_get_instance_dispatch(physical_device); \
disp->phys_dev_ext[num](loader_unwrap_physical_device(physical_device)); \
}
// Terminator function macro for unknown physical device extension command.
#define PhysDevExtTermin(num) \
VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin##num(VkPhysicalDevice physical_device) { \
struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physical_device; \
struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; \
struct loader_instance *inst = (struct loader_instance *)icd_term->this_instance; \
if (NULL == icd_term->phys_dev_ext[num]) { \
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "Function %s not supported for this physical device", \
inst->phys_dev_ext_disp_functions[num]); \
} \
icd_term->phys_dev_ext[num](phys_dev_term->phys_dev); \
}
// Trampoline function macro for unknown physical device extension command.
#define DevExtTramp(num) \
VKAPI_ATTR void VKAPI_CALL vkdev_ext##num(VkDevice device) { \
const struct loader_dev_dispatch_table *disp; \
disp = loader_get_dev_dispatch(device); \
disp->ext_dispatch[num](device); \
}
// clang-format off
// Instantiations of the trampoline
PhysDevExtTramp(0)
PhysDevExtTramp(1)
PhysDevExtTramp(2)
PhysDevExtTramp(3)
PhysDevExtTramp(4)
PhysDevExtTramp(5)
PhysDevExtTramp(6)
PhysDevExtTramp(7)
PhysDevExtTramp(8)
PhysDevExtTramp(9)
PhysDevExtTramp(10)
PhysDevExtTramp(11)
PhysDevExtTramp(12)
PhysDevExtTramp(13)
PhysDevExtTramp(14)
PhysDevExtTramp(15)
PhysDevExtTramp(16)
PhysDevExtTramp(17)
PhysDevExtTramp(18)
PhysDevExtTramp(19)
PhysDevExtTramp(20)
PhysDevExtTramp(21)
PhysDevExtTramp(22)
PhysDevExtTramp(23)
PhysDevExtTramp(24)
PhysDevExtTramp(25)
PhysDevExtTramp(26)
PhysDevExtTramp(27)
PhysDevExtTramp(28)
PhysDevExtTramp(29)
PhysDevExtTramp(30)
PhysDevExtTramp(31)
PhysDevExtTramp(32)
PhysDevExtTramp(33)
PhysDevExtTramp(34)
PhysDevExtTramp(35)
PhysDevExtTramp(36)
PhysDevExtTramp(37)
PhysDevExtTramp(38)
PhysDevExtTramp(39)
PhysDevExtTramp(40)
PhysDevExtTramp(41)
PhysDevExtTramp(42)
PhysDevExtTramp(43)
PhysDevExtTramp(44)
PhysDevExtTramp(45)
PhysDevExtTramp(46)
PhysDevExtTramp(47)
PhysDevExtTramp(48)
PhysDevExtTramp(49)
PhysDevExtTramp(50)
PhysDevExtTramp(51)
PhysDevExtTramp(52)
PhysDevExtTramp(53)
PhysDevExtTramp(54)
PhysDevExtTramp(55)
PhysDevExtTramp(56)
PhysDevExtTramp(57)
PhysDevExtTramp(58)
PhysDevExtTramp(59)
PhysDevExtTramp(60)
PhysDevExtTramp(61)
PhysDevExtTramp(62)
PhysDevExtTramp(63)
PhysDevExtTramp(64)
PhysDevExtTramp(65)
PhysDevExtTramp(66)
PhysDevExtTramp(67)
PhysDevExtTramp(68)
PhysDevExtTramp(69)
PhysDevExtTramp(70)
PhysDevExtTramp(71)
PhysDevExtTramp(72)
PhysDevExtTramp(73)
PhysDevExtTramp(74)
PhysDevExtTramp(75)
PhysDevExtTramp(76)
PhysDevExtTramp(77)
PhysDevExtTramp(78)
PhysDevExtTramp(79)
PhysDevExtTramp(80)
PhysDevExtTramp(81)
PhysDevExtTramp(82)
PhysDevExtTramp(83)
PhysDevExtTramp(84)
PhysDevExtTramp(85)
PhysDevExtTramp(86)
PhysDevExtTramp(87)
PhysDevExtTramp(88)
PhysDevExtTramp(89)
PhysDevExtTramp(90)
PhysDevExtTramp(91)
PhysDevExtTramp(92)
PhysDevExtTramp(93)
PhysDevExtTramp(94)
PhysDevExtTramp(95)
PhysDevExtTramp(96)
PhysDevExtTramp(97)
PhysDevExtTramp(98)
PhysDevExtTramp(99)
PhysDevExtTramp(100)
PhysDevExtTramp(101)
PhysDevExtTramp(102)
PhysDevExtTramp(103)
PhysDevExtTramp(104)
PhysDevExtTramp(105)
PhysDevExtTramp(106)
PhysDevExtTramp(107)
PhysDevExtTramp(108)
PhysDevExtTramp(109)
PhysDevExtTramp(110)
PhysDevExtTramp(111)
PhysDevExtTramp(112)
PhysDevExtTramp(113)
PhysDevExtTramp(114)
PhysDevExtTramp(115)
PhysDevExtTramp(116)
PhysDevExtTramp(117)
PhysDevExtTramp(118)
PhysDevExtTramp(119)
PhysDevExtTramp(120)
PhysDevExtTramp(121)
PhysDevExtTramp(122)
PhysDevExtTramp(123)
PhysDevExtTramp(124)
PhysDevExtTramp(125)
PhysDevExtTramp(126)
PhysDevExtTramp(127)
PhysDevExtTramp(128)
PhysDevExtTramp(129)
PhysDevExtTramp(130)
PhysDevExtTramp(131)
PhysDevExtTramp(132)
PhysDevExtTramp(133)
PhysDevExtTramp(134)
PhysDevExtTramp(135)
PhysDevExtTramp(136)
PhysDevExtTramp(137)
PhysDevExtTramp(138)
PhysDevExtTramp(139)
PhysDevExtTramp(140)
PhysDevExtTramp(141)
PhysDevExtTramp(142)
PhysDevExtTramp(143)
PhysDevExtTramp(144)
PhysDevExtTramp(145)
PhysDevExtTramp(146)
PhysDevExtTramp(147)
PhysDevExtTramp(148)
PhysDevExtTramp(149)
PhysDevExtTramp(150)
PhysDevExtTramp(151)
PhysDevExtTramp(152)
PhysDevExtTramp(153)
PhysDevExtTramp(154)
PhysDevExtTramp(155)
PhysDevExtTramp(156)
PhysDevExtTramp(157)
PhysDevExtTramp(158)
PhysDevExtTramp(159)
PhysDevExtTramp(160)
PhysDevExtTramp(161)
PhysDevExtTramp(162)
PhysDevExtTramp(163)
PhysDevExtTramp(164)
PhysDevExtTramp(165)
PhysDevExtTramp(166)
PhysDevExtTramp(167)
PhysDevExtTramp(168)
PhysDevExtTramp(169)
PhysDevExtTramp(170)
PhysDevExtTramp(171)
PhysDevExtTramp(172)
PhysDevExtTramp(173)
PhysDevExtTramp(174)
PhysDevExtTramp(175)
PhysDevExtTramp(176)
PhysDevExtTramp(177)
PhysDevExtTramp(178)
PhysDevExtTramp(179)
PhysDevExtTramp(180)
PhysDevExtTramp(181)
PhysDevExtTramp(182)
PhysDevExtTramp(183)
PhysDevExtTramp(184)
PhysDevExtTramp(185)
PhysDevExtTramp(186)
PhysDevExtTramp(187)
PhysDevExtTramp(188)
PhysDevExtTramp(189)
PhysDevExtTramp(190)
PhysDevExtTramp(191)
PhysDevExtTramp(192)
PhysDevExtTramp(193)
PhysDevExtTramp(194)
PhysDevExtTramp(195)
PhysDevExtTramp(196)
PhysDevExtTramp(197)
PhysDevExtTramp(198)
PhysDevExtTramp(199)
PhysDevExtTramp(200)
PhysDevExtTramp(201)
PhysDevExtTramp(202)
PhysDevExtTramp(203)
PhysDevExtTramp(204)
PhysDevExtTramp(205)
PhysDevExtTramp(206)
PhysDevExtTramp(207)
PhysDevExtTramp(208)
PhysDevExtTramp(209)
PhysDevExtTramp(210)
PhysDevExtTramp(211)
PhysDevExtTramp(212)
PhysDevExtTramp(213)
PhysDevExtTramp(214)
PhysDevExtTramp(215)
PhysDevExtTramp(216)
PhysDevExtTramp(217)
PhysDevExtTramp(218)
PhysDevExtTramp(219)
PhysDevExtTramp(220)
PhysDevExtTramp(221)
PhysDevExtTramp(222)
PhysDevExtTramp(223)
PhysDevExtTramp(224)
PhysDevExtTramp(225)
PhysDevExtTramp(226)
PhysDevExtTramp(227)
PhysDevExtTramp(228)
PhysDevExtTramp(229)
PhysDevExtTramp(230)
PhysDevExtTramp(231)
PhysDevExtTramp(232)
PhysDevExtTramp(233)
PhysDevExtTramp(234)
PhysDevExtTramp(235)
PhysDevExtTramp(236)
PhysDevExtTramp(237)
PhysDevExtTramp(238)
PhysDevExtTramp(239)
PhysDevExtTramp(240)
PhysDevExtTramp(241)
PhysDevExtTramp(242)
PhysDevExtTramp(243)
PhysDevExtTramp(244)
PhysDevExtTramp(245)
PhysDevExtTramp(246)
PhysDevExtTramp(247)
PhysDevExtTramp(248)
PhysDevExtTramp(249)
// Instantiations of the terminator
PhysDevExtTermin(0)
PhysDevExtTermin(1)
PhysDevExtTermin(2)
PhysDevExtTermin(3)
PhysDevExtTermin(4)
PhysDevExtTermin(5)
PhysDevExtTermin(6)
PhysDevExtTermin(7)
PhysDevExtTermin(8)
PhysDevExtTermin(9)
PhysDevExtTermin(10)
PhysDevExtTermin(11)
PhysDevExtTermin(12)
PhysDevExtTermin(13)
PhysDevExtTermin(14)
PhysDevExtTermin(15)
PhysDevExtTermin(16)
PhysDevExtTermin(17)
PhysDevExtTermin(18)
PhysDevExtTermin(19)
PhysDevExtTermin(20)
PhysDevExtTermin(21)
PhysDevExtTermin(22)
PhysDevExtTermin(23)
PhysDevExtTermin(24)
PhysDevExtTermin(25)
PhysDevExtTermin(26)
PhysDevExtTermin(27)
PhysDevExtTermin(28)
PhysDevExtTermin(29)
PhysDevExtTermin(30)
PhysDevExtTermin(31)
PhysDevExtTermin(32)
PhysDevExtTermin(33)
PhysDevExtTermin(34)
PhysDevExtTermin(35)
PhysDevExtTermin(36)
PhysDevExtTermin(37)
PhysDevExtTermin(38)
PhysDevExtTermin(39)
PhysDevExtTermin(40)
PhysDevExtTermin(41)
PhysDevExtTermin(42)
PhysDevExtTermin(43)
PhysDevExtTermin(44)
PhysDevExtTermin(45)
PhysDevExtTermin(46)
PhysDevExtTermin(47)
PhysDevExtTermin(48)
PhysDevExtTermin(49)
PhysDevExtTermin(50)
PhysDevExtTermin(51)
PhysDevExtTermin(52)
PhysDevExtTermin(53)
PhysDevExtTermin(54)
PhysDevExtTermin(55)
PhysDevExtTermin(56)
PhysDevExtTermin(57)
PhysDevExtTermin(58)
PhysDevExtTermin(59)
PhysDevExtTermin(60)
PhysDevExtTermin(61)
PhysDevExtTermin(62)
PhysDevExtTermin(63)
PhysDevExtTermin(64)
PhysDevExtTermin(65)
PhysDevExtTermin(66)
PhysDevExtTermin(67)
PhysDevExtTermin(68)
PhysDevExtTermin(69)
PhysDevExtTermin(70)
PhysDevExtTermin(71)
PhysDevExtTermin(72)
PhysDevExtTermin(73)
PhysDevExtTermin(74)
PhysDevExtTermin(75)
PhysDevExtTermin(76)
PhysDevExtTermin(77)
PhysDevExtTermin(78)
PhysDevExtTermin(79)
PhysDevExtTermin(80)
PhysDevExtTermin(81)
PhysDevExtTermin(82)
PhysDevExtTermin(83)
PhysDevExtTermin(84)
PhysDevExtTermin(85)
PhysDevExtTermin(86)
PhysDevExtTermin(87)
PhysDevExtTermin(88)
PhysDevExtTermin(89)
PhysDevExtTermin(90)
PhysDevExtTermin(91)
PhysDevExtTermin(92)
PhysDevExtTermin(93)
PhysDevExtTermin(94)
PhysDevExtTermin(95)
PhysDevExtTermin(96)
PhysDevExtTermin(97)
PhysDevExtTermin(98)
PhysDevExtTermin(99)
PhysDevExtTermin(100)
PhysDevExtTermin(101)
PhysDevExtTermin(102)
PhysDevExtTermin(103)
PhysDevExtTermin(104)
PhysDevExtTermin(105)
PhysDevExtTermin(106)
PhysDevExtTermin(107)
PhysDevExtTermin(108)
PhysDevExtTermin(109)
PhysDevExtTermin(110)
PhysDevExtTermin(111)
PhysDevExtTermin(112)
PhysDevExtTermin(113)
PhysDevExtTermin(114)
PhysDevExtTermin(115)
PhysDevExtTermin(116)
PhysDevExtTermin(117)
PhysDevExtTermin(118)
PhysDevExtTermin(119)
PhysDevExtTermin(120)
PhysDevExtTermin(121)
PhysDevExtTermin(122)
PhysDevExtTermin(123)
PhysDevExtTermin(124)
PhysDevExtTermin(125)
PhysDevExtTermin(126)
PhysDevExtTermin(127)
PhysDevExtTermin(128)
PhysDevExtTermin(129)
PhysDevExtTermin(130)
PhysDevExtTermin(131)
PhysDevExtTermin(132)
PhysDevExtTermin(133)
PhysDevExtTermin(134)
PhysDevExtTermin(135)
PhysDevExtTermin(136)
PhysDevExtTermin(137)
PhysDevExtTermin(138)
PhysDevExtTermin(139)
PhysDevExtTermin(140)
PhysDevExtTermin(141)
PhysDevExtTermin(142)
PhysDevExtTermin(143)
PhysDevExtTermin(144)
PhysDevExtTermin(145)
PhysDevExtTermin(146)
PhysDevExtTermin(147)
PhysDevExtTermin(148)
PhysDevExtTermin(149)
PhysDevExtTermin(150)
PhysDevExtTermin(151)
PhysDevExtTermin(152)
PhysDevExtTermin(153)
PhysDevExtTermin(154)
PhysDevExtTermin(155)
PhysDevExtTermin(156)
PhysDevExtTermin(157)
PhysDevExtTermin(158)
PhysDevExtTermin(159)
PhysDevExtTermin(160)
PhysDevExtTermin(161)
PhysDevExtTermin(162)
PhysDevExtTermin(163)
PhysDevExtTermin(164)
PhysDevExtTermin(165)
PhysDevExtTermin(166)
PhysDevExtTermin(167)
PhysDevExtTermin(168)
PhysDevExtTermin(169)
PhysDevExtTermin(170)
PhysDevExtTermin(171)
PhysDevExtTermin(172)
PhysDevExtTermin(173)
PhysDevExtTermin(174)
PhysDevExtTermin(175)
PhysDevExtTermin(176)
PhysDevExtTermin(177)
PhysDevExtTermin(178)
PhysDevExtTermin(179)
PhysDevExtTermin(180)
PhysDevExtTermin(181)
PhysDevExtTermin(182)
PhysDevExtTermin(183)
PhysDevExtTermin(184)
PhysDevExtTermin(185)
PhysDevExtTermin(186)
PhysDevExtTermin(187)
PhysDevExtTermin(188)
PhysDevExtTermin(189)
PhysDevExtTermin(190)
PhysDevExtTermin(191)
PhysDevExtTermin(192)
PhysDevExtTermin(193)
PhysDevExtTermin(194)
PhysDevExtTermin(195)
PhysDevExtTermin(196)
PhysDevExtTermin(197)
PhysDevExtTermin(198)
PhysDevExtTermin(199)
PhysDevExtTermin(200)
PhysDevExtTermin(201)
PhysDevExtTermin(202)
PhysDevExtTermin(203)
PhysDevExtTermin(204)
PhysDevExtTermin(205)
PhysDevExtTermin(206)
PhysDevExtTermin(207)
PhysDevExtTermin(208)
PhysDevExtTermin(209)
PhysDevExtTermin(210)
PhysDevExtTermin(211)
PhysDevExtTermin(212)
PhysDevExtTermin(213)
PhysDevExtTermin(214)
PhysDevExtTermin(215)
PhysDevExtTermin(216)
PhysDevExtTermin(217)
PhysDevExtTermin(218)
PhysDevExtTermin(219)
PhysDevExtTermin(220)
PhysDevExtTermin(221)
PhysDevExtTermin(222)
PhysDevExtTermin(223)
PhysDevExtTermin(224)
PhysDevExtTermin(225)
PhysDevExtTermin(226)
PhysDevExtTermin(227)
PhysDevExtTermin(228)
PhysDevExtTermin(229)
PhysDevExtTermin(230)
PhysDevExtTermin(231)
PhysDevExtTermin(232)
PhysDevExtTermin(233)
PhysDevExtTermin(234)
PhysDevExtTermin(235)
PhysDevExtTermin(236)
PhysDevExtTermin(237)
PhysDevExtTermin(238)
PhysDevExtTermin(239)
PhysDevExtTermin(240)
PhysDevExtTermin(241)
PhysDevExtTermin(242)
PhysDevExtTermin(243)
PhysDevExtTermin(244)
PhysDevExtTermin(245)
PhysDevExtTermin(246)
PhysDevExtTermin(247)
PhysDevExtTermin(248)
PhysDevExtTermin(249)
// Instantiations of the device trampoline
DevExtTramp(0)
DevExtTramp(1)
DevExtTramp(2)
DevExtTramp(3)
DevExtTramp(4)
DevExtTramp(5)
DevExtTramp(6)
DevExtTramp(7)
DevExtTramp(8)
DevExtTramp(9)
DevExtTramp(10)
DevExtTramp(11)
DevExtTramp(12)
DevExtTramp(13)
DevExtTramp(14)
DevExtTramp(15)
DevExtTramp(16)
DevExtTramp(17)
DevExtTramp(18)
DevExtTramp(19)
DevExtTramp(20)
DevExtTramp(21)
DevExtTramp(22)
DevExtTramp(23)
DevExtTramp(24)
DevExtTramp(25)
DevExtTramp(26)
DevExtTramp(27)
DevExtTramp(28)
DevExtTramp(29)
DevExtTramp(30)
DevExtTramp(31)
DevExtTramp(32)
DevExtTramp(33)
DevExtTramp(34)
DevExtTramp(35)
DevExtTramp(36)
DevExtTramp(37)
DevExtTramp(38)
DevExtTramp(39)
DevExtTramp(40)
DevExtTramp(41)
DevExtTramp(42)
DevExtTramp(43)
DevExtTramp(44)
DevExtTramp(45)
DevExtTramp(46)
DevExtTramp(47)
DevExtTramp(48)
DevExtTramp(49)
DevExtTramp(50)
DevExtTramp(51)
DevExtTramp(52)
DevExtTramp(53)
DevExtTramp(54)
DevExtTramp(55)
DevExtTramp(56)
DevExtTramp(57)
DevExtTramp(58)
DevExtTramp(59)
DevExtTramp(60)
DevExtTramp(61)
DevExtTramp(62)
DevExtTramp(63)
DevExtTramp(64)
DevExtTramp(65)
DevExtTramp(66)
DevExtTramp(67)
DevExtTramp(68)
DevExtTramp(69)
DevExtTramp(70)
DevExtTramp(71)
DevExtTramp(72)
DevExtTramp(73)
DevExtTramp(74)
DevExtTramp(75)
DevExtTramp(76)
DevExtTramp(77)
DevExtTramp(78)
DevExtTramp(79)
DevExtTramp(80)
DevExtTramp(81)
DevExtTramp(82)
DevExtTramp(83)
DevExtTramp(84)
DevExtTramp(85)
DevExtTramp(86)
DevExtTramp(87)
DevExtTramp(88)
DevExtTramp(89)
DevExtTramp(90)
DevExtTramp(91)
DevExtTramp(92)
DevExtTramp(93)
DevExtTramp(94)
DevExtTramp(95)
DevExtTramp(96)
DevExtTramp(97)
DevExtTramp(98)
DevExtTramp(99)
DevExtTramp(100)
DevExtTramp(101)
DevExtTramp(102)
DevExtTramp(103)
DevExtTramp(104)
DevExtTramp(105)
DevExtTramp(106)
DevExtTramp(107)
DevExtTramp(108)
DevExtTramp(109)
DevExtTramp(110)
DevExtTramp(111)
DevExtTramp(112)
DevExtTramp(113)
DevExtTramp(114)
DevExtTramp(115)
DevExtTramp(116)
DevExtTramp(117)
DevExtTramp(118)
DevExtTramp(119)
DevExtTramp(120)
DevExtTramp(121)
DevExtTramp(122)
DevExtTramp(123)
DevExtTramp(124)
DevExtTramp(125)
DevExtTramp(126)
DevExtTramp(127)
DevExtTramp(128)
DevExtTramp(129)
DevExtTramp(130)
DevExtTramp(131)
DevExtTramp(132)
DevExtTramp(133)
DevExtTramp(134)
DevExtTramp(135)
DevExtTramp(136)
DevExtTramp(137)
DevExtTramp(138)
DevExtTramp(139)
DevExtTramp(140)
DevExtTramp(141)
DevExtTramp(142)
DevExtTramp(143)
DevExtTramp(144)
DevExtTramp(145)
DevExtTramp(146)
DevExtTramp(147)
DevExtTramp(148)
DevExtTramp(149)
DevExtTramp(150)
DevExtTramp(151)
DevExtTramp(152)
DevExtTramp(153)
DevExtTramp(154)
DevExtTramp(155)
DevExtTramp(156)
DevExtTramp(157)
DevExtTramp(158)
DevExtTramp(159)
DevExtTramp(160)
DevExtTramp(161)
DevExtTramp(162)
DevExtTramp(163)
DevExtTramp(164)
DevExtTramp(165)
DevExtTramp(166)
DevExtTramp(167)
DevExtTramp(168)
DevExtTramp(169)
DevExtTramp(170)
DevExtTramp(171)
DevExtTramp(172)
DevExtTramp(173)
DevExtTramp(174)
DevExtTramp(175)
DevExtTramp(176)
DevExtTramp(177)
DevExtTramp(178)
DevExtTramp(179)
DevExtTramp(180)
DevExtTramp(181)
DevExtTramp(182)
DevExtTramp(183)
DevExtTramp(184)
DevExtTramp(185)
DevExtTramp(186)
DevExtTramp(187)
DevExtTramp(188)
DevExtTramp(189)
DevExtTramp(190)
DevExtTramp(191)
DevExtTramp(192)
DevExtTramp(193)
DevExtTramp(194)
DevExtTramp(195)
DevExtTramp(196)
DevExtTramp(197)
DevExtTramp(198)
DevExtTramp(199)
DevExtTramp(200)
DevExtTramp(201)
DevExtTramp(202)
DevExtTramp(203)
DevExtTramp(204)
DevExtTramp(205)
DevExtTramp(206)
DevExtTramp(207)
DevExtTramp(208)
DevExtTramp(209)
DevExtTramp(210)
DevExtTramp(211)
DevExtTramp(212)
DevExtTramp(213)
DevExtTramp(214)
DevExtTramp(215)
DevExtTramp(216)
DevExtTramp(217)
DevExtTramp(218)
DevExtTramp(219)
DevExtTramp(220)
DevExtTramp(221)
DevExtTramp(222)
DevExtTramp(223)
DevExtTramp(224)
DevExtTramp(225)
DevExtTramp(226)
DevExtTramp(227)
DevExtTramp(228)
DevExtTramp(229)
DevExtTramp(230)
DevExtTramp(231)
DevExtTramp(232)
DevExtTramp(233)
DevExtTramp(234)
DevExtTramp(235)
DevExtTramp(236)
DevExtTramp(237)
DevExtTramp(238)
DevExtTramp(239)
DevExtTramp(240)
DevExtTramp(241)
DevExtTramp(242)
DevExtTramp(243)
DevExtTramp(244)
DevExtTramp(245)
DevExtTramp(246)
DevExtTramp(247)
DevExtTramp(248)
DevExtTramp(249)
@@ -1,5 +1,7 @@
//
// Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// Copyright (c) 2024 Valve Corporation
// Copyright (c) 2024 LunarG, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,6 +16,7 @@
// limitations under the License.
//
// Author: Eric Sullivan <esullivan@nvidia.com>
// Author: Charles Giessen <charles@lunarg.com>
//
// This code is used to pass on device (including physical device) extensions through the call chain. It must do this without
@@ -21,39 +24,74 @@
// VkPhysicalDevice or a dispatchable object it can unwrap the object, possibly overwriting the wrapped physical device, and then
// jump to the next function in the call chain
.include "gen_defines.asm"
#include "gen_defines.asm"
/*
* References:
* - https://developer.arm.com/documentation/101028/0012/5--Feature-test-macros
* - https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst
*/
#if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1
#define BTI_J hint 36 /* bti j: for jumps, IE br instructions */
#define BTI_C hint 34 /* bti c: for calls, IE bl instructions */
#define GNU_PROPERTY_AARCH64_BTI 1 /* bit 0 GNU Notes is for BTI support */
#else
#define BTI_J
#define BTI_C
#define GNU_PROPERTY_AARCH64_BTI 0
#endif
/*
* We just need PAC added to GNU Notes for auditing features, the assembly itself does
* not need pac augmentation at this time because it doesn't make use of the SP aka x30.
*/
#if defined(__ARM_FEATURE_PAC_DEFAULT)
#define GNU_PROPERTY_AARCH64_POINTER_AUTH 2 /* bit 1 GNU Notes is for PAC support */
#else
#define GNU_PROPERTY_AARCH64_POINTER_AUTH 0
#endif
.if AARCH_64
.macro PhysDevExtTramp num
.global vkPhysDevExtTramp\num
#if defined(__ELF__)
.type vkPhysDevExtTramp\num, @function
.hidden vkPhysDevExtTramp\num
#endif
.balign 4
/*
* NOTE: x16 is used for the br register so the pstate.btype is 01 and can
* land on 'bti c' that would be inserted by the compiler in C/C++ functions.
* See: https://developer.arm.com/documentation/102433/0200/Jump-oriented-programming
*/
vkPhysDevExtTramp\num:
BTI_C
ldr x9, [x0] // Load the loader_instance_dispatch_table* into x9
ldr x0, [x0, PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] // Load the unwrapped VkPhysicalDevice into x0
mov x10, (PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * \num)) // Put the offset of the entry in the dispatch table for the function
ldr x11, [x9, x10] // Load the address to branch to out of the dispatch table
br x11 // Branch to the next member of the dispatch chain
ldr x16, [x9, x10] // Load the address to branch to out of the dispatch table
br x16 // Branch to the next member of the dispatch chain
.endm
.macro PhysDevExtTermin num
.global vkPhysDevExtTermin\num
#if defined(__ELF__)
.type vkPhysDevExtTermin\num, @function
.hidden vkPhysDevExtTermin\num
#endif
.balign 4
vkPhysDevExtTermin\num:
BTI_C
ldr x9, [x0, ICD_TERM_OFFSET_PHYS_DEV_TERM] // Load the loader_icd_term* in x9
mov x11, (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num)) // Put the offset into the dispatch table in x11
ldr x10, [x9, x11] // Load the address of the next function in the dispatch chain
cbz x10, terminError\num // Go to the error section if the next function in the chain is NULL
ldr x16, [x9, x11] // Load the address of the next function in the dispatch chain
cbz x16, terminError\num // Go to the error section if the next function in the chain is NULL
ldr x0, [x0, PHYS_DEV_OFFSET_PHYS_DEV_TERM] // Unwrap the VkPhysicalDevice in x0
br x10 // Jump to the next function in the chain
br x16 // Jump to the next function in the chain
terminError\num:
BTI_J
mov x10, (FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * \num)) // Offset of the function name string in the instance
ldr x11, [x9, INSTANCE_OFFSET_ICD_TERM] // Load the instance pointer
mov x0, x11 // Vulkan instance pointer (first arg)
@@ -72,16 +110,92 @@ terminError\num:
#endif
.balign 4
vkdev_ext\num:
BTI_C
ldr x9, [x0] // Load the loader_instance_dispatch_table* into x9
mov x10, (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * \num)) // Offset of the desired function in the dispatch table
ldr x11, [x9, x10] // Load the function address
br x11
ldr x16, [x9, x10] // Load the function address
br x16
.endm
.else // AARCH_32
.macro PhysDevExtTramp num
.global vkPhysDevExtTramp\num
#if defined(__ELF__)
.hidden vkPhysDevExtTramp\num
#endif
.balign 4
vkPhysDevExtTrampDispatchEntry\num: .word PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * \num)
vkPhysDevExtTramp\num:
ldr r4, [r0] // Load the loader_instance_dispatch_table* into r4
ldr r0, [r0, #PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] // Load the unwrapped VkPhysicalDevice into r0
ldr r5, vkPhysDevExtTrampDispatchEntry\num // Put the offset of the entry in the dispatch table for the function
ldr r6, [r4, r5] // Load the address to branch to out of the dispatch table
bx r6 // Branch to the next member of the dispatch chain
.endm
.macro PhysDevExtTermin num
.global vkPhysDevExtTermin\num
#if defined(__ELF__)
.hidden vkPhysDevExtTermin\num
#endif
.balign 4
vkPhysDevExtTerminDispatchEntry\num: .word DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num)
vkPhysDevExtTerminFunctionNameEntry\num: .word FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * \num)
vkPhysDevExtTermin\num:
ldr r4, [r0, #ICD_TERM_OFFSET_PHYS_DEV_TERM] // Load the loader_icd_term* in r4
ldr r6, vkPhysDevExtTerminDispatchEntry\num // Put the offset into the dispatch table in r6
ldr r5, [r4, r6] // Load the address of the next function in the dispatch chain
cmp r5, #0
beq terminError\num // Go to the error section if the next function in the chain is NULL
ldr r0, [r0, #PHYS_DEV_OFFSET_PHYS_DEV_TERM] // Unwrap the VkPhysicalDevice in r0
bx r5 // Jump to the next function in the chain
terminError\num:
ldr r5, vkPhysDevExtTerminFunctionNameEntry\num // Offset of the function name string in the instance
ldr r6, [r4, #INSTANCE_OFFSET_ICD_TERM] // Load the instance pointer
mov r0, r6 // Vulkan instance pointer (first arg)
mov r1, #VULKAN_LOADER_ERROR_BIT // The error logging bit (second arg)
mov r2, #0 // Zero (third arg)
ldr r3, [r6, r5] // The function name (fourth arg)
bl loader_log_asm_function_not_supported // Log the error message before we crash
mov r0, #0
bx r0 // Crash intentionally by jumping to address zero
.endm
.macro DevExtTramp num
.global vkdev_ext\num
#if defined(__ELF__)
.hidden vkdev_ext\num
#endif
.balign 4
vkdev_ext_dispatch_entry\num: .word EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * \num)
vkdev_ext\num:
ldr r4, [r0] // Load the loader_instance_dispatch_table* into r4
ldr r5, vkdev_ext_dispatch_entry\num // Offset of the desired function in the dispatch table
ldr r6, [r4, r5] // Load the function address
bx r6
.endm
.endif
#if defined(__ELF__)
.section .note.GNU-stack,"",%progbits
/* Add the PAC and BTI support to GNU Notes section for ELF object files */
#if GNU_PROPERTY_AARCH64_BTI != 0 || GNU_PROPERTY_AARCH64_POINTER_AUTH != 0
.pushsection .note.gnu.property, "a"; /* Start a new allocatable section */
.balign 8; /* align it on a byte boundry */
.long 4; /* size of "GNU\0" */
.long 0x10; /* size of descriptor */
.long 0x5; /* NT_GNU_PROPERTY_TYPE_0 */
.asciz "GNU";
.long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */
.long 4; /* Four bytes of data */
.long (GNU_PROPERTY_AARCH64_BTI|GNU_PROPERTY_AARCH64_POINTER_AUTH); /* BTI or PAC is enabled */
.long 0; /* padding for 8 byte alignment */
.popsection; /* end the section */
#endif
#endif
.data
+1 -1
View File
@@ -33,7 +33,7 @@
#endif
.intel_syntax noprefix
.include "gen_defines.asm"
#include "gen_defines.asm"
.ifdef X86_64
+896
View File
@@ -0,0 +1,896 @@
;
; Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
; Copyright (c) 2024 Valve Corporation
; Copyright (c) 2024 LunarG, Inc.
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; Author: Eric Sullivan <esullivan@nvidia.com>
; Author: Charles Giessen <charles@lunarg.com>
;
; This code is used to pass on device (including physical device) extensions through the call chain. It must do this without
; creating a stack frame, because the actual parameters of the call are not known. Since the first parameter is known to be a
; VkPhysicalDevice or a dispatchable object it can unwrap the object, possibly overwriting the wrapped physical device, and then
; jump to the next function in the call chain
GET gen_defines.asm
EXTERN loader_log_asm_function_not_supported
IF AARCH_64==1
MACRO
PhysDevExtTramp $num
ALIGN
EXPORT vkPhysDevExtTramp$num [FUNC]
vkPhysDevExtTramp$num FUNCTION
ldr x9, [x0] ; Load the loader_instance_dispatch_table* into x9
ldr x0, [x0, PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] ; Load the unwrapped VkPhysicalDevice into x0
mov x10, #(PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * $num)) ; Put the offset of the entry in the dispatch table for the function
ldr x11, [x9, x10] ; Load the address to branch to out of the dispatch table
br x11 ; Branch to the next member of the dispatch chain
ENDFUNC
MEND
MACRO
$label PhysDevExtTermin $num
ALIGN
EXPORT vkPhysDevExtTermin$num [FUNC]
vkPhysDevExtTermin$num FUNCTION
ldr x9, [x0, ICD_TERM_OFFSET_PHYS_DEV_TERM] ; Load the loader_icd_term* in x9
mov x11, (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * $num)) ; Put the offset into the dispatch table in x11
ldr x10, [x9, x11] ; Load the address of the next function in the dispatch chain
cbz x10, terminError$num ; Go to the error section if the next function in the chain is NULL
ldr x0, [x0, PHYS_DEV_OFFSET_PHYS_DEV_TERM] ; Unwrap the VkPhysicalDevice in x0
br x10 ; Jump to the next function in the chain
terminError$num
mov x10, (FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * $num)) ; Offset of the function name string in the instance
ldr x11, [x9, INSTANCE_OFFSET_ICD_TERM] ; Load the instance pointer
mov x0, x11 ; Vulkan instance pointer (first arg)
mov x1, VULKAN_LOADER_ERROR_BIT ; The error logging bit (second arg)
mov x2, #0 ; Zero (third arg)
ldr x3, [x11, x10] ; The function name (fourth arg)
bl loader_log_asm_function_not_supported ; Log the error message before we crash
mov x0, #0
br x0 ; Crash intentionally by jumping to address zero
ENDFUNC
MEND
MACRO
DevExtTramp $num
ALIGN
EXPORT vkdev_ext$num [FUNC]
vkdev_ext$num FUNCTION
ldr x9, [x0] ; Load the loader_instance_dispatch_table* into x9
mov x10, (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * $num)) ; Offset of the desired function in the dispatch table
ldr x11, [x9, x10] ; Load the function address
br x11
ENDFUNC
MEND
; 32 bit (armhf) assembly
ELSE
MACRO
PhysDevExtTramp $num
ALIGN
EXPORT vkPhysDevExtTramp$num [FUNC]
vkPhysDevExtTramp$num FUNCTION
ldr r4, [r0] ; Load the loader_instance_dispatch_table* into r4
ldr r0, [r0, #PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] ; Load the unwrapped VkPhysicalDevice into r0
mov r5, #(PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * $num)) ; Put the offset of the entry in the dispatch table for the function
ldr r6, [r4, r5] ; Load the address to branch to out of the dispatch table
bx r6 ; Branch to the next member of the dispatch chain
ENDFUNC
MEND
MACRO
$label PhysDevExtTermin $num
ALIGN
EXPORT vkPhysDevExtTermin$num [FUNC]
vkPhysDevExtTermin$num FUNCTION
ldr r4, [r0, #ICD_TERM_OFFSET_PHYS_DEV_TERM] ; Load the loader_icd_term* in r4
mov r6, #(DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * $num)) ; Put the offset into the dispatch table in r6
ldr r5, [r4, r6] ; Load the address of the next function in the dispatch chain
cbz r5, terminError$num ; Go to the error section if the next function in the chain is NULL
ldr r0, [r0, #PHYS_DEV_OFFSET_PHYS_DEV_TERM] ; Unwrap the VkPhysicalDevice in r0
bx r5 ; Jump to the next function in the chain
terminError$num
mov r5, #(FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * $num)) ; Offset of the function name string in the instance
ldr r6, [r4, #INSTANCE_OFFSET_ICD_TERM] ; Load the instance pointer
mov r0, r6 ; Vulkan instance pointer (first arg)
mov r1, #VULKAN_LOADER_ERROR_BIT ; The error logging bit (second arg)
mov r2, #0 ; Zero (third arg)
ldr r3, [r6, r5] ; The function name (fourth arg)
bl loader_log_asm_function_not_supported ; Log the error message before we crash
mov r0, #0
bx r0 ; Crash intentionally by jumping to address zero
ENDFUNC
MEND
MACRO
DevExtTramp $num
ALIGN
EXPORT vkdev_ext$num [FUNC]
vkdev_ext$num FUNCTION
ldr r4, [r0] ; Load the loader_instance_dispatch_table* into r4
mov r5, #(EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * $num)) ; Offset of the desired function in the dispatch table
ldr r6, [r4, r5] ; Load the function address
bx r6
ENDFUNC
MEND
ENDIF
AREA terminator_string_data, DATA, READONLY
termin_error_string DCB "Function %s not supported for this physical device", 0
AREA UnknownFunctionImpl, CODE, READONLY
PhysDevExtTramp 0
PhysDevExtTramp 1
PhysDevExtTramp 2
PhysDevExtTramp 3
PhysDevExtTramp 4
PhysDevExtTramp 5
PhysDevExtTramp 6
PhysDevExtTramp 7
PhysDevExtTramp 8
PhysDevExtTramp 9
PhysDevExtTramp 10
PhysDevExtTramp 11
PhysDevExtTramp 12
PhysDevExtTramp 13
PhysDevExtTramp 14
PhysDevExtTramp 15
PhysDevExtTramp 16
PhysDevExtTramp 17
PhysDevExtTramp 18
PhysDevExtTramp 19
PhysDevExtTramp 20
PhysDevExtTramp 21
PhysDevExtTramp 22
PhysDevExtTramp 23
PhysDevExtTramp 24
PhysDevExtTramp 25
PhysDevExtTramp 26
PhysDevExtTramp 27
PhysDevExtTramp 28
PhysDevExtTramp 29
PhysDevExtTramp 30
PhysDevExtTramp 31
PhysDevExtTramp 32
PhysDevExtTramp 33
PhysDevExtTramp 34
PhysDevExtTramp 35
PhysDevExtTramp 36
PhysDevExtTramp 37
PhysDevExtTramp 38
PhysDevExtTramp 39
PhysDevExtTramp 40
PhysDevExtTramp 41
PhysDevExtTramp 42
PhysDevExtTramp 43
PhysDevExtTramp 44
PhysDevExtTramp 45
PhysDevExtTramp 46
PhysDevExtTramp 47
PhysDevExtTramp 48
PhysDevExtTramp 49
PhysDevExtTramp 50
PhysDevExtTramp 51
PhysDevExtTramp 52
PhysDevExtTramp 53
PhysDevExtTramp 54
PhysDevExtTramp 55
PhysDevExtTramp 56
PhysDevExtTramp 57
PhysDevExtTramp 58
PhysDevExtTramp 59
PhysDevExtTramp 60
PhysDevExtTramp 61
PhysDevExtTramp 62
PhysDevExtTramp 63
PhysDevExtTramp 64
PhysDevExtTramp 65
PhysDevExtTramp 66
PhysDevExtTramp 67
PhysDevExtTramp 68
PhysDevExtTramp 69
PhysDevExtTramp 70
PhysDevExtTramp 71
PhysDevExtTramp 72
PhysDevExtTramp 73
PhysDevExtTramp 74
PhysDevExtTramp 75
PhysDevExtTramp 76
PhysDevExtTramp 77
PhysDevExtTramp 78
PhysDevExtTramp 79
PhysDevExtTramp 80
PhysDevExtTramp 81
PhysDevExtTramp 82
PhysDevExtTramp 83
PhysDevExtTramp 84
PhysDevExtTramp 85
PhysDevExtTramp 86
PhysDevExtTramp 87
PhysDevExtTramp 88
PhysDevExtTramp 89
PhysDevExtTramp 90
PhysDevExtTramp 91
PhysDevExtTramp 92
PhysDevExtTramp 93
PhysDevExtTramp 94
PhysDevExtTramp 95
PhysDevExtTramp 96
PhysDevExtTramp 97
PhysDevExtTramp 98
PhysDevExtTramp 99
PhysDevExtTramp 100
PhysDevExtTramp 101
PhysDevExtTramp 102
PhysDevExtTramp 103
PhysDevExtTramp 104
PhysDevExtTramp 105
PhysDevExtTramp 106
PhysDevExtTramp 107
PhysDevExtTramp 108
PhysDevExtTramp 109
PhysDevExtTramp 110
PhysDevExtTramp 111
PhysDevExtTramp 112
PhysDevExtTramp 113
PhysDevExtTramp 114
PhysDevExtTramp 115
PhysDevExtTramp 116
PhysDevExtTramp 117
PhysDevExtTramp 118
PhysDevExtTramp 119
PhysDevExtTramp 120
PhysDevExtTramp 121
PhysDevExtTramp 122
PhysDevExtTramp 123
PhysDevExtTramp 124
PhysDevExtTramp 125
PhysDevExtTramp 126
PhysDevExtTramp 127
PhysDevExtTramp 128
PhysDevExtTramp 129
PhysDevExtTramp 130
PhysDevExtTramp 131
PhysDevExtTramp 132
PhysDevExtTramp 133
PhysDevExtTramp 134
PhysDevExtTramp 135
PhysDevExtTramp 136
PhysDevExtTramp 137
PhysDevExtTramp 138
PhysDevExtTramp 139
PhysDevExtTramp 140
PhysDevExtTramp 141
PhysDevExtTramp 142
PhysDevExtTramp 143
PhysDevExtTramp 144
PhysDevExtTramp 145
PhysDevExtTramp 146
PhysDevExtTramp 147
PhysDevExtTramp 148
PhysDevExtTramp 149
PhysDevExtTramp 150
PhysDevExtTramp 151
PhysDevExtTramp 152
PhysDevExtTramp 153
PhysDevExtTramp 154
PhysDevExtTramp 155
PhysDevExtTramp 156
PhysDevExtTramp 157
PhysDevExtTramp 158
PhysDevExtTramp 159
PhysDevExtTramp 160
PhysDevExtTramp 161
PhysDevExtTramp 162
PhysDevExtTramp 163
PhysDevExtTramp 164
PhysDevExtTramp 165
PhysDevExtTramp 166
PhysDevExtTramp 167
PhysDevExtTramp 168
PhysDevExtTramp 169
PhysDevExtTramp 170
PhysDevExtTramp 171
PhysDevExtTramp 172
PhysDevExtTramp 173
PhysDevExtTramp 174
PhysDevExtTramp 175
PhysDevExtTramp 176
PhysDevExtTramp 177
PhysDevExtTramp 178
PhysDevExtTramp 179
PhysDevExtTramp 180
PhysDevExtTramp 181
PhysDevExtTramp 182
PhysDevExtTramp 183
PhysDevExtTramp 184
PhysDevExtTramp 185
PhysDevExtTramp 186
PhysDevExtTramp 187
PhysDevExtTramp 188
PhysDevExtTramp 189
PhysDevExtTramp 190
PhysDevExtTramp 191
PhysDevExtTramp 192
PhysDevExtTramp 193
PhysDevExtTramp 194
PhysDevExtTramp 195
PhysDevExtTramp 196
PhysDevExtTramp 197
PhysDevExtTramp 198
PhysDevExtTramp 199
PhysDevExtTramp 200
PhysDevExtTramp 201
PhysDevExtTramp 202
PhysDevExtTramp 203
PhysDevExtTramp 204
PhysDevExtTramp 205
PhysDevExtTramp 206
PhysDevExtTramp 207
PhysDevExtTramp 208
PhysDevExtTramp 209
PhysDevExtTramp 210
PhysDevExtTramp 211
PhysDevExtTramp 212
PhysDevExtTramp 213
PhysDevExtTramp 214
PhysDevExtTramp 215
PhysDevExtTramp 216
PhysDevExtTramp 217
PhysDevExtTramp 218
PhysDevExtTramp 219
PhysDevExtTramp 220
PhysDevExtTramp 221
PhysDevExtTramp 222
PhysDevExtTramp 223
PhysDevExtTramp 224
PhysDevExtTramp 225
PhysDevExtTramp 226
PhysDevExtTramp 227
PhysDevExtTramp 228
PhysDevExtTramp 229
PhysDevExtTramp 230
PhysDevExtTramp 231
PhysDevExtTramp 232
PhysDevExtTramp 233
PhysDevExtTramp 234
PhysDevExtTramp 235
PhysDevExtTramp 236
PhysDevExtTramp 237
PhysDevExtTramp 238
PhysDevExtTramp 239
PhysDevExtTramp 240
PhysDevExtTramp 241
PhysDevExtTramp 242
PhysDevExtTramp 243
PhysDevExtTramp 244
PhysDevExtTramp 245
PhysDevExtTramp 246
PhysDevExtTramp 247
PhysDevExtTramp 248
PhysDevExtTramp 249
PhysDevExtTermin 0
PhysDevExtTermin 1
PhysDevExtTermin 2
PhysDevExtTermin 3
PhysDevExtTermin 4
PhysDevExtTermin 5
PhysDevExtTermin 6
PhysDevExtTermin 7
PhysDevExtTermin 8
PhysDevExtTermin 9
PhysDevExtTermin 10
PhysDevExtTermin 11
PhysDevExtTermin 12
PhysDevExtTermin 13
PhysDevExtTermin 14
PhysDevExtTermin 15
PhysDevExtTermin 16
PhysDevExtTermin 17
PhysDevExtTermin 18
PhysDevExtTermin 19
PhysDevExtTermin 20
PhysDevExtTermin 21
PhysDevExtTermin 22
PhysDevExtTermin 23
PhysDevExtTermin 24
PhysDevExtTermin 25
PhysDevExtTermin 26
PhysDevExtTermin 27
PhysDevExtTermin 28
PhysDevExtTermin 29
PhysDevExtTermin 30
PhysDevExtTermin 31
PhysDevExtTermin 32
PhysDevExtTermin 33
PhysDevExtTermin 34
PhysDevExtTermin 35
PhysDevExtTermin 36
PhysDevExtTermin 37
PhysDevExtTermin 38
PhysDevExtTermin 39
PhysDevExtTermin 40
PhysDevExtTermin 41
PhysDevExtTermin 42
PhysDevExtTermin 43
PhysDevExtTermin 44
PhysDevExtTermin 45
PhysDevExtTermin 46
PhysDevExtTermin 47
PhysDevExtTermin 48
PhysDevExtTermin 49
PhysDevExtTermin 50
PhysDevExtTermin 51
PhysDevExtTermin 52
PhysDevExtTermin 53
PhysDevExtTermin 54
PhysDevExtTermin 55
PhysDevExtTermin 56
PhysDevExtTermin 57
PhysDevExtTermin 58
PhysDevExtTermin 59
PhysDevExtTermin 60
PhysDevExtTermin 61
PhysDevExtTermin 62
PhysDevExtTermin 63
PhysDevExtTermin 64
PhysDevExtTermin 65
PhysDevExtTermin 66
PhysDevExtTermin 67
PhysDevExtTermin 68
PhysDevExtTermin 69
PhysDevExtTermin 70
PhysDevExtTermin 71
PhysDevExtTermin 72
PhysDevExtTermin 73
PhysDevExtTermin 74
PhysDevExtTermin 75
PhysDevExtTermin 76
PhysDevExtTermin 77
PhysDevExtTermin 78
PhysDevExtTermin 79
PhysDevExtTermin 80
PhysDevExtTermin 81
PhysDevExtTermin 82
PhysDevExtTermin 83
PhysDevExtTermin 84
PhysDevExtTermin 85
PhysDevExtTermin 86
PhysDevExtTermin 87
PhysDevExtTermin 88
PhysDevExtTermin 89
PhysDevExtTermin 90
PhysDevExtTermin 91
PhysDevExtTermin 92
PhysDevExtTermin 93
PhysDevExtTermin 94
PhysDevExtTermin 95
PhysDevExtTermin 96
PhysDevExtTermin 97
PhysDevExtTermin 98
PhysDevExtTermin 99
PhysDevExtTermin 100
PhysDevExtTermin 101
PhysDevExtTermin 102
PhysDevExtTermin 103
PhysDevExtTermin 104
PhysDevExtTermin 105
PhysDevExtTermin 106
PhysDevExtTermin 107
PhysDevExtTermin 108
PhysDevExtTermin 109
PhysDevExtTermin 110
PhysDevExtTermin 111
PhysDevExtTermin 112
PhysDevExtTermin 113
PhysDevExtTermin 114
PhysDevExtTermin 115
PhysDevExtTermin 116
PhysDevExtTermin 117
PhysDevExtTermin 118
PhysDevExtTermin 119
PhysDevExtTermin 120
PhysDevExtTermin 121
PhysDevExtTermin 122
PhysDevExtTermin 123
PhysDevExtTermin 124
PhysDevExtTermin 125
PhysDevExtTermin 126
PhysDevExtTermin 127
PhysDevExtTermin 128
PhysDevExtTermin 129
PhysDevExtTermin 130
PhysDevExtTermin 131
PhysDevExtTermin 132
PhysDevExtTermin 133
PhysDevExtTermin 134
PhysDevExtTermin 135
PhysDevExtTermin 136
PhysDevExtTermin 137
PhysDevExtTermin 138
PhysDevExtTermin 139
PhysDevExtTermin 140
PhysDevExtTermin 141
PhysDevExtTermin 142
PhysDevExtTermin 143
PhysDevExtTermin 144
PhysDevExtTermin 145
PhysDevExtTermin 146
PhysDevExtTermin 147
PhysDevExtTermin 148
PhysDevExtTermin 149
PhysDevExtTermin 150
PhysDevExtTermin 151
PhysDevExtTermin 152
PhysDevExtTermin 153
PhysDevExtTermin 154
PhysDevExtTermin 155
PhysDevExtTermin 156
PhysDevExtTermin 157
PhysDevExtTermin 158
PhysDevExtTermin 159
PhysDevExtTermin 160
PhysDevExtTermin 161
PhysDevExtTermin 162
PhysDevExtTermin 163
PhysDevExtTermin 164
PhysDevExtTermin 165
PhysDevExtTermin 166
PhysDevExtTermin 167
PhysDevExtTermin 168
PhysDevExtTermin 169
PhysDevExtTermin 170
PhysDevExtTermin 171
PhysDevExtTermin 172
PhysDevExtTermin 173
PhysDevExtTermin 174
PhysDevExtTermin 175
PhysDevExtTermin 176
PhysDevExtTermin 177
PhysDevExtTermin 178
PhysDevExtTermin 179
PhysDevExtTermin 180
PhysDevExtTermin 181
PhysDevExtTermin 182
PhysDevExtTermin 183
PhysDevExtTermin 184
PhysDevExtTermin 185
PhysDevExtTermin 186
PhysDevExtTermin 187
PhysDevExtTermin 188
PhysDevExtTermin 189
PhysDevExtTermin 190
PhysDevExtTermin 191
PhysDevExtTermin 192
PhysDevExtTermin 193
PhysDevExtTermin 194
PhysDevExtTermin 195
PhysDevExtTermin 196
PhysDevExtTermin 197
PhysDevExtTermin 198
PhysDevExtTermin 199
PhysDevExtTermin 200
PhysDevExtTermin 201
PhysDevExtTermin 202
PhysDevExtTermin 203
PhysDevExtTermin 204
PhysDevExtTermin 205
PhysDevExtTermin 206
PhysDevExtTermin 207
PhysDevExtTermin 208
PhysDevExtTermin 209
PhysDevExtTermin 210
PhysDevExtTermin 211
PhysDevExtTermin 212
PhysDevExtTermin 213
PhysDevExtTermin 214
PhysDevExtTermin 215
PhysDevExtTermin 216
PhysDevExtTermin 217
PhysDevExtTermin 218
PhysDevExtTermin 219
PhysDevExtTermin 220
PhysDevExtTermin 221
PhysDevExtTermin 222
PhysDevExtTermin 223
PhysDevExtTermin 224
PhysDevExtTermin 225
PhysDevExtTermin 226
PhysDevExtTermin 227
PhysDevExtTermin 228
PhysDevExtTermin 229
PhysDevExtTermin 230
PhysDevExtTermin 231
PhysDevExtTermin 232
PhysDevExtTermin 233
PhysDevExtTermin 234
PhysDevExtTermin 235
PhysDevExtTermin 236
PhysDevExtTermin 237
PhysDevExtTermin 238
PhysDevExtTermin 239
PhysDevExtTermin 240
PhysDevExtTermin 241
PhysDevExtTermin 242
PhysDevExtTermin 243
PhysDevExtTermin 244
PhysDevExtTermin 245
PhysDevExtTermin 246
PhysDevExtTermin 247
PhysDevExtTermin 248
PhysDevExtTermin 249
DevExtTramp 0
DevExtTramp 1
DevExtTramp 2
DevExtTramp 3
DevExtTramp 4
DevExtTramp 5
DevExtTramp 6
DevExtTramp 7
DevExtTramp 8
DevExtTramp 9
DevExtTramp 10
DevExtTramp 11
DevExtTramp 12
DevExtTramp 13
DevExtTramp 14
DevExtTramp 15
DevExtTramp 16
DevExtTramp 17
DevExtTramp 18
DevExtTramp 19
DevExtTramp 20
DevExtTramp 21
DevExtTramp 22
DevExtTramp 23
DevExtTramp 24
DevExtTramp 25
DevExtTramp 26
DevExtTramp 27
DevExtTramp 28
DevExtTramp 29
DevExtTramp 30
DevExtTramp 31
DevExtTramp 32
DevExtTramp 33
DevExtTramp 34
DevExtTramp 35
DevExtTramp 36
DevExtTramp 37
DevExtTramp 38
DevExtTramp 39
DevExtTramp 40
DevExtTramp 41
DevExtTramp 42
DevExtTramp 43
DevExtTramp 44
DevExtTramp 45
DevExtTramp 46
DevExtTramp 47
DevExtTramp 48
DevExtTramp 49
DevExtTramp 50
DevExtTramp 51
DevExtTramp 52
DevExtTramp 53
DevExtTramp 54
DevExtTramp 55
DevExtTramp 56
DevExtTramp 57
DevExtTramp 58
DevExtTramp 59
DevExtTramp 60
DevExtTramp 61
DevExtTramp 62
DevExtTramp 63
DevExtTramp 64
DevExtTramp 65
DevExtTramp 66
DevExtTramp 67
DevExtTramp 68
DevExtTramp 69
DevExtTramp 70
DevExtTramp 71
DevExtTramp 72
DevExtTramp 73
DevExtTramp 74
DevExtTramp 75
DevExtTramp 76
DevExtTramp 77
DevExtTramp 78
DevExtTramp 79
DevExtTramp 80
DevExtTramp 81
DevExtTramp 82
DevExtTramp 83
DevExtTramp 84
DevExtTramp 85
DevExtTramp 86
DevExtTramp 87
DevExtTramp 88
DevExtTramp 89
DevExtTramp 90
DevExtTramp 91
DevExtTramp 92
DevExtTramp 93
DevExtTramp 94
DevExtTramp 95
DevExtTramp 96
DevExtTramp 97
DevExtTramp 98
DevExtTramp 99
DevExtTramp 100
DevExtTramp 101
DevExtTramp 102
DevExtTramp 103
DevExtTramp 104
DevExtTramp 105
DevExtTramp 106
DevExtTramp 107
DevExtTramp 108
DevExtTramp 109
DevExtTramp 110
DevExtTramp 111
DevExtTramp 112
DevExtTramp 113
DevExtTramp 114
DevExtTramp 115
DevExtTramp 116
DevExtTramp 117
DevExtTramp 118
DevExtTramp 119
DevExtTramp 120
DevExtTramp 121
DevExtTramp 122
DevExtTramp 123
DevExtTramp 124
DevExtTramp 125
DevExtTramp 126
DevExtTramp 127
DevExtTramp 128
DevExtTramp 129
DevExtTramp 130
DevExtTramp 131
DevExtTramp 132
DevExtTramp 133
DevExtTramp 134
DevExtTramp 135
DevExtTramp 136
DevExtTramp 137
DevExtTramp 138
DevExtTramp 139
DevExtTramp 140
DevExtTramp 141
DevExtTramp 142
DevExtTramp 143
DevExtTramp 144
DevExtTramp 145
DevExtTramp 146
DevExtTramp 147
DevExtTramp 148
DevExtTramp 149
DevExtTramp 150
DevExtTramp 151
DevExtTramp 152
DevExtTramp 153
DevExtTramp 154
DevExtTramp 155
DevExtTramp 156
DevExtTramp 157
DevExtTramp 158
DevExtTramp 159
DevExtTramp 160
DevExtTramp 161
DevExtTramp 162
DevExtTramp 163
DevExtTramp 164
DevExtTramp 165
DevExtTramp 166
DevExtTramp 167
DevExtTramp 168
DevExtTramp 169
DevExtTramp 170
DevExtTramp 171
DevExtTramp 172
DevExtTramp 173
DevExtTramp 174
DevExtTramp 175
DevExtTramp 176
DevExtTramp 177
DevExtTramp 178
DevExtTramp 179
DevExtTramp 180
DevExtTramp 181
DevExtTramp 182
DevExtTramp 183
DevExtTramp 184
DevExtTramp 185
DevExtTramp 186
DevExtTramp 187
DevExtTramp 188
DevExtTramp 189
DevExtTramp 190
DevExtTramp 191
DevExtTramp 192
DevExtTramp 193
DevExtTramp 194
DevExtTramp 195
DevExtTramp 196
DevExtTramp 197
DevExtTramp 198
DevExtTramp 199
DevExtTramp 200
DevExtTramp 201
DevExtTramp 202
DevExtTramp 203
DevExtTramp 204
DevExtTramp 205
DevExtTramp 206
DevExtTramp 207
DevExtTramp 208
DevExtTramp 209
DevExtTramp 210
DevExtTramp 211
DevExtTramp 212
DevExtTramp 213
DevExtTramp 214
DevExtTramp 215
DevExtTramp 216
DevExtTramp 217
DevExtTramp 218
DevExtTramp 219
DevExtTramp 220
DevExtTramp 221
DevExtTramp 222
DevExtTramp 223
DevExtTramp 224
DevExtTramp 225
DevExtTramp 226
DevExtTramp 227
DevExtTramp 228
DevExtTramp 229
DevExtTramp 230
DevExtTramp 231
DevExtTramp 232
DevExtTramp 233
DevExtTramp 234
DevExtTramp 235
DevExtTramp 236
DevExtTramp 237
DevExtTramp 238
DevExtTramp 239
DevExtTramp 240
DevExtTramp 241
DevExtTramp 242
DevExtTramp 243
DevExtTramp 244
DevExtTramp 245
DevExtTramp 246
DevExtTramp 247
DevExtTramp 248
DevExtTramp 249
END
+40
View File
@@ -24,6 +24,44 @@
#include "unknown_function_handling.h"
// If the assembly code necessary for unknown functions isn't supported, then replace all of the functions with stubs.
// This way, if an application queries for an unknown function, they receive NULL and can act accordingly.
// Previously, there was a fallback path written in C. However, it depended on the compiler optimizing the functions
// in such a way as to not disturb the callstack. This reliance on implementation defined behavior is unsustainable and was only
// known to work with GCC.
#if !defined(UNKNOWN_FUNCTIONS_SUPPORTED)
void loader_init_dispatch_dev_ext(struct loader_instance *inst, struct loader_device *dev) {
(void)inst;
(void)dev;
}
void *loader_dev_ext_gpa_tramp(struct loader_instance *inst, const char *funcName) {
(void)inst;
(void)funcName;
return NULL;
}
void *loader_dev_ext_gpa_term(struct loader_instance *inst, const char *funcName) {
(void)inst;
(void)funcName;
return NULL;
}
void *loader_phys_dev_ext_gpa_tramp(struct loader_instance *inst, const char *funcName) {
(void)inst;
(void)funcName;
return NULL;
}
void *loader_phys_dev_ext_gpa_term(struct loader_instance *inst, const char *funcName) {
(void)inst;
(void)funcName;
return NULL;
}
void loader_free_dev_ext_table(struct loader_instance *inst) { (void)inst; }
void loader_free_phys_dev_ext_table(struct loader_instance *inst) { (void)inst; }
#else
#include "allocation.h"
#include "log.h"
@@ -337,3 +375,5 @@ void *loader_phys_dev_ext_gpa_tramp(struct loader_instance *inst, const char *fu
void *loader_phys_dev_ext_gpa_term(struct loader_instance *inst, const char *funcName) {
return loader_phys_dev_ext_gpa_impl(inst, funcName, false);
}
#endif
+36 -6
View File
@@ -71,9 +71,9 @@
#include <io.h>
#include <shlwapi.h>
#include <direct.h>
#endif // defined(_WIN32)
#include "stack_allocation.h"
#endif // defined(_WIN32)
#if defined(APPLE_STATIC_LOADER) && !defined(__APPLE__)
#error "APPLE_STATIC_LOADER can only be defined on Apple platforms!"
@@ -89,6 +89,17 @@
#define LOADER_EXPORT
#endif
// For testing purposes, we want to expose some functions not normally callable on the library
#if defined(SHOULD_EXPORT_TEST_FUNCTIONS)
#if defined(_WIN32)
#define TEST_FUNCTION_EXPORT __declspec(dllexport)
#else
#define TEST_FUNCTION_EXPORT LOADER_EXPORT
#endif
#else
#define TEST_FUNCTION_EXPORT
#endif
#define MAX_STRING_SIZE 1024
// This is defined in vk_layer.h, but if there's problems we need to create the define
@@ -100,10 +111,10 @@
// Environment Variable information
#define VK_ICD_FILENAMES_ENV_VAR "VK_ICD_FILENAMES" // Deprecated in v1.3.207 loader
#define VK_DRIVER_FILES_ENV_VAR "VK_DRIVER_FILES"
#define VK_LAYER_PATH_ENV_VAR "VK_LAYER_PATH"
#define VK_EXPLICIT_LAYER_PATH_ENV_VAR "VK_LAYER_PATH"
// Support added in v1.3.207 loader
#define VK_ADDITIONAL_DRIVER_FILES_ENV_VAR "VK_ADD_DRIVER_FILES"
#define VK_ADDITIONAL_LAYER_PATH_ENV_VAR "VK_ADD_LAYER_PATH"
#define VK_ADDITIONAL_EXPLICIT_LAYER_PATH_ENV_VAR "VK_ADD_LAYER_PATH"
// Support added in v1.3.234 loader
#define VK_LAYERS_ENABLE_ENV_VAR "VK_LOADER_LAYERS_ENABLE"
#define VK_LAYERS_DISABLE_ENV_VAR "VK_LOADER_LAYERS_DISABLE"
@@ -115,6 +126,9 @@
#define VK_LOADER_DISABLE_ALL_LAYERS_VAR_3 "**"
#define VK_LOADER_DISABLE_IMPLICIT_LAYERS_VAR "~implicit~"
#define VK_LOADER_DISABLE_EXPLICIT_LAYERS_VAR "~explicit~"
// Support added in v1.3.295 loader
#define VK_IMPLICIT_LAYER_PATH_ENV_VAR "VK_IMPLICIT_LAYER_PATH"
#define VK_ADDITIONAL_IMPLICIT_LAYER_PATH_ENV_VAR "VK_ADD_IMPLICIT_LAYER_PATH"
// Override layer information
#define VK_OVERRIDE_LAYER_NAME "VK_LAYER_LUNARG_override"
@@ -151,8 +165,10 @@
#define VK_SETTINGS_INFO_REGISTRY_LOC ""
#if defined(__QNX__)
#ifndef SYSCONFDIR
#define SYSCONFDIR "/etc"
#endif
#endif
// C99:
#define PRINTF_SIZE_T_SPECIFIER "%zu"
@@ -227,9 +243,14 @@ extern bool loader_disable_dynamic_library_unloading;
// Returns true if the DIRECTORY_SYMBOL is contained within path
static inline bool loader_platform_is_path(const char *path) { return strchr(path, DIRECTORY_SYMBOL) != NULL; }
// The once init functionality is not used when building a DLL on Windows. This is because there is no way to clean up the
// resources allocated by anything allocated by once init. This isn't a problem for static libraries, but it is for dynamic
// ones. When building a DLL, we use DllMain() instead to allow properly cleaning up resources.
// The loader has various initialization tasks which it must do before user code can run. This includes initializing synchronization
// objects, determining the log level, writing the version of the loader to the log, and loading dll's (on windows). On linux, the
// solution is simply running the initialization code in __attribute__((constructor)), which MacOS uses when the loader is
// dynamically linked. When statically linking on MacOS, the setup code instead uses pthread_once to run the logic a single time
// regardless of which API function the application calls first. On Windows, the equivalent way to run code at dll load time is
// DllMain which has many limitations placed upon it. Instead, the Windows code follows MacOS and does initialization in the first
// API call made, using InitOnceExecuteOnce, except for initialization primitives which must be done in DllMain. This is because
// there is no way to clean up the resources allocated by anything allocated by once init.
#if defined(APPLE_STATIC_LOADER)
static inline void loader_platform_thread_once_fn(pthread_once_t *ctl, void (*func)(void)) {
@@ -240,6 +261,13 @@ static inline void loader_platform_thread_once_fn(pthread_once_t *ctl, void (*fu
#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) pthread_once_t var = PTHREAD_ONCE_INIT;
#define LOADER_PLATFORM_THREAD_ONCE_EXTERN_DEFINITION(var) extern pthread_once_t var;
#define LOADER_PLATFORM_THREAD_ONCE(ctl, func) loader_platform_thread_once_fn(ctl, func);
#elif defined(WIN32)
static inline void loader_platform_thread_win32_once_fn(INIT_ONCE *ctl, PINIT_ONCE_FN func) {
InitOnceExecuteOnce(ctl, func, NULL, NULL);
}
#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) INIT_ONCE var = INIT_ONCE_STATIC_INIT;
#define LOADER_PLATFORM_THREAD_ONCE_EXTERN_DEFINITION(var) extern INIT_ONCE var;
#define LOADER_PLATFORM_THREAD_ONCE(ctl, func) loader_platform_thread_win32_once_fn(ctl, func);
#else
#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var)
#define LOADER_PLATFORM_THREAD_ONCE_EXTERN_DEFINITION(var)
@@ -329,7 +357,9 @@ static inline char *loader_platform_executable_path(char *buffer, size_t size) {
static inline char *loader_platform_executable_path(char *buffer, size_t size) { return NULL; }
#elif defined(__QNX__)
#ifndef SYSCONFDIR
#define SYSCONFDIR "/etc"
#endif
#include <fcntl.h>
#include <sys/stat.h>
+24 -4
View File
@@ -1,9 +1,9 @@
;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Copyright (c) 2015-2021 The Khronos Group Inc.
; Copyright (c) 2015-2021 Valve Corporation
; Copyright (c) 2015-2021 LunarG, Inc.
; Copyright (c) 2015-2024 The Khronos Group Inc.
; Copyright (c) 2015-2024 Valve Corporation
; Copyright (c) 2015-2024 LunarG, Inc.
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
@@ -275,4 +275,24 @@ EXPORTS
vkCmdSetPrimitiveRestartEnable
vkGetDeviceBufferMemoryRequirements
vkGetDeviceImageMemoryRequirements
vkGetDeviceImageSparseMemoryRequirements
vkGetDeviceImageSparseMemoryRequirements
vkCmdSetLineStipple
vkMapMemory2
vkUnmapMemory2
vkCmdBindIndexBuffer2
vkGetRenderingAreaGranularity
vkGetDeviceImageSubresourceLayout
vkGetImageSubresourceLayout2
vkCmdPushDescriptorSet
vkCmdPushDescriptorSetWithTemplate
vkCmdSetRenderingAttachmentLocations
vkCmdSetRenderingInputAttachmentIndices
vkCmdBindDescriptorSets2
vkCmdPushConstants2
vkCmdPushDescriptorSet2
vkCmdPushDescriptorSetWithTemplate2
vkCopyMemoryToImage
vkCopyImageToMemory
vkCopyImageToImage
vkTransitionImageLayout
+490 -523
View File
File diff suppressed because it is too large Load Diff
+5 -1
View File
@@ -25,6 +25,10 @@
#include "loader_common.h"
typedef struct {
// This union holds the data that drivers which use ICD interface version 2 and before expect. This is so they can dereference
// VkSurfaceKHR to get this struct and access the creation parameters used in subsequent API calls, such as get surface formats
// & get surface present modes.
// Thus, these members need to stay here in order to preserve ABI compatibility.
union {
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
VkIcdSurfaceWayland wayland_surf;
@@ -66,7 +70,7 @@ typedef struct {
uint32_t platform_size; // Size of corresponding VkIcdSurfaceXXX
uint32_t non_platform_offset; // Start offset to base_size
uint32_t entire_size; // Size of entire VkIcdSurface
VkSurfaceKHR *real_icd_surfaces;
uint32_t surface_index; // This surface's index into each drivers list of created surfaces
} VkIcdSurface;
bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr);
+3 -3
View File
@@ -65,7 +65,7 @@ if (UPDATE_DEPS)
math(EXPR bitness "8 * ${CMAKE_SIZEOF_VOID_P}")
set(UPDATE_DEPS_DIR_SUFFIX "${UPDATE_DEPS_DIR_SUFFIX}/${bitness}")
endif()
endif()
endif()
set(UPDATE_DEPS_DIR "${PROJECT_SOURCE_DIR}/external/${UPDATE_DEPS_DIR_SUFFIX}" CACHE PATH "Location where update_deps.py installs packages")
list(APPEND update_dep_command "--dir" )
list(APPEND update_dep_command "${UPDATE_DEPS_DIR}")
@@ -139,8 +139,8 @@ if (VULKAN_HEADERS_INSTALL_DIR)
set(CMAKE_REQUIRE_FIND_PACKAGE_VulkanHeaders TRUE PARENT_SCOPE)
endif()
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
if (CMAKE_CROSSCOMPILING)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
else()
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
endif()
+665
View File
@@ -0,0 +1,665 @@
#
# Copyright (C) 2018-2020 by George Cave - gcave@stablecoder.ca
#
# 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.
# USAGE: To enable any code coverage instrumentation/targets, the single CMake
# option of `CODE_COVERAGE` needs to be set to 'ON', either by GUI, ccmake, or
# on the command line.
#
# From this point, there are two primary methods for adding instrumentation to
# targets: 1 - A blanket instrumentation by calling `add_code_coverage()`, where
# all targets in that directory and all subdirectories are automatically
# instrumented. 2 - Per-target instrumentation by calling
# `target_code_coverage(<TARGET_NAME>)`, where the target is given and thus only
# that target is instrumented. This applies to both libraries and executables.
#
# To add coverage targets, such as calling `make ccov` to generate the actual
# coverage information for perusal or consumption, call
# `target_code_coverage(<TARGET_NAME>)` on an *executable* target.
#
# Example 1: All targets instrumented
#
# In this case, the coverage information reported will will be that of the
# `theLib` library target and `theExe` executable.
#
# 1a: Via global command
#
# ~~~
# add_code_coverage() # Adds instrumentation to all targets
#
# add_library(theLib lib.cpp)
#
# add_executable(theExe main.cpp)
# target_link_libraries(theExe PRIVATE theLib)
# target_code_coverage(theExe) # As an executable target, adds the 'ccov-theExe' target (instrumentation already added via global anyways) for generating code coverage reports.
# ~~~
#
# 1b: Via target commands
#
# ~~~
# add_library(theLib lib.cpp)
# target_code_coverage(theLib) # As a library target, adds coverage instrumentation but no targets.
#
# add_executable(theExe main.cpp)
# target_link_libraries(theExe PRIVATE theLib)
# target_code_coverage(theExe) # As an executable target, adds the 'ccov-theExe' target and instrumentation for generating code coverage reports.
# ~~~
#
# Example 2: Target instrumented, but with regex pattern of files to be excluded
# from report
#
# ~~~
# add_executable(theExe main.cpp non_covered.cpp)
# target_code_coverage(theExe EXCLUDE non_covered.cpp test/*) # As an executable target, the reports will exclude the non-covered.cpp file, and any files in a test/ folder.
# ~~~
#
# Example 3: Target added to the 'ccov' and 'ccov-all' targets
#
# ~~~
# add_code_coverage_all_targets(EXCLUDE test/*) # Adds the 'ccov-all' target set and sets it to exclude all files in test/ folders.
#
# add_executable(theExe main.cpp non_covered.cpp)
# target_code_coverage(theExe AUTO ALL EXCLUDE non_covered.cpp test/*) # As an executable target, adds to the 'ccov' and ccov-all' targets, and the reports will exclude the non-covered.cpp file, and any files in a test/ folder.
# ~~~
# Options
# option(
# CODE_COVERAGE
# "Builds targets with code coverage instrumentation. (Requires GCC or Clang)"
# OFF)
# Programs
find_program(LLVM_COV_PATH llvm-cov)
find_program(LLVM_PROFDATA_PATH llvm-profdata)
find_program(LCOV_PATH lcov)
find_program(GENHTML_PATH genhtml)
# Hide behind the 'advanced' mode flag for GUI/ccmake
mark_as_advanced(FORCE LLVM_COV_PATH LLVM_PROFDATA_PATH LCOV_PATH GENHTML_PATH)
# Variables
set(CMAKE_COVERAGE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/ccov)
set_property(GLOBAL PROPERTY JOB_POOLS ccov_serial_pool=1)
# Common initialization/checks
if(CODE_COVERAGE AND NOT CODE_COVERAGE_ADDED)
set(CODE_COVERAGE_ADDED ON)
# Common Targets
add_custom_target(
ccov-preprocessing
COMMAND ${CMAKE_COMMAND} -E make_directory
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}
DEPENDS ccov-clean)
if(CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang"
OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?[Cc]lang")
# Messages
message(STATUS "Building with llvm Code Coverage Tools")
if(NOT LLVM_COV_PATH)
message(FATAL_ERROR "llvm-cov not found! Aborting.")
else()
# Version number checking for 'EXCLUDE' compatibility
execute_process(COMMAND ${LLVM_COV_PATH} --version
OUTPUT_VARIABLE LLVM_COV_VERSION_CALL_OUTPUT)
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" LLVM_COV_VERSION
${LLVM_COV_VERSION_CALL_OUTPUT})
if(LLVM_COV_VERSION VERSION_LESS "7.0.0")
message(
WARNING
"target_code_coverage()/add_code_coverage_all_targets() 'EXCLUDE' option only available on llvm-cov >= 7.0.0"
)
endif()
endif()
# Targets
if(${CMAKE_VERSION} VERSION_LESS "3.17.0")
add_custom_target(
ccov-clean
COMMAND ${CMAKE_COMMAND} -E remove -f
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list
COMMAND ${CMAKE_COMMAND} -E remove -f
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/profraw.list)
else()
add_custom_target(
ccov-clean
COMMAND ${CMAKE_COMMAND} -E rm -f
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list
COMMAND ${CMAKE_COMMAND} -E rm -f
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/profraw.list)
endif()
# Used to get the shared object file list before doing the main all-
# processing
add_custom_target(
ccov-libs
COMMAND ;
COMMENT "libs ready for coverage report.")
elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES
"GNU")
# Messages
message(STATUS "Building with lcov Code Coverage Tools")
if(CMAKE_BUILD_TYPE)
string(TOUPPER ${CMAKE_BUILD_TYPE} upper_build_type)
if(NOT ${upper_build_type} STREQUAL "DEBUG")
message(
WARNING
"Code coverage results with an optimized (non-Debug) build may be misleading"
)
endif()
else()
message(
WARNING
"Code coverage results with an optimized (non-Debug) build may be misleading"
)
endif()
if(NOT LCOV_PATH)
message(FATAL_ERROR "lcov not found! Aborting...")
endif()
if(NOT GENHTML_PATH)
message(FATAL_ERROR "genhtml not found! Aborting...")
endif()
# Targets
add_custom_target(ccov-clean COMMAND ${LCOV_PATH} --directory
${CMAKE_BINARY_DIR} --zerocounters)
else()
message(FATAL_ERROR "Code coverage requires Clang or GCC. Aborting.")
endif()
endif()
# Adds code coverage instrumentation to a library, or instrumentation/targets
# for an executable target.
# ~~~
# EXECUTABLE ADDED TARGETS:
# GCOV/LCOV:
# ccov : Generates HTML code coverage report for every target added with 'AUTO' parameter.
# ccov-${TARGET_NAME} : Generates HTML code coverage report for the associated named target.
# ccov-all : Generates HTML code coverage report, merging every target added with 'ALL' parameter into a single detailed report.
#
# LLVM-COV:
# ccov : Generates HTML code coverage report for every target added with 'AUTO' parameter.
# ccov-report : Generates HTML code coverage report for every target added with 'AUTO' parameter.
# ccov-${TARGET_NAME} : Generates HTML code coverage report.
# ccov-report-${TARGET_NAME} : Prints to command line summary per-file coverage information.
# ccov-export-${TARGET_NAME} : Exports the coverage report to a JSON file.
# ccov-show-${TARGET_NAME} : Prints to command line detailed per-line coverage information.
# ccov-all : Generates HTML code coverage report, merging every target added with 'ALL' parameter into a single detailed report.
# ccov-all-report : Prints summary per-file coverage information for every target added with ALL' parameter to the command line.
# ccov-all-export : Exports the coverage report to a JSON file.
#
# Required:
# TARGET_NAME - Name of the target to generate code coverage for.
# Optional:
# PUBLIC - Sets the visibility for added compile options to targets to PUBLIC instead of the default of PRIVATE.
# INTERFACE - Sets the visibility for added compile options to targets to INTERFACE instead of the default of PRIVATE.
# AUTO - Adds the target to the 'ccov' target so that it can be run in a batch with others easily. Effective on executable targets.
# ALL - Adds the target to the 'ccov-all' and 'ccov-all-report' targets, which merge several executable targets coverage data to a single report. Effective on executable targets.
# EXTERNAL - For GCC's lcov, allows the profiling of 'external' files from the processing directory
# COVERAGE_TARGET_NAME - For executables ONLY, changes the outgoing target name so instead of `ccov-${TARGET_NAME}` it becomes `ccov-${COVERAGE_TARGET_NAME}`.
# EXCLUDE <PATTERNS> - Excludes files of the patterns provided from coverage. Note that GCC/lcov excludes by glob pattern, and clang/LLVM excludes via regex! **These do not copy to the 'all' targets.**
# OBJECTS <TARGETS> - For executables ONLY, if the provided targets are shared libraries, adds coverage information to the output
# ARGS <ARGUMENTS> - For executables ONLY, appends the given arguments to the associated ccov-* executable call
# ~~~
function(target_code_coverage TARGET_NAME)
# Argument parsing
set(options AUTO ALL EXTERNAL PUBLIC INTERFACE)
set(single_value_keywords COVERAGE_TARGET_NAME)
set(multi_value_keywords EXCLUDE OBJECTS ARGS)
cmake_parse_arguments(
target_code_coverage "${options}" "${single_value_keywords}"
"${multi_value_keywords}" ${ARGN})
# Set the visibility of target functions to PUBLIC, INTERFACE or default to
# PRIVATE.
if(target_code_coverage_PUBLIC)
set(TARGET_VISIBILITY PUBLIC)
elseif(target_code_coverage_INTERFACE)
set(TARGET_VISIBILITY INTERFACE)
else()
set(TARGET_VISIBILITY PRIVATE)
endif()
if(NOT target_code_coverage_COVERAGE_TARGET_NAME)
# If a specific name was given, use that instead.
set(target_code_coverage_COVERAGE_TARGET_NAME ${TARGET_NAME})
endif()
if(CODE_COVERAGE)
# Add code coverage instrumentation to the target's linker command
if(CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang"
OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?[Cc]lang")
target_compile_options(${TARGET_NAME} ${TARGET_VISIBILITY}
-fprofile-instr-generate -fcoverage-mapping)
target_link_options(${TARGET_NAME} ${TARGET_VISIBILITY}
-fprofile-instr-generate -fcoverage-mapping)
elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES
"GNU")
target_compile_options(${TARGET_NAME} ${TARGET_VISIBILITY} -fprofile-arcs
-ftest-coverage)
target_link_libraries(${TARGET_NAME} ${TARGET_VISIBILITY} gcov)
endif()
# Targets
get_target_property(target_type ${TARGET_NAME} TYPE)
# Add shared library to processing for 'all' targets
if(target_type STREQUAL "SHARED_LIBRARY" AND target_code_coverage_ALL)
if(CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang"
OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?[Cc]lang")
add_custom_target(
ccov-run-${target_code_coverage_COVERAGE_TARGET_NAME}
COMMAND
${CMAKE_COMMAND} -E echo "-object=$<TARGET_FILE:${TARGET_NAME}>" >>
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list
DEPENDS ccov-preprocessing ${TARGET_NAME})
if(NOT TARGET ccov-libs)
message(
FATAL_ERROR
"Calling target_code_coverage with 'ALL' must be after a call to 'add_code_coverage_all_targets'."
)
endif()
add_dependencies(ccov-libs
ccov-run-${target_code_coverage_COVERAGE_TARGET_NAME})
endif()
endif()
# For executables add targets to run and produce output
if(target_type STREQUAL "EXECUTABLE")
if(CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang"
OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?[Cc]lang")
# If there are shared objects to also work with, generate the string to
# add them here
foreach(SO_TARGET ${target_code_coverage_OBJECTS})
# Check to see if the target is a shared object
if(TARGET ${SO_TARGET})
get_target_property(SO_TARGET_TYPE ${SO_TARGET} TYPE)
if(${SO_TARGET_TYPE} STREQUAL "SHARED_LIBRARY")
set(SO_OBJECTS ${SO_OBJECTS} -object=$<TARGET_FILE:${SO_TARGET}>)
endif()
endif()
endforeach()
# Run the executable, generating raw profile data Make the run data
# available for further processing. Separated to allow Windows to run
# this target serially.
add_custom_target(
ccov-run-${target_code_coverage_COVERAGE_TARGET_NAME}
COMMAND
${CMAKE_COMMAND} -E env
LLVM_PROFILE_FILE=${target_code_coverage_COVERAGE_TARGET_NAME}.profraw
$<TARGET_FILE:${TARGET_NAME}> ${target_code_coverage_ARGS}
COMMAND
${CMAKE_COMMAND} -E echo "-object=$<TARGET_FILE:${TARGET_NAME}>"
${SO_OBJECTS} >> ${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list
COMMAND
${CMAKE_COMMAND} -E echo
"${CMAKE_CURRENT_BINARY_DIR}/${target_code_coverage_COVERAGE_TARGET_NAME}.profraw"
>> ${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/profraw.list
JOB_POOL ccov_serial_pool
DEPENDS ccov-preprocessing ccov-libs ${TARGET_NAME})
# Merge the generated profile data so llvm-cov can process it
add_custom_target(
ccov-processing-${target_code_coverage_COVERAGE_TARGET_NAME}
COMMAND
${LLVM_PROFDATA_PATH} merge -sparse
${target_code_coverage_COVERAGE_TARGET_NAME}.profraw -o
${target_code_coverage_COVERAGE_TARGET_NAME}.profdata
DEPENDS ccov-run-${target_code_coverage_COVERAGE_TARGET_NAME})
# Ignore regex only works on LLVM >= 7
if(LLVM_COV_VERSION VERSION_GREATER_EQUAL "7.0.0")
foreach(EXCLUDE_ITEM ${target_code_coverage_EXCLUDE})
set(EXCLUDE_REGEX ${EXCLUDE_REGEX}
-ignore-filename-regex='${EXCLUDE_ITEM}')
endforeach()
endif()
# Print out details of the coverage information to the command line
add_custom_target(
ccov-show-${target_code_coverage_COVERAGE_TARGET_NAME}
COMMAND
${LLVM_COV_PATH} show $<TARGET_FILE:${TARGET_NAME}> ${SO_OBJECTS}
-instr-profile=${target_code_coverage_COVERAGE_TARGET_NAME}.profdata
-show-line-counts-or-regions ${EXCLUDE_REGEX}
DEPENDS ccov-processing-${target_code_coverage_COVERAGE_TARGET_NAME})
# Print out a summary of the coverage information to the command line
add_custom_target(
ccov-report-${target_code_coverage_COVERAGE_TARGET_NAME}
COMMAND
${LLVM_COV_PATH} report $<TARGET_FILE:${TARGET_NAME}> ${SO_OBJECTS}
-instr-profile=${target_code_coverage_COVERAGE_TARGET_NAME}.profdata
${EXCLUDE_REGEX}
DEPENDS ccov-processing-${target_code_coverage_COVERAGE_TARGET_NAME})
# Export coverage information so continuous integration tools (e.g.
# Jenkins) can consume it
add_custom_target(
ccov-export-${target_code_coverage_COVERAGE_TARGET_NAME}
COMMAND
${LLVM_COV_PATH} export $<TARGET_FILE:${TARGET_NAME}> ${SO_OBJECTS}
-instr-profile=${target_code_coverage_COVERAGE_TARGET_NAME}.profdata
-format="text" ${EXCLUDE_REGEX} >
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/${target_code_coverage_COVERAGE_TARGET_NAME}.json
DEPENDS ccov-processing-${target_code_coverage_COVERAGE_TARGET_NAME})
# Generates HTML output of the coverage information for perusal
add_custom_target(
ccov-${target_code_coverage_COVERAGE_TARGET_NAME}
COMMAND
${LLVM_COV_PATH} show $<TARGET_FILE:${TARGET_NAME}> ${SO_OBJECTS}
-instr-profile=${target_code_coverage_COVERAGE_TARGET_NAME}.profdata
-show-line-counts-or-regions
-output-dir=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/${target_code_coverage_COVERAGE_TARGET_NAME}
-format="html" ${EXCLUDE_REGEX}
DEPENDS ccov-processing-${target_code_coverage_COVERAGE_TARGET_NAME})
elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES
"GNU")
set(COVERAGE_INFO
"${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/${target_code_coverage_COVERAGE_TARGET_NAME}.info"
)
# Run the executable, generating coverage information
add_custom_target(
ccov-run-${target_code_coverage_COVERAGE_TARGET_NAME}
COMMAND $<TARGET_FILE:${TARGET_NAME}> ${target_code_coverage_ARGS}
DEPENDS ccov-preprocessing ${TARGET_NAME})
# Generate exclusion string for use
foreach(EXCLUDE_ITEM ${target_code_coverage_EXCLUDE})
set(EXCLUDE_REGEX ${EXCLUDE_REGEX} --remove ${COVERAGE_INFO}
'${EXCLUDE_ITEM}')
endforeach()
if(EXCLUDE_REGEX)
set(EXCLUDE_COMMAND ${LCOV_PATH} ${EXCLUDE_REGEX} --output-file
${COVERAGE_INFO})
else()
set(EXCLUDE_COMMAND ;)
endif()
if(NOT ${target_code_coverage_EXTERNAL})
set(EXTERNAL_OPTION --no-external)
endif()
# Capture coverage data
if(${CMAKE_VERSION} VERSION_LESS "3.17.0")
add_custom_target(
ccov-capture-${target_code_coverage_COVERAGE_TARGET_NAME}
COMMAND ${CMAKE_COMMAND} -E remove -f ${COVERAGE_INFO}
COMMAND ${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --zerocounters
COMMAND $<TARGET_FILE:${TARGET_NAME}> ${target_code_coverage_ARGS}
COMMAND
${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --base-directory
${CMAKE_SOURCE_DIR} --capture ${EXTERNAL_OPTION} --output-file
${COVERAGE_INFO}
COMMAND ${EXCLUDE_COMMAND}
DEPENDS ccov-preprocessing ${TARGET_NAME})
else()
add_custom_target(
ccov-capture-${target_code_coverage_COVERAGE_TARGET_NAME}
COMMAND ${CMAKE_COMMAND} -E rm -f ${COVERAGE_INFO}
COMMAND ${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --zerocounters
COMMAND $<TARGET_FILE:${TARGET_NAME}> ${target_code_coverage_ARGS}
COMMAND
${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --base-directory
${CMAKE_SOURCE_DIR} --capture ${EXTERNAL_OPTION} --output-file
${COVERAGE_INFO}
COMMAND ${EXCLUDE_COMMAND}
DEPENDS ccov-preprocessing ${TARGET_NAME})
endif()
# Generates HTML output of the coverage information for perusal
add_custom_target(
ccov-${target_code_coverage_COVERAGE_TARGET_NAME}
COMMAND
${GENHTML_PATH} -o
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/${target_code_coverage_COVERAGE_TARGET_NAME}
${COVERAGE_INFO}
DEPENDS ccov-capture-${target_code_coverage_COVERAGE_TARGET_NAME})
endif()
add_custom_command(
TARGET ccov-${target_code_coverage_COVERAGE_TARGET_NAME}
POST_BUILD
COMMAND ;
COMMENT
"Open ${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/${target_code_coverage_COVERAGE_TARGET_NAME}/index.html in your browser to view the coverage report."
)
# AUTO
if(target_code_coverage_AUTO)
if(NOT TARGET ccov)
add_custom_target(ccov)
endif()
add_dependencies(ccov ccov-${target_code_coverage_COVERAGE_TARGET_NAME})
if(NOT CMAKE_C_COMPILER_ID MATCHES "GNU" AND NOT CMAKE_CXX_COMPILER_ID
MATCHES "GNU")
if(NOT TARGET ccov-report)
add_custom_target(ccov-report)
endif()
add_dependencies(
ccov-report
ccov-report-${target_code_coverage_COVERAGE_TARGET_NAME})
endif()
endif()
# ALL
if(target_code_coverage_ALL)
if(NOT TARGET ccov-all-processing)
message(
FATAL_ERROR
"Calling target_code_coverage with 'ALL' must be after a call to 'add_code_coverage_all_targets'."
)
endif()
add_dependencies(ccov-all-processing
ccov-run-${target_code_coverage_COVERAGE_TARGET_NAME})
endif()
endif()
endif()
endfunction()
# Adds code coverage instrumentation to all targets in the current directory and
# any subdirectories. To add coverage instrumentation to only specific targets,
# use `target_code_coverage`.
function(add_code_coverage)
if(CODE_COVERAGE)
if(CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang"
OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?[Cc]lang")
add_compile_options(-fprofile-instr-generate -fcoverage-mapping)
add_link_options(-fprofile-instr-generate -fcoverage-mapping)
elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES
"GNU")
add_compile_options(-fprofile-arcs -ftest-coverage)
link_libraries(gcov)
endif()
endif()
endfunction()
# Adds the 'ccov-all' type targets that calls all targets added via
# `target_code_coverage` with the `ALL` parameter, but merges all the coverage
# data from them into a single large report instead of the numerous smaller
# reports. Also adds the ccov-all-capture Generates an all-merged.info file, for
# use with coverage dashboards (e.g. codecov.io, coveralls).
# ~~~
# Optional:
# EXCLUDE <PATTERNS> - Excludes files of the patterns provided from coverage. Note that GCC/lcov excludes by glob pattern, and clang/LLVM excludes via regex!
# ~~~
function(add_code_coverage_all_targets)
# Argument parsing
set(multi_value_keywords EXCLUDE)
cmake_parse_arguments(add_code_coverage_all_targets "" ""
"${multi_value_keywords}" ${ARGN})
if(CODE_COVERAGE)
if(CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang"
OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?[Cc]lang")
# Merge the profile data for all of the run executables
if(WIN32)
add_custom_target(
ccov-all-processing
COMMAND
powershell -Command $$FILELIST = Get-Content
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/profraw.list\; llvm-profdata.exe
merge -o ${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.profdata
-sparse $$FILELIST)
else()
add_custom_target(
ccov-all-processing
COMMAND
${LLVM_PROFDATA_PATH} merge -o
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.profdata -sparse `cat
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/profraw.list`)
endif()
# Regex exclude only available for LLVM >= 7
if(LLVM_COV_VERSION VERSION_GREATER_EQUAL "7.0.0")
foreach(EXCLUDE_ITEM ${add_code_coverage_all_targets_EXCLUDE})
set(EXCLUDE_REGEX ${EXCLUDE_REGEX}
-ignore-filename-regex='${EXCLUDE_ITEM}')
endforeach()
endif()
# Print summary of the code coverage information to the command line
if(WIN32)
add_custom_target(
ccov-all-report
COMMAND
powershell -Command $$FILELIST = Get-Content
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list\; llvm-cov.exe
report $$FILELIST
-instr-profile=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.profdata
${EXCLUDE_REGEX}
DEPENDS ccov-all-processing)
else()
add_custom_target(
ccov-all-report
COMMAND
${LLVM_COV_PATH} report `cat
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list`
-instr-profile=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.profdata
${EXCLUDE_REGEX}
DEPENDS ccov-all-processing)
endif()
# Export coverage information so continuous integration tools (e.g.
# Jenkins) can consume it
add_custom_target(
ccov-all-export
COMMAND
${LLVM_COV_PATH} export `cat
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list`
-instr-profile=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.profdata
-format="text" ${EXCLUDE_REGEX} >
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/coverage.json
DEPENDS ccov-all-processing)
# Generate HTML output of all added targets for perusal
if(WIN32)
add_custom_target(
ccov-all
COMMAND
powershell -Command $$FILELIST = Get-Content
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list\; llvm-cov.exe show
$$FILELIST
-instr-profile=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.profdata
-show-line-counts-or-regions
-output-dir=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged
-format="html" ${EXCLUDE_REGEX}
DEPENDS ccov-all-processing)
else()
add_custom_target(
ccov-all
COMMAND
${LLVM_COV_PATH} show `cat
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list`
-instr-profile=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.profdata
-show-line-counts-or-regions
-output-dir=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged
-format="html" ${EXCLUDE_REGEX}
DEPENDS ccov-all-processing)
endif()
elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES
"GNU")
set(COVERAGE_INFO "${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.info")
# Nothing required for gcov
add_custom_target(ccov-all-processing COMMAND ;)
# Exclusion regex string creation
set(EXCLUDE_REGEX)
foreach(EXCLUDE_ITEM ${add_code_coverage_all_targets_EXCLUDE})
set(EXCLUDE_REGEX ${EXCLUDE_REGEX} --remove ${COVERAGE_INFO}
'${EXCLUDE_ITEM}')
endforeach()
if(EXCLUDE_REGEX)
set(EXCLUDE_COMMAND ${LCOV_PATH} ${EXCLUDE_REGEX} --output-file
${COVERAGE_INFO})
else()
set(EXCLUDE_COMMAND ;)
endif()
# Capture coverage data
if(${CMAKE_VERSION} VERSION_LESS "3.17.0")
add_custom_target(
ccov-all-capture
COMMAND ${CMAKE_COMMAND} -E remove -f ${COVERAGE_INFO}
COMMAND ${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --capture
--output-file ${COVERAGE_INFO}
COMMAND ${EXCLUDE_COMMAND}
DEPENDS ccov-preprocessing ccov-all-processing)
else()
add_custom_target(
ccov-all-capture
COMMAND ${CMAKE_COMMAND} -E rm -f ${COVERAGE_INFO}
COMMAND ${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --capture
--output-file ${COVERAGE_INFO}
COMMAND ${EXCLUDE_COMMAND}
DEPENDS ccov-preprocessing ccov-all-processing)
endif()
# Generates HTML output of all targets for perusal
add_custom_target(
ccov-all
COMMAND ${GENHTML_PATH} -o ${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged
${COVERAGE_INFO} -p ${CMAKE_SOURCE_DIR}
DEPENDS ccov-all-capture)
endif()
add_custom_command(
TARGET ccov-all
POST_BUILD
COMMAND ;
COMMENT
"Open ${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged/index.html in your browser to view the coverage report."
)
endif()
endfunction()
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env python3
# Copyright 2023 The Khronos Group Inc.
# Copyright 2023 Valve Corporation
# Copyright 2023 LunarG, Inc.
#
# SPDX-License-Identifier: Apache-2.0
import argparse
import sys
def main(argv):
parser = argparse.ArgumentParser(description='Update Loader.rc for official builds')
parser.add_argument('src')
parser.add_argument('dst')
parser.add_argument('--is_official', action='store_true')
parser.set_defaults(is_official=False)
args = parser.parse_args(argv)
with open(args.src, 'r') as src:
with open(args.dst, 'w') as dst:
for line in src:
if args.is_official:
if line.startswith('#define VER_FILE_DESCRIPTION_STR'):
dst.write(line.replace('Dev Build', '0'))
elif line.startswith('#define VER_FILE_VERSION_STR'):
dst.write(line.replace(' - Dev Build', ''))
else:
dst.write(line)
else:
dst.write(line)
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
Executable → Regular
+8 -1
View File
@@ -44,8 +44,15 @@ def main(argv):
group.add_argument('-v', '--verify', action='store_true', help='verify repo files match generator output')
args = parser.parse_args(argv)
registry = os.path.abspath(os.path.join(args.registry, 'vk.xml'))
if not os.path.isfile(registry):
registry = os.path.abspath(os.path.join(args.registry, 'Vulkan-Headers/registry/vk.xml'))
if not os.path.isfile(registry):
print(f'cannot find vk.xml in {args.registry}')
return -1
gen_cmds = [[common_codegen.repo_relative('scripts/loader_genvk.py'),
'-registry', os.path.abspath(os.path.join(args.registry, 'vk.xml')),
'-registry', registry,
'-quiet',
filename] for filename in ['vk_layer_dispatch_table.h',
'vk_loader_extensions.h',
+3 -3
View File
@@ -7,7 +7,7 @@
"sub_dir": "Vulkan-Headers",
"build_dir": "Vulkan-Headers/build",
"install_dir": "Vulkan-Headers/build/install",
"commit": "v1.3.275"
"commit": "v1.4.309"
},
{
"name": "googletest",
@@ -28,7 +28,7 @@
"build_dir": "detours",
"install_dir": "detours",
"build_step": "skip",
"commit": "v4.0.1",
"commit": "4b8c659f549b0ab21cf649377c7a84eb708f5e68",
"optional": [
"tests"
],
@@ -42,4 +42,4 @@
"googletest": "GOOGLETEST_INSTALL_DIR",
"detours": "DETOURS_INSTALL_DIR"
}
}
}
+151 -127
View File
@@ -22,10 +22,10 @@
# Author: Mark Young <marky@lunarg.com>
# Author: Mark Lobodzinski <mark@lunarg.com>
import os,re,sys
import xml.etree.ElementTree as etree
from generator import *
import re
import sys
from collections import namedtuple
from generator import *
from common_codegen import *
@@ -193,7 +193,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
OutputGenerator.beginFile(self, genOpts)
# User-supplied prefix text, if any (list of strings)
if (genOpts.prefixText):
if genOpts.prefixText:
for s in genOpts.prefixText:
write(s, file=self.outFile)
@@ -232,12 +232,18 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
if self.genOpts.filename == 'vk_loader_extensions.h':
preamble += '#pragma once\n'
preamble += '\n'
preamble += '#include <stdbool.h>\n'
preamble += '#include <vulkan/vulkan.h>\n'
preamble += '#include <vulkan/vk_layer.h>\n'
preamble += '#include "vk_layer_dispatch_table.h"\n'
preamble += '\n'
elif self.genOpts.filename == 'vk_loader_extensions.c':
preamble += '#include <stdio.h>\n'
preamble += '#include <stdlib.h>\n'
preamble += '#include <string.h>\n'
preamble += '#include "vk_loader_platform.h"\n'
preamble += '#include "loader.h"\n'
preamble += '#include "vk_loader_extensions.h"\n'
preamble += '#include <vulkan/vk_icd.h>\n'
@@ -248,6 +254,8 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
elif self.genOpts.filename == 'vk_layer_dispatch_table.h':
preamble += '#pragma once\n'
preamble += '\n'
preamble += '#include <vulkan/vulkan.h>\n'
preamble += '\n'
preamble += '#if !defined(PFN_GetPhysicalDeviceProcAddr)\n'
preamble += 'typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName);\n'
preamble += '#endif\n'
@@ -287,7 +295,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
file_data += '// clang-format on'
write(file_data, file=self.outFile);
write(file_data, file=self.outFile)
# Finish processing in superclass
OutputGenerator.endFile(self)
@@ -341,16 +349,16 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
# Retrieve the value of the len tag
def getLen(self, param):
result = None
len = param.attrib.get('len')
if len and len != 'null-terminated':
length = param.attrib.get('len')
if length and length != 'null-terminated':
# For string arrays, 'len' can look like 'count,null-terminated',
# indicating that we have a null terminated array of strings. We
# strip the null-terminated from the 'len' field and only return
# the parameter specifying the string count
if 'null-terminated' in len:
result = len.split(',')[0]
if 'null-terminated' in length:
result = length.split(',')[0]
else:
result = len
result = length
result = str(result).replace('::', '->')
return result
@@ -381,11 +389,11 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
return_type = cmdinfo.elem.find('proto/type')
if (return_type is not None and return_type.text == 'void'):
return_type = None
return_type = None
require = None
if name == 'vkGetDeviceGroupSurfacePresentModes2EXT':
require_node = self.registry.tree.find("./extensions/extension[@name='{}']/require/command[@name='{}']/..".format(extension_name, name))
require_node = self.registry.tree.find(f"./extensions/extension[@name='{extension_name}']/require/command[@name='{name}']/..")
if 'depends' in require_node.attrib:
require = require_node.attrib['depends']
@@ -396,10 +404,10 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
params = cmdinfo.elem.findall('param')
lens = set()
for param in params:
len = self.getLen(param)
if len:
lens.add(len)
paramsInfo = []
length = self.getLen(param)
if length:
lens.add(length)
for param in params:
paramInfo = self.getTypeNameTuple(param)
param_type = paramInfo[0]
@@ -466,14 +474,24 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
#
# Retrieve the type and name for a parameter
def getTypeNameTuple(self, param):
type = ''
name = ''
t = ''
n = ''
for elem in param:
if elem.tag == 'type':
type = noneStr(elem.text)
t = noneStr(elem.text)
elif elem.tag == 'name':
name = noneStr(elem.text)
return (type, name)
n = noneStr(elem.text)
return (t, n)
# Convert an XML dependency expression to a C expression, taking a callback to replace extension names
# See https://registry.khronos.org/vulkan/specs/1.4/registry.html#depends-expressions
@staticmethod
def ConvertDependencyExpression(expr, replace_func):
# '(' and ')' can pass through unchanged
expr = re.sub(',', ' || ', expr)
expr = re.sub(r'\+', ' && ', expr)
expr = re.sub(r'\w+', lambda match: replace_func(match.group()), expr)
return expr
def OutputPrototypesInHeader(self):
protos = ''
@@ -543,7 +561,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
protos += 'VKAPI_ATTR VkResult VKAPI_CALL vkDevExtError(VkDevice dev) {\n'
protos += ' struct loader_device *found_dev;\n'
protos += ' // The device going in is a trampoline device\n'
protos += ' struct loader_icd_term *icd_term = loader_get_icd_and_device(dev, &found_dev, NULL);\n'
protos += ' struct loader_icd_term *icd_term = loader_get_icd_and_device(dev, &found_dev);\n'
protos += '\n'
protos += ' if (icd_term)\n'
protos += ' loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,\n'
@@ -581,21 +599,21 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
if cur_cmd.ext_name != cur_extension_name:
if version:
table += '\n // ---- Core %s commands\n' % version.name
table += f'\n // ---- Core {version.name} commands\n'
else:
table += '\n // ---- %s extension commands\n' % cur_cmd.ext_name
table += f'\n // ---- {cur_cmd.ext_name} extension commands\n'
cur_extension_name = cur_cmd.ext_name
# Remove 'vk' from proto name
base_name = cur_cmd.name[2:]
if cur_cmd.protect is not None:
table += '#if defined(%s)\n' % cur_cmd.protect
table += f'#if defined({cur_cmd.protect})\n'
table += ' PFN_%s %s;\n' % (cur_cmd.name, base_name)
table += f' PFN_{cur_cmd.name} {base_name};\n'
if cur_cmd.protect is not None:
table += '#endif // %s\n' % cur_cmd.protect
table += f'#endif // {cur_cmd.protect}\n'
table += '} VkLayerInstanceDispatchTable;\n\n'
return table
@@ -625,21 +643,20 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
if cur_cmd.ext_name != cur_extension_name:
if version:
table += '\n // ---- Core %s commands\n' % version.name
table += f'\n // ---- Core {version.name} commands\n'
else:
table += '\n // ---- %s extension commands\n' % cur_cmd.ext_name
table += f'\n // ---- {cur_cmd.ext_name} extension commands\n'
cur_extension_name = cur_cmd.ext_name
# Remove 'vk' from proto name
base_name = cur_cmd.name[2:]
if cur_cmd.protect is not None:
table += '#if defined(%s)\n' % cur_cmd.protect
table += ' PFN_%s %s;\n' % (cur_cmd.name, base_name)
table += f'#if defined({cur_cmd.protect})\n'
table += f' PFN_{cur_cmd.name} {base_name};\n'
if cur_cmd.protect is not None:
table += '#endif // %s\n' % cur_cmd.protect
table += f'#endif // {cur_cmd.protect}\n'
table += '} VkLayerDispatchTable;\n\n'
return table
@@ -672,24 +689,24 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
for cur_cmd in commands:
version = self.getAPIVersion(cur_cmd.ext_name)
if (self.ShouldPrintInIcdDispatchTable(cur_cmd, skip_commands)):
if self.ShouldPrintInIcdDispatchTable(cur_cmd, skip_commands):
if cur_cmd.ext_name != cur_extension_name:
if version:
table += '\n // ---- Core %s commands\n' % version.name
table += f'\n // ---- Core {version.name} commands\n'
else:
table += '\n // ---- %s extension commands\n' % cur_cmd.ext_name
table += f'\n // ---- {cur_cmd.ext_name} extension commands\n'
cur_extension_name = cur_cmd.ext_name
# Remove 'vk' from proto name
base_name = cur_cmd.name[2:]
if cur_cmd.protect is not None:
table += '#if defined(%s)\n' % cur_cmd.protect
table += f'#if defined({cur_cmd.protect})\n'
table += ' PFN_%s %s;\n' % (cur_cmd.name, base_name)
table += f' PFN_{cur_cmd.name} {base_name};\n'
if cur_cmd.protect is not None:
table += '#endif // %s\n' % cur_cmd.protect
table += f'#endif // {cur_cmd.protect}\n'
table += '};\n\n'
return table
@@ -735,14 +752,14 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
required = False
for cur_cmd in commands:
version = self.getAPIVersion(cur_cmd.ext_name)
if (self.ShouldPrintInIcdDispatchTable(cur_cmd, skip_gipa_commands)):
if self.ShouldPrintInIcdDispatchTable(cur_cmd, skip_gipa_commands):
if cur_cmd.ext_name != cur_extension_name:
if version:
table += '\n // ---- Core %s\n' % version.name
table += f'\n // ---- Core {version.name}\n'
required = version.number == '1.0'
else:
table += '\n // ---- %s extension commands\n' % cur_cmd.ext_name
table += f'\n // ---- {cur_cmd.ext_name} extension commands\n'
required = False
cur_extension_name = cur_cmd.ext_name
@@ -750,7 +767,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
base_name = cur_cmd.name[2:]
if cur_cmd.protect is not None:
table += '#if defined(%s)\n' % cur_cmd.protect
table += f'#if defined({cur_cmd.protect})\n'
if required:
# The Core Vulkan code will be wrapped in a feature called VK_VERSION_#_#
@@ -759,7 +776,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
else:
table += f' LOOKUP_GIPA({base_name});\n'
if cur_cmd.protect is not None:
table += '#endif // %s\n' % cur_cmd.protect
table += f'#endif // {cur_cmd.protect}\n'
table += '\n'
table += '#undef LOOKUP_REQUIRED_GIPA\n'
@@ -781,7 +798,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
ext.type == 'device' or ext.num_commands == 0):
continue
union += ' uint8_t %s;\n' % ext.name[3:].lower()
union += f' uint8_t {ext.name[3:].lower()};\n'
union += '};\n\n'
return union
@@ -800,16 +817,22 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
mod_string = new_terminator.replace("VKAPI_CALL vk", "VKAPI_CALL terminator_")
if cur_cmd.name in PRE_INSTANCE_FUNCTIONS:
pre_instance_basic_version = mod_string
mod_string = mod_string.replace("terminator_", "terminator_pre_instance_")
mod_string = mod_string.replace(cur_cmd.name[2:] + '(\n', cur_cmd.name[2:] + '(\n const Vk' + cur_cmd.name[2:] + 'Chain* chain,\n')
if (cur_cmd.protect is not None):
terminators += '#if defined(%s)\n' % cur_cmd.protect
if cur_cmd.protect is not None:
terminators += f'#if defined({cur_cmd.protect})\n'
if cur_cmd.name in PRE_INSTANCE_FUNCTIONS:
terminators += pre_instance_basic_version
terminators += '\n'
terminators += mod_string
terminators += '\n'
if (cur_cmd.protect is not None):
terminators += '#endif // %s\n' % cur_cmd.protect
if cur_cmd.protect is not None:
terminators += f'#endif // {cur_cmd.protect}\n'
terminators += '\n'
return terminators
@@ -874,9 +897,9 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
if ((cur_type == 'instance' and is_inst_handle_type) or (cur_type == 'device' and not is_inst_handle_type)):
if cur_cmd.ext_name != cur_extension_name:
if version:
tables += '\n // ---- Core %s commands\n' % version.name
tables += f'\n // ---- Core {version.name} commands\n'
else:
tables += '\n // ---- %s extension commands\n' % cur_cmd.ext_name
tables += f'\n // ---- {cur_cmd.ext_name} extension commands\n'
cur_extension_name = cur_cmd.ext_name
# Remove 'vk' from proto name
@@ -890,7 +913,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
continue
if cur_cmd.protect is not None:
tables += '#if defined(%s)\n' % cur_cmd.protect
tables += f'#if defined({cur_cmd.protect})\n'
# If we're looking for the proc we are passing in, just point the table to it. This fixes the issue where
# a layer overrides the function name for the loader.
@@ -898,18 +921,18 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
if base_name == 'GetDeviceProcAddr':
tables += ' table->GetDeviceProcAddr = gdpa;\n'
elif cur_cmd.ext_type == 'instance':
tables += ' table->%s = (PFN_%s)gipa(inst, "%s");\n' % (base_name, cur_cmd.name, cur_cmd.name)
tables += f' table->{base_name} = (PFN_{cur_cmd.name})gipa(inst, "{cur_cmd.name}");\n'
else:
tables += ' table->%s = (PFN_%s)gdpa(dev, "%s");\n' % (base_name, cur_cmd.name, cur_cmd.name)
tables += f' table->{base_name} = (PFN_{cur_cmd.name})gdpa(dev, "{cur_cmd.name}");\n'
elif (x < 1 and base_name == 'GetDeviceProcAddr'):
tables += ' table->GetDeviceProcAddr = gpa;\n'
elif (x > 1 and base_name == 'GetInstanceProcAddr'):
tables += ' table->GetInstanceProcAddr = gpa;\n'
else:
tables += ' table->%s = (PFN_%s)gpa(%s, "%s");\n' % (base_name, cur_cmd.name, gpa_param, cur_cmd.name)
tables += f' table->{base_name} = (PFN_{cur_cmd.name})gpa({gpa_param}, "{cur_cmd.name}");\n'
if cur_cmd.protect is not None:
tables += '#endif // %s\n' % cur_cmd.protect
tables += f'#endif // {cur_cmd.protect}\n'
tables += '}\n\n'
return tables
@@ -967,12 +990,12 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
if ((cur_type == 'instance' and is_inst_handle_type) or (cur_type == 'device' and not is_inst_handle_type)):
if cur_cmd.ext_name != cur_extension_name:
if version:
tables += '\n // ---- Core %s commands\n' % version.name
tables += f'\n // ---- Core {version.name} commands\n'
if cur_type == 'device':
version_check = f' if (dev->should_ignore_device_commands_from_newer_version && api_version < {version.constant}) return NULL;\n'
else:
tables += '\n // ---- %s extension commands\n' % cur_cmd.ext_name
tables += f'\n // ---- {cur_cmd.ext_name} extension commands\n'
version_check = ''
cur_extension_name = cur_cmd.ext_name
@@ -986,7 +1009,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
continue
if cur_cmd.protect is not None:
tables += '#if defined(%s)\n' % cur_cmd.protect
tables += f'#if defined({cur_cmd.protect})\n'
tables += f' if (!strcmp(name, "{base_name}")) '
if cur_cmd.name in DEVICE_CMDS_MUST_USE_TRAMP:
@@ -1002,7 +1025,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
tables += f'return (void *)table->{base_name};\n'
if cur_cmd.protect is not None:
tables += '#endif // %s\n' % cur_cmd.protect
tables += f'#endif // {cur_cmd.protect}\n'
tables += '\n'
tables += ' *found_name = false;\n'
@@ -1013,7 +1036,6 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
#
# Create the appropriate trampoline (and possibly terminator) functions
def CreateTrampTermFuncs(self):
entries = []
funcs = ''
cur_extension_name = ''
@@ -1055,13 +1077,13 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
version = self.getAPIVersion(ext_cmd.ext_name)
if ext_cmd.ext_name != cur_extension_name:
if version:
funcs += '\n// ---- Core %s trampoline/terminators\n\n' % version.name
funcs += f'\n// ---- Core {version.name} trampoline/terminators\n\n'
else:
funcs += '\n// ---- %s extension trampoline/terminators\n\n' % ext_cmd.ext_name
funcs += f'\n// ---- {ext_cmd.ext_name} extension trampoline/terminators\n\n'
cur_extension_name = ext_cmd.ext_name
if ext_cmd.protect is not None:
funcs += '#if defined(%s)\n' % ext_cmd.protect
funcs += f'#if defined({ext_cmd.protect})\n'
func_header = ext_cmd.cdecl.replace(";", " {\n")
tramp_header = func_header.replace("VKAPI_CALL vk", "VKAPI_CALL ")
@@ -1088,14 +1110,14 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
requires_terminator = 1
always_use_param_name = False
surface_type_to_replace = 'VkSurfaceKHR'
surface_name_replacement = 'icd_surface->real_icd_surfaces[icd_index]'
surface_name_replacement = 'icd_term->surface_list[icd_surface->surface_index]'
if param.type == 'VkPhysicalDeviceSurfaceInfo2KHR':
has_surface = 1
surface_var_name = param.name + '->surface'
requires_terminator = 1
update_structure_surface = 1
update_structure_string = ' VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;\n'
update_structure_string += ' info_copy.surface = icd_surface->real_icd_surfaces[icd_index];\n'
update_structure_string += ' info_copy.surface = icd_term->surface_list[icd_surface->surface_index];\n'
always_use_param_name = False
surface_type_to_replace = 'VkPhysicalDeviceSurfaceInfo2KHR'
surface_name_replacement = '&info_copy'
@@ -1109,7 +1131,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
requires_terminator = 1
instance_var_name = param.name
if (ext_cmd.return_type is not None):
if ext_cmd.return_type is not None:
return_prefix += 'return '
has_return_type = True
@@ -1125,20 +1147,20 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
if ext_cmd.handle_type == 'VkPhysicalDevice':
funcs += ' const VkLayerInstanceDispatchTable *disp;\n'
funcs += ' VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(%s);\n' % (phys_dev_var_name)
funcs += f' VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device({phys_dev_var_name});\n'
funcs += ' if (VK_NULL_HANDLE == unwrapped_phys_dev) {\n'
funcs += ' loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n'
funcs += ' "%s: Invalid %s "\n' % (ext_cmd.name, phys_dev_var_name)
funcs += ' "[VUID-%s-%s-parameter]");\n' % (ext_cmd.name, phys_dev_var_name)
funcs += f' "{ext_cmd.name}: Invalid {phys_dev_var_name} "\n'
funcs += f' "[VUID-{ext_cmd.name}-{phys_dev_var_name}-parameter]");\n'
funcs += ' abort(); /* Intentionally fail so user can correct issue. */\n'
funcs += ' }\n'
funcs += ' disp = loader_get_instance_layer_dispatch(%s);\n' % (phys_dev_var_name)
funcs += f' disp = loader_get_instance_layer_dispatch({phys_dev_var_name});\n'
elif ext_cmd.handle_type == 'VkInstance':
funcs += ' struct loader_instance *inst = loader_get_instance(%s);\n' % (instance_var_name)
funcs += f' struct loader_instance *inst = loader_get_instance({instance_var_name});\n'
funcs += ' if (NULL == inst) {\n'
funcs += ' loader_log(\n'
funcs += ' NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n'
funcs += ' "%s: Invalid instance [VUID-%s-%s-parameter]");\n' % (ext_cmd.name, ext_cmd.name, instance_var_name)
funcs += f' "{ext_cmd.name}: Invalid instance [VUID-{ext_cmd.name}-{instance_var_name}-parameter]");\n'
funcs += ' abort(); /* Intentionally fail so user can correct issue. */\n'
funcs += ' }\n'
funcs += '#error("Not implemented. Likely needs to be manually generated!");\n'
@@ -1148,8 +1170,8 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
funcs += ');\n'
funcs += ' if (NULL == disp) {\n'
funcs += ' loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n'
funcs += ' "%s: Invalid %s "\n' % (ext_cmd.name, ext_cmd.params[0].name)
funcs += ' "[VUID-%s-%s-parameter]");\n' % (ext_cmd.name, ext_cmd.params[0].name)
funcs += f' "{ext_cmd.name}: Invalid {ext_cmd.params[0].name} "\n'
funcs += f' "[VUID-{ext_cmd.name}-{ext_cmd.params[0].name}-parameter]");\n'
funcs += ' abort(); /* Intentionally fail so user can correct issue. */\n'
funcs += ' }\n'
@@ -1219,9 +1241,9 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
if param.type == 'VkPhysicalDevice':
funcs += 'unwrapped_phys_dev'
elif ('DebugMarkerSetObject' in ext_cmd.name or 'SetDebugUtilsObject' in ext_cmd.name) and param.name == 'pNameInfo':
funcs += '&local_name_info'
funcs += '&local_name_info'
elif ('DebugMarkerSetObject' in ext_cmd.name or 'SetDebugUtilsObject' in ext_cmd.name) and param.name == 'pTagInfo':
funcs += '&local_tag_info'
funcs += '&local_tag_info'
else:
funcs += param.name
@@ -1236,7 +1258,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
funcs += term_header
if ext_cmd.handle_type == 'VkPhysicalDevice':
funcs += ' struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)%s;\n' % (phys_dev_var_name)
funcs += f' struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *){phys_dev_var_name};\n'
funcs += ' struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;\n'
funcs += ' if (NULL == icd_term->dispatch.'
funcs += base_name
@@ -1256,9 +1278,11 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
funcs += ' }\n'
if has_surface == 1:
funcs += ' VkIcdSurface *icd_surface = (VkIcdSurface *)(%s);\n' % (surface_var_name)
funcs += ' uint8_t icd_index = phys_dev_term->icd_index;\n'
funcs += ' if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)icd_surface->real_icd_surfaces[icd_index]) {\n'
funcs += ' VkIcdSurface *icd_surface = NULL;\n'
funcs += f' if (NULL != {surface_var_name}) {{\n'
funcs += f' icd_surface = (VkIcdSurface *)(uintptr_t)({surface_var_name});\n'
funcs += ' }\n'
funcs += ' if (NULL != icd_surface && NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && icd_term->surface_list[icd_surface->surface_index]) {\n'
# If there's a structure with a surface, we need to update its internals with the correct surface for the ICD
if update_structure_surface == 1:
@@ -1307,11 +1331,11 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
elif ext_cmd.handle_type == 'VkInstance':
funcs += ' struct loader_instance *inst = loader_get_instance(%s);\n' % (instance_var_name)
funcs += f' struct loader_instance *inst = loader_get_instance({instance_var_name});\n'
funcs += ' if (NULL == inst) {\n'
funcs += ' loader_log(\n'
funcs += ' NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n'
funcs += ' "%s: Invalid instance [VUID-%s-%s-parameter]");\n' % (ext_cmd.name, ext_cmd.name, instance_var_name)
funcs += f' "{ext_cmd.name}: Invalid instance [VUID-{ext_cmd.name}-{instance_var_name}-parameter]");\n'
funcs += ' abort(); /* Intentionally fail so user can correct issue. */\n'
funcs += ' }\n'
funcs += '#error("Not implemented. Likely needs to be manually generated!");\n'
@@ -1325,10 +1349,9 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
phys_dev_check = 'VK_OBJECT_TYPE_PHYSICAL_DEVICE' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT'
surf_check = 'VK_OBJECT_TYPE_SURFACE_KHR' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT'
inst_check = 'VK_OBJECT_TYPE_INSTANCE' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT'
funcs += ' uint32_t icd_index = 0;\n'
funcs += ' struct loader_device *dev;\n'
funcs += f' struct loader_icd_term *icd_term = loader_get_icd_and_device({ ext_cmd.params[0].name}, &dev, &icd_index);\n'
funcs += f' if (NULL == icd_term || NULL == dev) {{\n'
funcs += f' struct loader_icd_term *icd_term = loader_get_icd_and_device({ ext_cmd.params[0].name}, &dev);\n'
funcs += ' if (NULL == icd_term || NULL == dev) {\n'
funcs += f' loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "{ext_cmd.name[2:]}: Invalid device handle");\n'
funcs += ' abort(); /* Intentionally fail so user can correct issue. */\n'
funcs += ' }\n'
@@ -1342,8 +1365,9 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
funcs += f' }} else if ({debug_struct_name}->objectType == {surf_check}) {{\n'
funcs += ' if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) {\n'
funcs += f' VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t){debug_struct_name}->{member_name};\n'
funcs += ' if (NULL != icd_surface->real_icd_surfaces) {\n'
funcs += f' {local_struct}.{member_name} = (uint64_t)icd_surface->real_icd_surfaces[icd_index];\n'
funcs += ' if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR)\n'
funcs += ' && icd_term->surface_list.list[icd_surface->surface_index]) {\n'
funcs += f' {local_struct}.{member_name} = (uint64_t)icd_term->surface_list.list[icd_surface->surface_index];\n'
funcs += ' }\n'
funcs += ' }\n'
funcs += ' // If this is an instance we have to replace it with the proper one for the next call.\n'
@@ -1356,7 +1380,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
dispatch = 'dev->loader_dispatch.'
else:
funcs += f' struct loader_dev_dispatch_table *dispatch_table = loader_get_dev_dispatch({ext_cmd.params[0].name});\n'
funcs += f' if (NULL == dispatch_table) {{\n'
funcs += ' if (NULL == dispatch_table) {\n'
funcs += f' loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "{ext_cmd.ext_name}: Invalid device handle");\n'
funcs += ' abort(); /* Intentionally fail so user can correct issue. */\n'
funcs += ' }\n'
@@ -1375,7 +1399,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
if param.type == 'VkPhysicalDevice':
funcs += 'phys_dev_term->phys_dev'
elif param.type == 'VkSurfaceKHR':
funcs += 'icd_surface->real_icd_surfaces[icd_index]'
funcs += 'icd_term->surface_list[icd_surface->surface_index]'
elif ('DebugMarkerSetObject' in ext_cmd.name or 'SetDebugUtilsObject' in ext_cmd.name) and param.name == 'pNameInfo':
funcs += '&local_name_info'
elif ('DebugMarkerSetObject' in ext_cmd.name or 'SetDebugUtilsObject' in ext_cmd.name) and param.name == 'pTagInfo':
@@ -1398,8 +1422,8 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
funcs += ');\n'
funcs += ' if (NULL == disp) {\n'
funcs += ' loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,\n'
funcs += ' "%s: Invalid %s "\n' % (ext_cmd.name, ext_cmd.params[0].name)
funcs += ' "[VUID-%s-%s-parameter]");\n' % (ext_cmd.name, ext_cmd.params[0].name)
funcs += f' "{ext_cmd.name}: Invalid {ext_cmd.params[0].name} "\n'
funcs += f' "[VUID-{ext_cmd.name}-{ext_cmd.params[0].name}-parameter]");\n'
funcs += ' abort(); /* Intentionally fail so user can correct issue. */\n'
funcs += ' }\n'
@@ -1425,7 +1449,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
funcs += '}\n\n'
if ext_cmd.protect is not None:
funcs += '#endif // %s\n' % ext_cmd.protect
funcs += f'#endif // {ext_cmd.protect}\n'
return funcs
@@ -1433,7 +1457,6 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
#
# Create a function for the extension GPA call
def InstExtensionGPA(self):
entries = []
gpa_func = ''
cur_extension_name = ''
@@ -1449,32 +1472,32 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
continue
if cur_cmd.ext_name != cur_extension_name:
gpa_func += '\n // ---- %s extension commands\n' % cur_cmd.ext_name
gpa_func += f'\n // ---- {cur_cmd.ext_name} extension commands\n'
cur_extension_name = cur_cmd.ext_name
if cur_cmd.protect is not None:
gpa_func += '#if defined(%s)\n' % cur_cmd.protect
gpa_func += f'#if defined({cur_cmd.protect})\n'
#base_name = cur_cmd.name[2:]
base_name = SHARED_ALIASES[cur_cmd.name] if cur_cmd.name in SHARED_ALIASES else cur_cmd.name[2:]
if (cur_cmd.ext_type == 'instance'):
gpa_func += ' if (!strcmp("%s", name)) {\n' % (cur_cmd.name)
if cur_cmd.ext_type == 'instance':
gpa_func += f' if (!strcmp("{cur_cmd.name}", name)) {{\n'
gpa_func += ' *addr = (ptr_instance->enabled_known_extensions.'
gpa_func += cur_cmd.ext_name[3:].lower()
gpa_func += ' == 1)\n'
gpa_func += ' ? (void *)%s\n' % (base_name)
gpa_func += f' ? (void *){base_name}\n'
gpa_func += ' : NULL;\n'
gpa_func += ' return true;\n'
gpa_func += ' }\n'
else:
gpa_func += ' if (!strcmp("%s", name)) {\n' % (cur_cmd.name)
gpa_func += ' *addr = (void *)%s;\n' % (base_name)
gpa_func += f' if (!strcmp("{cur_cmd.name}", name)) {{\n'
gpa_func += f' *addr = (void *){base_name};\n'
gpa_func += ' return true;\n'
gpa_func += ' }\n'
if cur_cmd.protect is not None:
gpa_func += '#endif // %s\n' % cur_cmd.protect
gpa_func += f'#endif // {cur_cmd.protect}\n'
gpa_func += ' return false;\n'
gpa_func += '}\n\n'
@@ -1500,11 +1523,11 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
continue
if ext.name != cur_extension_name:
create_func += '\n // ---- %s extension commands\n' % ext.name
create_func += f'\n // ---- {ext.name} extension commands\n'
cur_extension_name = ext.name
if ext.protect is not None:
create_func += '#if defined(%s)\n' % ext.protect
create_func += f'#if defined({ext.protect})\n'
if count == 0:
create_func += ' if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], '
else:
@@ -1516,7 +1539,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
create_func += ' = 1;\n'
if ext.protect is not None:
create_func += '#endif // %s\n' % ext.protect
create_func += f'#endif // {ext.protect}\n'
count += 1
create_func += ' }\n'
@@ -1551,21 +1574,22 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
last_protect = ext_cmd.protect
if ext_cmd.protect is not None:
term_func += f'#if defined({ext_cmd.protect})\n'
if (last_ext != ext_cmd.ext_name):
if last_ext != ext_cmd.ext_name:
term_func += f' // ---- {ext_cmd.ext_name} extension commands\n'
last_ext = ext_cmd.ext_name
term_func += f' if (!strcmp(name, "{ext_cmd.name[2:]}")) {{\n'
term_func += f' *found_name = true;\n'
term_func += ' *found_name = true;\n'
if ext_cmd.require:
term_func += f' return dev->driver_extensions.{ext_cmd.ext_name[3:].lower()}_enabled && dev->driver_extensions.{ext_cmd.require[3:].lower()}_enabled ?\n'
dep_expr = self.ConvertDependencyExpression(ext_cmd.require, lambda ext_name: f'dev->driver_extensions.{ext_name[3:].lower()}_enabled')
term_func += f' return (dev->driver_extensions.{ext_cmd.ext_name[3:].lower()}_enabled && ({dep_expr})) ?\n'
else:
term_func += f' return dev->driver_extensions.{ext_cmd.ext_name[3:].lower()}_enabled ?\n'
term_func += f' (PFN_vkVoidFunction)terminator_{(ext_cmd.name[2:])} : NULL;\n'
term_func += f' }}\n'
term_func += ' }\n'
if last_protect is not None:
term_func += '#endif // %s\n' % last_protect
term_func += f'#endif // {last_protect}\n'
term_func += ' return NULL;\n'
term_func += '}\n\n'
@@ -1591,14 +1615,14 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
last_protect = ext_cmd.protect
if ext_cmd.protect is not None:
term_func += f'#if defined({ext_cmd.protect})\n'
if (last_ext != ext_cmd.ext_name):
if last_ext != ext_cmd.ext_name:
term_func += f' // ---- {ext_cmd.ext_name} extension commands\n'
last_ext = ext_cmd.ext_name
term_func += f' PFN_{ext_cmd.name} {ext_cmd.name[2:]};\n'
if last_protect is not None:
term_func += '#endif // %s\n' % last_protect
term_func += f'#endif // {last_protect}\n'
term_func += '};\n\n'
@@ -1619,14 +1643,14 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
last_protect = ext_cmd.protect
if ext_cmd.protect is not None:
tramp_protos += f'#if defined({ext_cmd.protect})\n'
if (last_ext != ext_cmd.ext_name):
if last_ext != ext_cmd.ext_name:
tramp_protos += f' // ---- {ext_cmd.ext_name} extension commands\n'
last_ext = ext_cmd.ext_name
tramp_protos += f'{ext_cmd.cdecl.replace("VKAPI_CALL vk", "VKAPI_CALL ")}\n'
if last_protect is not None:
tramp_protos += '#endif // %s\n' % last_protect
tramp_protos += f'#endif // {last_protect}\n'
tramp_protos += '\n'
return tramp_protos
@@ -1652,20 +1676,21 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
last_protect = ext_cmd.protect
if ext_cmd.protect is not None:
term_func += f'#if defined({ext_cmd.protect})\n'
if (last_ext != ext_cmd.ext_name):
if last_ext != ext_cmd.ext_name:
term_func += f' // ---- {ext_cmd.ext_name} extension commands\n'
last_ext = ext_cmd.ext_name
if ext_cmd.require:
term_func += f' if (dev->driver_extensions.{ext_cmd.ext_name[3:].lower()}_enabled && dev->driver_extensions.{ext_cmd.require[3:].lower()}_enabled)\n'
dep_expr = self.ConvertDependencyExpression(ext_cmd.require, lambda ext_name: f'dev->driver_extensions.{ext_name[3:].lower()}_enabled')
term_func += f' if (dev->driver_extensions.{ext_cmd.ext_name[3:].lower()}_enabled && ({dep_expr}))\n'
term_func += f' dispatch->{ext_cmd.name[2:]} = (PFN_{(ext_cmd.name)})gpda(dev->icd_device, "{(ext_cmd.name)}");\n'
else:
term_func += f' if (dev->driver_extensions.{ext_cmd.ext_name[3:].lower()}_enabled)\n'
term_func += f' dispatch->{ext_cmd.name[2:]} = (PFN_{(ext_cmd.name)})gpda(dev->icd_device, "{(ext_cmd.name)}");\n'
if last_protect is not None:
term_func += '#endif // %s\n' % last_protect
term_func += f'#endif // {last_protect}\n'
term_func += '}\n\n'
@@ -1695,9 +1720,9 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
if cur_cmd.handle_type == 'VkInstance' or cur_cmd.handle_type == 'VkPhysicalDevice':
if cur_cmd.ext_name != cur_extension_name:
if version:
table += '\n // ---- Core %s commands\n' % version.name
table += f'\n // ---- Core {version.name} commands\n'
else:
table += '\n // ---- %s extension commands\n' % cur_cmd.ext_name
table += f'\n // ---- {cur_cmd.ext_name} extension commands\n'
cur_extension_name = cur_cmd.ext_name
# Remove 'vk' from proto name
@@ -1711,15 +1736,15 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
continue
if cur_cmd.protect is not None:
table += '#if defined(%s)\n' % cur_cmd.protect
table += f'#if defined({cur_cmd.protect})\n'
if base_name == 'GetInstanceProcAddr':
table += ' .%s = %s,\n' % (base_name, cur_cmd.name)
table += f' .{base_name} = {cur_cmd.name},\n'
else:
table += ' .%s = terminator_%s,\n' % (base_name, aliased_name)
table += f' .{base_name} = terminator_{aliased_name},\n'
if cur_cmd.protect is not None:
table += '#endif // %s\n' % cur_cmd.protect
table += f'#endif // {cur_cmd.protect}\n'
table += '};\n\n'
return table
@@ -1740,12 +1765,11 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
continue
if ext.protect is not None:
table += '#if defined(%s)\n' % ext.protect
table += f'#if defined({ext.protect})\n'
table += ' '
table += ext.define + ',\n'
if ext.protect is not None:
table += '#endif // %s\n' % ext.protect
table += f'#endif // {ext.protect}\n'
table += ' NULL };\n'
return table
+47 -13
View File
@@ -25,18 +25,20 @@ import sys
import os.path
from os.path import exists
import re
import subprocess
import traceback
# Where to write the "gen_defines.asm" file
destination_file = sys.argv[1]
# The location the build system puts the intermediate asm file which depends on the compiler
source_asm_file = sys.argv[2]
# Whether we are using "MASM" or "GAS" for the assembler
# Whether we are using "MASM", "MARMASM" or "GAS" for the assembler
assembler_type = sys.argv[3]
# Whether we are using gcc, clang, or msvc
compiler = sys.argv[4]
# taken from CMAKE_SYSTEM_PROCESSOR - x86_64, aarch64, or x86
# Only used with GAS - MASM doesn't need this, as it has its own way to determine x86 vs x64
# taken from CMAKE_SYSTEM_PROCESSOR - x86_64, aarch64|arm64, x86, aarch32|armhf
# Only used with GAS/MARMASM - MASM doesn't need this, as it has its own way to determine x86 vs x64
arch = sys.argv[5]
POSIX_COMPILERS = ["GNU", "Clang", "AppleClang"]
@@ -57,23 +59,47 @@ defines = ["VULKAN_LOADER_ERROR_BIT",
"DISPATCH_OFFSET_ICD_TERM",
"EXT_OFFSET_DEVICE_DISPATCH" ]
try:
with open(source_asm_file, 'r') as f:
asm_intermediate_file = f.read()
except IOError:
print("Could not open assembler file:", source_asm_file)
sys.exit(1)
if os.path.splitext(source_asm_file)[1] == ".a":
try:
ar_path = sys.argv[6]
asm_archive_member = sys.argv[7]
subprocess_result = subprocess.Popen([ar_path, "p", source_asm_file, asm_archive_member], stdout=subprocess.PIPE)
asm_intermediate_file = subprocess_result.stdout.read().decode("utf-8")
except IOError:
print("Could not open assembler archive file:", source_asm_file)
traceback.print_exc()
sys.exit(1)
else:
try:
with open(source_asm_file, 'r') as f:
asm_intermediate_file = f.read()
except IOError:
print("Could not open assembler file:", source_asm_file)
sys.exit(1)
with open(destination_file, "w", encoding="utf-8") as dest:
# special case vulkan error bit due to it not appearing in the asm - its defined in the header as 8 so it shouldn't change
if assembler_type == "MASM":
# special case vulkan error bit due to it not appearing in the asm - its defined in the header as 8 so it shouldn't change
dest.write("VULKAN_LOADER_ERROR_BIT equ 8;\n")
elif assembler_type == 'MARMASM':
dest.write(' AREA loader_structs_details, DATA,READONLY\n')
if arch == "aarch64" or arch == "arm64":
dest.write("AARCH_64 EQU 1\n")
elif arch in ["aarch32", "armhf", "arm"]:
dest.write("AARCH_64 EQU 0\n")
else:
print('The parameter "arch" has value of ', arch, ' which is not recognized')
dest.write("VULKAN_LOADER_ERROR_BIT EQU 8\n")
elif assembler_type == "GAS":
# let the assembler know which platform to use
if arch == "x86_64":
dest.write(".set X86_64, 1\n")
elif arch == "aarch64" or arch == "arm64":
dest.write(".set AARCH_64, 1\n")
elif arch in ["aarch32", "armhf", "arm"]:
dest.write(".set AARCH_64, 0\n")
else:
print('The parameter "arch" has value of ', arch, ' which is not recognized')
# Nothing to write in the x86 case
for d in defines:
@@ -81,21 +107,29 @@ with open(destination_file, "w", encoding="utf-8") as dest:
if compiler == "MSVC":
if d == "VULKAN_LOADER_ERROR_BIT":
continue # skip due to special case
match = re.search(d + " DD [ ]*([0-9a-f]+)H", asm_intermediate_file)
if 'arm' in arch.lower():
match = re.search('\\|'+ d + '\\| DCD[\t ]*0x([0-9a-f]+)', asm_intermediate_file)
else:
match = re.search(d + " DD [ ]*([0-9a-f]+)H", asm_intermediate_file)
elif compiler in POSIX_COMPILERS:
match = re.search(d + " = ([0-9]+)", asm_intermediate_file)
if match:
if len(match.groups()) > 0:
if compiler == "MSVC":
value = str(int(match.group(1), 16))
elif compiler in POSIX_COMPILERS:
value = match.group(1)
if assembler_type == "MASM":
# MASM uses hex values, decode them here
if assembler_type == "MASM":
dest.write(d + " equ " + value +";\n")
elif assembler_type == 'MARMASM':
dest.write(d + ' EQU ' + value +'\n')
elif assembler_type == "GAS":
dest.write(".set " + d + ", " + value + "\n")
else:
print("Couldn't find ", d)
sys.exit(1)
if assembler_type == 'MARMASM':
dest.write(" END\n")
+1 -1
View File
@@ -32,7 +32,7 @@ include $(MKFILES_ROOT)/qtargets.mk
CCFLAGS += -DVK_USE_PLATFORM_SCREEN_QNX=1 -DVK_ENABLE_BETA_EXTENSIONS
CCFLAGS += -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers
CCFLAGS += -Wno-stringop-truncation
CCFLAGS += -fno-strict-aliasing -Wno-stringop-truncation
CCFLAGS += -Wno-stringop-overflow -fvisibility=hidden
CCFLAGS += -Wpointer-arith -fPIC
Executable → Regular
+16 -6
View File
@@ -295,7 +295,7 @@ def run_cmake_command(cmake_cmd):
# NOTE: Because CMake is an exectuable that runs executables
# stdout/stderr are mixed together. So this combines the outputs
# and prints them properly in case there is a non-zero exit code.
result = subprocess.run(cmake_cmd,
result = subprocess.run(cmake_cmd,
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT,
text = True
@@ -415,8 +415,15 @@ class GoodRepo(object):
if VERBOSE:
print('Checking out {n} in {d}'.format(n=self.name, d=self.repo_dir))
if self._args.do_clean_repo:
if os.path.exists(os.path.join(self.repo_dir, '.git')):
url_changed = command_output(['git', 'config', '--get', 'remote.origin.url'], self.repo_dir).strip() != self.url
else:
url_changed = False
if self._args.do_clean_repo or url_changed:
if os.path.isdir(self.repo_dir):
if VERBOSE:
print('Clearing directory {d}'.format(d=self.repo_dir))
shutil.rmtree(self.repo_dir, onerror = on_rm_error)
if not os.path.exists(os.path.join(self.repo_dir, '.git')):
self.Clone()
@@ -503,11 +510,14 @@ class GoodRepo(object):
# Use the CMake -A option to select the platform architecture
# without needing a Visual Studio generator.
if platform.system() == 'Windows' and self._args.generator != "Ninja":
cmake_cmd.append('-A')
if self._args.arch.lower() == '64' or self._args.arch == 'x64' or self._args.arch == 'win64':
cmake_cmd.append('-A')
cmake_cmd.append('x64')
elif self._args.arch == 'arm64':
cmake_cmd.append('arm64')
elif self._args.arch == 'arm':
cmake_cmd.append('arm')
else:
cmake_cmd.append('-A')
cmake_cmd.append('Win32')
# Apply a generator, if one is specified. This can be used to supply
@@ -620,7 +630,7 @@ def CreateHelper(args, repos, filename):
if repo.api is not None and repo.api != args.api:
continue
if install_names and repo.name in install_names and repo.on_build_platform:
helper_file.write('set({var} "{dir}" CACHE STRING "" FORCE)\n'
helper_file.write('set({var} "{dir}" CACHE STRING "")\n'
.format(
var=install_names[repo.name],
dir=escape(repo.install_dir)))
@@ -683,7 +693,7 @@ def main():
parser.add_argument(
'--arch',
dest='arch',
choices=['32', '64', 'x86', 'x64', 'win32', 'win64'],
choices=['32', '64', 'x86', 'x64', 'win32', 'win64', 'arm', 'arm64'],
type=str.lower,
help="Set build files architecture (Visual Studio Generator Only)",
default='64')
+18 -18
View File
@@ -23,16 +23,10 @@ set(CMAKE_CXX_EXTENSIONS OFF)
# Make sure tests uses the dynamic runtime instead
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
# For MSVC/Windows, replace /GR with an empty string, this prevents warnings of /GR being overriden by /GR-
# Newer CMake versions (3.20) have better solutions for this through policy - using the old
# way while waiting for when updating can occur
string(REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
if (IS_DIRECTORY "${GOOGLETEST_INSTALL_DIR}/googletest")
set(BUILD_GTEST ON)
set(BUILD_GMOCK OFF)
set(gtest_force_shared_crt ON)
set(BUILD_SHARED_LIBS ON)
set(INSTALL_GTEST OFF)
add_subdirectory("${GOOGLETEST_INSTALL_DIR}" ${CMAKE_CURRENT_BINARY_DIR}/gtest)
else()
@@ -95,6 +89,14 @@ add_executable(
target_link_libraries(test_regression PUBLIC testing_dependencies)
target_compile_definitions(test_regression PUBLIC VK_NO_PROTOTYPES)
add_executable(
test_fuzzing
loader_testing_main.cpp
loader_fuzz_tests.cpp
)
target_link_libraries(test_fuzzing PUBLIC testing_dependencies vulkan)
target_include_directories(test_fuzzing PUBLIC ${CMAKE_SOURCE_DIR}/loader ${CMAKE_SOURCE_DIR}/loader/generated)
# Threading tests live in separate executabe just for threading tests as it'll need support
# in the test harness to enable in CI, as thread sanitizer doesn't work with address sanitizer enabled.
add_executable(
@@ -110,19 +112,10 @@ if (ENABLE_LIVE_VERIFICATION_TESTS)
endif()
if(WIN32)
# Copy loader and googletest (gtest) libs to test dir so the test executable can find them.
add_custom_command(TARGET test_regression POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:gtest> $<TARGET_FILE_DIR:test_regression>)
# Copy the loader shared lib (if built) to the test application directory so the test app finds it.
# Copy vulkan-1.dll to the test_fuzzing build directory so that the test_fuzzing exe can find it.
if(TARGET vulkan)
add_custom_command(TARGET test_regression POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:vulkan> $<TARGET_FILE_DIR:test_regression>)
endif()
# Copy the gtest shared lib (if built) to the live verification tests directory so the tests finds it.
if(ENABLE_LIVE_VERIFICATION_TESTS)
add_custom_command(TARGET test_regression POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:gtest> $<TARGET_FILE_DIR:dynamic_rendering_get_proc_addr>)
add_custom_command(TARGET test_fuzzing POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:vulkan> $<TARGET_FILE_DIR:test_fuzzing>)
endif()
endif()
@@ -137,8 +130,10 @@ endif()
# must happen after the dll's get copied over
if(NOT CMAKE_CROSSCOMPILING)
gtest_discover_tests(test_regression PROPERTIES DISCOVERY_TIMEOUT 100)
gtest_discover_tests(test_fuzzing PROPERTIES DISCOVERY_TIMEOUT 100)
else()
gtest_add_tests(TARGET test_regression)
gtest_add_tests(TARGET test_fuzzing)
endif()
# When APPLE_STATIC_LOADER is ON installation is disabled
@@ -169,3 +164,8 @@ add_test(NAME integration.find_package
# Installing comes before testing
set_tests_properties(integration.find_package PROPERTIES DEPENDS integration.install)
if (CODE_COVERAGE)
target_code_coverage(test_regression AUTO ALL )
target_code_coverage(test_fuzzing AUTO ALL )
endif()
+6 -15
View File
@@ -46,8 +46,10 @@ if (UNIX)
endif()
if (MSVC)
# silence hidden class member warnings in test framework
# 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()
function(AddSharedLibrary LIBRARY_NAME)
@@ -74,27 +76,16 @@ add_subdirectory(layer)
#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.h.in using framework_config_temp.h.in as a source
# setup framework_config_$<CONFIG> using framework_config_temp.h.in as a source
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/framework_config_$<CONFIG>.h" INPUT "${CMAKE_CURRENT_BINARY_DIR}/framework_config_temp.h.in")
# copy framework_config_$<CONFIG> to the loader build directory
add_custom_command(
PRE_BUILD
COMMAND ${CMAKE_COMMAND} "-E" "copy_if_different" "${CMAKE_CURRENT_BINARY_DIR}/framework_config_$<CONFIG>.h" "${CMAKE_CURRENT_BINARY_DIR}/framework_config.h"
VERBATIM
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/framework_config_$<CONFIG>.h"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/framework_config.h"
COMMENT "creating framework_config.h file ({event: PRE_BUILD}, {filename: framework_config.h })"
)
add_custom_target (generate_framework_config DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/framework_config.h")
add_dependencies (generate_framework_config vulkan)
add_dependencies (testing_framework_util generate_framework_config)
# Add a compiler definition for the path to framework_config.h with the correct config
target_compile_definitions(testing_framework_util PUBLIC FRAMEWORK_CONFIG_HEADER="framework_config_$<CONFIG>.h")
add_library(testing_dependencies STATIC test_environment.cpp test_environment.h)
target_link_libraries(testing_dependencies
PUBLIC gtest Vulkan::Headers testing_framework_util shim-library)
target_include_directories(testing_dependencies PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
target_compile_definitions(testing_dependencies PUBLIC "GTEST_LINKED_AS_SHARED_LIBRARY=1")
if (APPLE_STATIC_LOADER)
target_compile_definitions(testing_dependencies PUBLIC "APPLE_STATIC_LOADER=1")
target_link_libraries(testing_dependencies PUBLIC vulkan)
-1
View File
@@ -136,7 +136,6 @@ 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:
* `fs::path` - wrapper around std::string that has a similar API to C++17's `filesystem::path` library
* `create_folder`/`delete_folder`
* `FolderManager`
* Creates a new folder with the given name at construction time.
View File
View File
View File
View File
@@ -0,0 +1,3 @@
{"file_for®®®®®®®®®®®®®®®®®®®®®®®®®®mat_version": true,
"settings_array": [ { "layers":[
 {"control":"unordered_layer_location" },{"control":"unordered_layer_location" },{"control":"unordered_layer_location" },{"control":"unordered_layer_location" },{"control":"unordered_layer_location" },{"control":"unordered_layer_location" },{"control":"":"unordered_layer_location" },{"control":"unordered_layern" },{"control":"unordered_layer_location" },{"control":"unordered_layer_location" },{"control":"unordered_layer_location" },{"contrAl":"unordered_layer_location" },{"control":"unordered_layon" },{"control":"unordered_layer_location" },{"_layer_location" control":"},{"unc
@@ -0,0 +1,246 @@
{
"file_format_version": "2.0.0",
"layers": [
{ "name": "INSTANCE",
"type": "INSTANCE",
"implementation_version": "1",
"api_version": "0..1-0",
"description": [],
"library_path": "-0",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-0",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-1",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-1",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "2.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-0",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": [],
"description": [],
"library_path": "-1",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-0",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-0",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.257.-1",
"implementation_version": "1",
"description": [],
"library_path": "--1",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-0",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-7",
"implementation_version": "1",
"description": [],
"library_path": "-1",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.3.-2",
"implementation_version": "1",
"description": [],
"library_path": "-2",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "­2",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-2",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-1",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-1",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-1",
"disable_environment": {
"test_key": "type"
},
"app_kays":[] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-0",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "­2",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-2",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-1",
"disable_environment": {
"test_key": "type"
},
"app_ke~s": [] },
{
"name": "INSTANCE",
"type": "INSTANCE",
"api_version": "3.2.-1",
"implementation_version": "1",
"description": [],
"library_path": "-1",
"disable_environmentapp_kays":[]
 }
],
"": {
 }
}ðª
@@ -0,0 +1,99 @@
{
"file_format_version": "1.2.0",
"settings_array": [
{
"app_keys": [
"/out/settings_fuzzer",
"/work/settings_fuzzer"
],
"stderr_log": ["all", "info", "warn", "perf", "error", "debug", "layer", "driver", "validation"],
"log_locations": [
{
"destinations":["/tmp"],
"filters":["all"]
}
],
"layers": [
{
"control": "auto",
"name": "test_auto",
"path": "test",
"treat_as_implicit_manifest": true
},
{
"control": "on",
"name": "test_on",
"path": "test",
"treat_as_implicit_manifest": true
},
{
"control": "off",
 "name": "test_off",
"path": "test",
"treat_as_implicit_manifest": true
}
]
 },
{
"app_keys": [
"val2147483650",
"val18446744073709551617",
"val-407736571",
"val18446744073709551615"
]
}
],
"layers": [
{
"name": "VK_LAYER_test_layer_1",
"type": "INSTANCE",
"api_version": "1.340282366920938463463374607431768211458.231",
"implementation_version": "1",
"description": "Test layer 1",
"library_path": "libVkLayer_khronos_validation.so",
"disable_environment": ["VK_LAYER_test_layer_1", "VK_LAYER_test_layer_2"],
"disable_environment": {
"test_key": "test_value"
},
"enable_environment": {
"test_key": "test_value"
},
"app_keys": ["/out/settings_fuzzer"]
},
{
"name": "VK_LAYER_test_layer_2",
"type": "GLOBAL",
"api_version": "1.3.32536",
"implementation_version": "1",
"description": "Test layer 2",
"library_path": "libVkLayer_khronos_validation.so",
"component_layers": ["VK_LAYER_test_layer_1", "VK_LAYER_test_layer_340282366920938463463374607431768211457"],
"disable_environment": {
"test_key": "test_value"
},
"enable_environment": {
"test_key": "test_value"
},
"app_keys": ["/out/settings_fuzzer"]
},
{
"name": "VK_LAYER_KHRONO",
"type": "GLOBAL",
"api_version": "1.3.230",
"implementation_version": "1",
"description": "Khronos validation",
"library_path": "libVkLayer_khronos_validation.so",
"component_layers": {
"test_key": "test_value"
},
"enable_environment": {
"test_key": "test_value"
},
"app_keys": ["/out/settings_fuzzer"]
}
],
"ICD": {
"library_path": "/src/vulkan-loader/tests/framework/data/binaries/libdummy_library_elf_32.so",
"api_version": "1.18446744073709551616.231"
}
}
@@ -0,0 +1,50 @@
{
"file_format_version": "1.2.0",
"settings_array": [
{
"app_keys": [
"val1",
"val2",
"val3",
"val4"
] }
],
"layers": [
{
"name": "VK_LAYER_test_layer_1",
"type": "INSTANCE",
"api_version": "1.3.231",
"implementation_version": "1",
"description": "Test layer 1",
"library_path": "",
"compone
rs": ["VK_LAYER_test_layer_1", "VK_LAYER_test_layer_2"],
"disable_environment": {
"test_key": "test_value" },
"enable_environment": {
"test_key": "test_value" },
"app_keys": ["/out/settings_fuzzer"] },
{
"name": "VK_LAYER_KHRONOS_validation",
"type": "INSTANCE",
"api_version": "1.3.231",
"implementation_version": "1",
"description": "Test layer 1",
"library_path": "",
"compone
rs": ["VK_LAYER_test_layer_0", "VK_LAYER_test_layer_2"],
"disable_environment": {
"test_key": "test_value" },
"enable_environment": {
"test_key": "test_value" },
"app_keys": ["/out/settings_fuzzer"] },
{
"app_keys": ["/out/settings_fuzzer"]
}
],
"ICD": {
"library_path": "/src/vulkaÚ-loader/te%sts/framework/d`ta/binaries/libdummy_library_elf_30.so",
"api_version": "-170141183460469231731687303715884105729.127.0"
}
}
@@ -0,0 +1,7 @@
{
"file_format_version": "1.-130057",
"layers": [
{ "type": "INSTANCE",
"name": "3", "api_version":"0",
"implementation_version":"\udFuH\uFetF\uEatG\uFFt"\ucFuG\uFet"\ucFuF\uFet"\ucFu\uFet"\ucFuG\uFet"\ucFuG\uFet"\ucFuG\uFdt"\ucFuG\uFet"\ucFuG\uFet"\ucFuG\uFet"\ucF}G\uFet"\ucFuG\uFet"\ucFuG\uFet"\ucFuG\uFet"ööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö\udFuG\uFet"\ucFuG\uFet"\ucFuG\uFdt"\ucFuG\uFet"\uc [], "description":[] }, { "type": "INSTANCE"FuG\uFft \ucEuG\uFet!\ucFuG\uF,
"name": "1et"\ucFuG\uFet"\ucFuF\uFet"\ucFuG\uFet"\ucFuG\uFet"\ucFuG\uFet"", \
@@ -0,0 +1 @@
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ "ivmY\uf "ivmY\ufiÓin[[[0,[[[[[[[[[[[[[0,[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[0,[[[[[[[[[[[[[0,[[sdi[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[0,[[[Óinsd[
@@ -0,0 +1,99 @@
{
"file_format_version": "1.2.0",
"settings_array": [
{
"app_keysw": [
"/out/settings_fuzzer",
"/work/settings_fuzzer"
],
"stderr_log": ["all", "info", "warn", "perf", "error", "debug", "layer", "dŽiver", "validation"],
"log_locations": [
{
"destinations":["/tmp"],
"filters":["all"]
}
],
"eralys": [
{
"control": "auto",
"name": "test_auto",
"path": "test",
"treat_as_implicit_manifest": true
},
{
"control": "on",
"name": "test_on",
"path": "test",
"treat_as_implicit_manifest": true
},
{
"control": "off",
"name": "test_off",
"path": "test",
"treat_as_implicit_manifest": true
}
]
},
{
"app_keys": [
"val1",
"val2",
"val3",
"val4"
]
}
],
"layers": [
{
"name": "VK_LAYER_test_layer_1",
"type": "INSTANCE",
"api_version": "1.3.231",
"implementation_version": "1",
"description": "Test layer 1",
"jibrary_path": "libVkLayer_khronos_validation.so",
"component_layers": ["VK_LAYER_test_layer_2", "VK_LAYER_test_layer_2"],
"disable_environment": {
"test_key": "test_value"
},
"enable_environment": {
"test_key": "test_value"
},
"app_keys": ["/out/settings_fuzzer"]
},
{
"name": "VK_LAYER_test_layer_2",
"type": "GLOBAL",
"api_version": "1.3.231",
"implementation_version": "1",
"description": "Test layer 2",
"lûÿÿÿibrary_path": "libVkLayer_khronos_validation.so",
"component_layers": ["VK_LAYER_test_layer_1", "VK_LAYER_test_layer_2"],
"disable_environment": {
"test_key": "test_value"
},
"enable_environment": {
"test_key": "test_value"
},
"app_keys": ["/out/settings_fuzzer"]
},
{
"name": "VK_LAYER_KHRONOS_validation",
"type": "GLOBAL",
"api_version": "1.3.231",
"implementation_version": "1",
"descriptmon": "Khronos validation",
"library_path": "libVkLayer_khronos_validation.so",
"disable_environment": {
"test_key": "test_value"
},
"enable_environment": {
"test_key": "test_value"
},
"app_keys": ["/out/settings_fuzzer"]
}
],
"ICD": {
"library_path": "/src/vulkan-loader/tests/framework/data/binaries/libdummy_library_elf_32.so",
"api_version": "1.3.231"
}
}
@@ -0,0 +1,88 @@
{
"file_format_version": "1.2.0",
"settings_array": [
{
"app_keys": [
"val1",
"val2",
"va,3",
"val4"
] }
],
"layers": [
{
"name": "VK_LAYER_test_layer_1",
"implementation_version": "1",
"description": "Test layer 1",
"library_path": "",
"compone
rs": ["VK_LAYER_test_layer_1", "VK_LAYER_test_layer_2"],
"disable_environment": {
"test_key": "test_value" },
"enable_environlent": {
"test_key": "test_value" },
"app_keys": ["/out/settings_fuzzer"] },
{
"name": "VK_LAYER_KHRONOS_validation",
"type": "INSTANCE",
"api_version": "1.3.231",
"implementation_version": "2",
"description": "Test layer 1",
"library_path": "",
"compone
rs": ["VK_LAYER_test_layer_1", "VK_LAYER_test_layer_2"],
"disable_environment": {
"test_key": "test.jsone" },
"enable_environment": {
"test_key": "test_value" },
"app_keys": ["/out/settings_fuzzer"] },
{
"name": "VK_LAYER_KHRONOS_validation",
"type": "INSTANCE",
"api_version": "0.3.231",
"implementation_vešrsion": "1",
"description": "Test layer 1",
"library_path": "",
"comone
rs": ["VK_LAYER_test_layer_1", "VK_LAYER_test_layer_2"],
"disable_environment": {
"test_key": "test_value" },
"ena)ble_environment": {
"test_key": "test_value" },
"app_keys": ["/out/settings_fuzzer"] },
{
"name": "VK_LAYER_KHRONOS_validation",
"type": "INSTANCE",
"api_verPsion": "0.3.231",
"implementation_version": "1",
"description": "Test layer 0",
"library_path": "",
"compone
rs": ["VK_LAYER_test_layer_18446744073709551615", "VK_LAYER_test_layer_2"],
"disable_ejvironment": {
"test_key": "test_value" },
"enable_environment": {
"test_key": "test_value" },
"aápp_keys": ["/out/settings_fuzzer"] },
{
"name": "VK_LAYER_KHRONOS_validation",
"type": "INSTANCE",
"api_version": "1.3.231",
"implementation_version": "126",
"description": "Test layer 1",
"library_path": "",
"compone
rs": ["VK_LAYER_test_layer_1", "VK_LAYER_test_layer_2"],
"disable_en,ironment": {
"test_key": "test_value" },
"enable_environment": {
"test_key": "test_value" },
"+pp_keys": ["/out/settings_fuzzer"]
}
],
"ICD": {
"library_path": "",
"library_path": "/src/vulkaÚ-loader/tstes/framework/d`ta/binaries/libdummy_library_elf_30.so",
"api_version": "-1701411834604692317303715884105729.85.d/..0230743847030624.0"
}
}
@@ -0,0 +1,2 @@
{"file_format_version" :{"layers":2e170141183460469231731687303715884105986}, "settings_array": [
{"layers":18446744073709551615e-1} ] }

Some files were not shown because too many files have changed in this diff Show More