mirror of
https://gitee.com/openharmony/third_party_vulkan-loader
synced 2024-11-22 23:00:43 +00:00
update to v1.3.275
Signed-off-by: andrew0229 <zhangzhao62@huawei.com> Change-Id: Ifc4224db2c6ea7c159d3cabe8f075475d47a41a8
This commit is contained in:
parent
8b5f1310fb
commit
0281b281d0
@ -1,34 +0,0 @@
|
||||
# Configuration for cmake-format (v0.4.1, circa Jul 2018)
|
||||
# https://github.com/cheshirekow/cmake_format
|
||||
|
||||
# How wide to allow formatted cmake files
|
||||
line_width = 132
|
||||
|
||||
# How many spaces to tab for indent
|
||||
tab_size = 4
|
||||
|
||||
# If arglists are longer than this, break them always
|
||||
max_subargs_per_line = 3
|
||||
|
||||
# If true, separate flow control names from their parentheses with a space
|
||||
separate_ctrl_name_with_space = False
|
||||
|
||||
# If true, separate function names from parentheses with a space
|
||||
separate_fn_name_with_space = False
|
||||
|
||||
# If a statement is wrapped to more than one line, than dangle the closing
|
||||
# parenthesis on it's own line
|
||||
dangle_parens = False
|
||||
|
||||
# What character to use for bulleted lists
|
||||
bullet_char = u'*'
|
||||
|
||||
# What character to use as punctuation after numerals in an enumerated list
|
||||
enum_char = u'.'
|
||||
|
||||
# What style line endings to use in the output.
|
||||
line_ending = u'unix'
|
||||
|
||||
# Format command names consistently as 'lower' or 'upper' case
|
||||
command_case = u'lower'
|
||||
|
7
.github/dependabot.yml
vendored
Normal file
7
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 3
|
427
.github/workflows/build.yml
vendored
427
.github/workflows/build.yml
vendored
@ -1,5 +1,5 @@
|
||||
# Copyright (c) 2021 Valve Corporation
|
||||
# Copyright (c) 2021 LunarG, Inc.
|
||||
# Copyright (c) 2021-2023 Valve Corporation
|
||||
# Copyright (c) 2021-2023 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,137 +14,380 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
# Author: Lenny Komow <lenny@lunarg.com>
|
||||
# Author: Charles Giessen <charles@lunarg.com>
|
||||
|
||||
name: CI Build
|
||||
|
||||
# https://docs.github.com/en/actions/using-jobs/using-concurrency
|
||||
concurrency:
|
||||
# github.head_ref is only defined on pull_request
|
||||
# Fallback to the run ID, which is guaranteed to be both unique and defined for the run.
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
push:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
cc: [ gcc, clang ]
|
||||
cxx: [ g++, clang++ ]
|
||||
compiler: [ {cc: gcc, cxx: g++}, {cc: clang, cxx: clang++} ]
|
||||
config: [ Debug, Release ]
|
||||
os: [ ubuntu-18.04, ubuntu-20.04 ]
|
||||
exclude:
|
||||
- cc: gcc
|
||||
cxx: clang++
|
||||
- cc: clang
|
||||
cxx: g++
|
||||
|
||||
os: [ ubuntu-20.04, ubuntu-22.04 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- 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
|
||||
# practice to try and support them so they don't have to install
|
||||
# the CMake tarball. Ideally the minimum we use matches what the default
|
||||
# package provided by Ubuntu via APT.
|
||||
if: ${{ matrix.os == 'ubuntu-20.04' }}
|
||||
uses: lukka/get-cmake@latest
|
||||
with:
|
||||
cmakeVersion: 3.17.2
|
||||
- run: sudo apt update
|
||||
- run: sudo apt install libwayland-dev libxrandr-dev
|
||||
- run: sudo apt install --yes --no-install-recommends libwayland-dev libxrandr-dev
|
||||
- run: |
|
||||
cmake -S. -B build \
|
||||
-D CMAKE_BUILD_TYPE=${{ matrix.config }} \
|
||||
-D BUILD_TESTS=ON \
|
||||
-D UPDATE_DEPS=ON \
|
||||
-D LOADER_ENABLE_ADDRESS_SANITIZER=ON \
|
||||
-D BUILD_WERROR=ON \
|
||||
-D CMAKE_CXX_COMPILER=${{ matrix.compiler.cxx }} \
|
||||
-D CMAKE_C_COMPILER=${{ matrix.compiler.cc }}
|
||||
- run: cmake --build build
|
||||
- run: ctest --output-on-failure --test-dir build/
|
||||
- run: cmake --install build --prefix /tmp
|
||||
|
||||
- name: Generate build files
|
||||
run: cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=${{matrix.config}} -DBUILD_TESTS=On -DUPDATE_DEPS=ON -DTEST_USE_ADDRESS_SANITIZER=ON
|
||||
codegen:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: scripts/update_deps.py --dir ext --no-build
|
||||
- run: scripts/generate_source.py --verify ext/Vulkan-Headers/registry/
|
||||
|
||||
linux-no-asm:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: sudo apt update
|
||||
- run: sudo apt install --yes --no-install-recommends libwayland-dev libxrandr-dev
|
||||
- run: |
|
||||
cmake -S. -B build \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D BUILD_TESTS=ON \
|
||||
-D UPDATE_DEPS=ON \
|
||||
-D BUILD_WERROR=ON \
|
||||
-D USE_GAS=OFF \
|
||||
-D CMAKE_C_COMPILER=clang \
|
||||
-D CMAKE_CXX_COMPILER=clang++
|
||||
- run: cmake --build build
|
||||
- run: cmake --install build --prefix /tmp
|
||||
- run: ctest --output-on-failure -E UnknownFunction --test-dir build/
|
||||
|
||||
linux-32:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
config: [ Debug, Release ]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- uses: lukka/get-cmake@latest
|
||||
with:
|
||||
cmakeVersion: 3.17.2
|
||||
- name: Enable 32 bit
|
||||
run: sudo dpkg --add-architecture i386
|
||||
- run: sudo apt-get update
|
||||
- run: |
|
||||
sudo apt install --yes --no-install-recommends \
|
||||
gcc-multilib g++-multilib libc6:i386 libc6-dev-i386 libgcc-s1:i386 \
|
||||
libwayland-dev:i386 libxrandr-dev:i386
|
||||
- run: |
|
||||
cmake -S. -B build \
|
||||
-D CMAKE_BUILD_TYPE=${{matrix.config}} \
|
||||
-D BUILD_TESTS=ON \
|
||||
-D UPDATE_DEPS=ON \
|
||||
-D BUILD_WERROR=ON \
|
||||
-D SYSCONFDIR=/etc/not_vulkan \
|
||||
-G Ninja
|
||||
env:
|
||||
CC: ${{matrix.cc}}
|
||||
CXX: ${{matrix.cxx}}
|
||||
CFLAGS: -m32
|
||||
CXXFLAGS: -m32
|
||||
LDFLAGS: -m32
|
||||
ASFLAGS: --32
|
||||
- run: cmake --build build
|
||||
- run: cmake --install build --prefix /tmp
|
||||
- run: ctest --output-on-failure
|
||||
working-directory: build/
|
||||
|
||||
- name: Build the loader
|
||||
run: make -C build
|
||||
|
||||
- name: Run regression tests
|
||||
working-directory: ./build
|
||||
run: ctest --output-on-failure
|
||||
|
||||
- name: Verify generated source files
|
||||
run: python scripts/generate_source.py --verify external/Vulkan-Headers/registry
|
||||
|
||||
- name: Verify code formatting with clang-format
|
||||
run: ./scripts/check_code_format.sh
|
||||
|
||||
- name: Verify commit message formatting
|
||||
run: ./scripts/check_commit_message_format.sh
|
||||
|
||||
windows:
|
||||
runs-on: ${{matrix.os}}
|
||||
linux-32-no-asm:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- uses: lukka/get-cmake@latest
|
||||
with:
|
||||
cmakeVersion: 3.17.2
|
||||
- name: Enable 32 bit
|
||||
run: sudo dpkg --add-architecture i386
|
||||
- run: sudo apt-get update
|
||||
- run: |
|
||||
sudo apt install --yes --no-install-recommends \
|
||||
gcc-multilib g++-multilib libc6:i386 libc6-dev-i386 libgcc-s1:i386 \
|
||||
libwayland-dev:i386 libxrandr-dev:i386
|
||||
- run: |
|
||||
cmake -S. -B build \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D BUILD_TESTS=ON \
|
||||
-D UPDATE_DEPS=ON \
|
||||
-D BUILD_WERROR=ON \
|
||||
-D USE_GAS=OFF \
|
||||
-G Ninja
|
||||
env:
|
||||
CFLAGS: -m32
|
||||
CXXFLAGS: -m32
|
||||
LDFLAGS: -m32
|
||||
ASFLAGS: --32
|
||||
- run: cmake --build build
|
||||
- run: ctest --output-on-failure -E UnknownFunction
|
||||
working-directory: build/
|
||||
|
||||
windows_vs:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [ Win32, x64 ]
|
||||
config: [ Debug, Release ]
|
||||
os: [ windows-latest ]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- uses: actions/checkout@v4
|
||||
- run: |
|
||||
cmake -S. -B build `
|
||||
-D BUILD_TESTS=ON `
|
||||
-D UPDATE_DEPS=ON `
|
||||
-D CMAKE_BUILD_TYPE=${{matrix.config}} `
|
||||
-A ${{ matrix.arch }} `
|
||||
-D BUILD_WERROR=ON
|
||||
- run: cmake --build build/ --config ${{matrix.config}}
|
||||
- run: cmake --install build --prefix build/install --config ${{matrix.config}}
|
||||
- run: ctest --output-on-failure -C ${{matrix.config}} --test-dir build/
|
||||
|
||||
- name: Generate build files
|
||||
run: cmake -S. -Bbuild -A${{matrix.arch}} -DBUILD_TESTS=On -DUPDATE_DEPS=ON
|
||||
windows_vs-no-asm:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [ Win32, x64 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: |
|
||||
cmake -S. -B build `
|
||||
-D BUILD_TESTS=ON `
|
||||
-D UPDATE_DEPS=ON `
|
||||
-D USE_MASM=OFF `
|
||||
-D CMAKE_BUILD_TYPE=Release `
|
||||
-A ${{ matrix.arch }} `
|
||||
-D BUILD_WERROR=ON
|
||||
- run: cmake --build build/ --config Release
|
||||
- run: ctest --output-on-failure -C Release -E UnknownFunction --test-dir build/
|
||||
|
||||
- name: Build the loader
|
||||
run: cmake --build ./build --config ${{matrix.config}}
|
||||
|
||||
- name: Run regression tests
|
||||
working-directory: ./build
|
||||
run: ctest --output-on-failure
|
||||
|
||||
- name: Verify generated source files
|
||||
run: python scripts/generate_source.py --verify external/Vulkan-Headers/registry
|
||||
# Test both clang and clang-cl (Chromium project uses clang-cl)
|
||||
windows_clang:
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
matrix:
|
||||
compiler: [ clang, clang-cl ]
|
||||
config: [ Debug, Release ]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
- run: |
|
||||
cmake -S. -B build `
|
||||
-D CMAKE_C_COMPILER=${{matrix.compiler}} `
|
||||
-D CMAKE_CXX_COMPILER=${{matrix.compiler}} `
|
||||
-D UPDATE_DEPS=ON `
|
||||
-D CMAKE_BUILD_TYPE=${{matrix.config}} `
|
||||
-D BUILD_WERROR=ON `
|
||||
-D BUILD_TESTS=ON `
|
||||
-G Ninja
|
||||
- run: cmake --build build/
|
||||
- run: ctest --output-on-failure --test-dir build/
|
||||
- run: cmake --install build --prefix build/install
|
||||
|
||||
mac:
|
||||
runs-on: macos-latest
|
||||
|
||||
runs-on: macos-11
|
||||
strategy:
|
||||
matrix:
|
||||
config: [ Debug, Release ]
|
||||
|
||||
static_build: [ APPLE_STATIC_LOADER=ON, APPLE_STATIC_LOADER=OFF ]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- uses: lukka/get-cmake@latest
|
||||
- run: |
|
||||
cmake -S. -B build \
|
||||
-D CMAKE_BUILD_TYPE=${{matrix.config}} \
|
||||
-D ${{matrix.static_build}} \
|
||||
-D BUILD_TESTS=ON \
|
||||
-D UPDATE_DEPS=ON \
|
||||
-D BUILD_WERROR=ON \
|
||||
-D LOADER_ENABLE_ADDRESS_SANITIZER=ON \
|
||||
-G Ninja
|
||||
env:
|
||||
# Prevents regression of KhronosGroup/Vulkan-Loader/issues/1332
|
||||
LDFLAGS: -Wl,-fatal_warnings
|
||||
- run: cmake --build build
|
||||
- run: cmake --install build --prefix /tmp
|
||||
- run: ctest --output-on-failure --test-dir build/
|
||||
|
||||
- name: Generate build files
|
||||
run: cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=${{matrix.config}} -DBUILD_TESTS=On -DUPDATE_DEPS=ON -DTEST_USE_ADDRESS_SANITIZER=ON
|
||||
|
||||
- name: Build the loader
|
||||
run: make -C build
|
||||
|
||||
- name: Run regression tests
|
||||
working-directory: ./build
|
||||
run: ctest --output-on-failure
|
||||
|
||||
gn:
|
||||
runs-on: ubuntu-18.04
|
||||
apple-cross-compile:
|
||||
name: ${{ matrix.CMAKE_SYSTEM_NAME }}
|
||||
runs-on: macos-12
|
||||
strategy:
|
||||
matrix:
|
||||
CMAKE_SYSTEM_NAME: [ iOS, tvOS ]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- uses: lukka/get-cmake@latest
|
||||
- run: |
|
||||
cmake -S . -B build \
|
||||
-D CMAKE_SYSTEM_NAME=${{ matrix.CMAKE_SYSTEM_NAME }} \
|
||||
"-D CMAKE_OSX_ARCHITECTURES=arm64;x86_64" \
|
||||
-D CMAKE_BUILD_TYPE=Debug \
|
||||
-D UPDATE_DEPS=ON \
|
||||
-D BUILD_WERROR=ON \
|
||||
-G Ninja
|
||||
env:
|
||||
LDFLAGS: -Wl,-fatal_warnings
|
||||
- run: cmake --build build
|
||||
- run: cmake --install build --prefix /tmp
|
||||
- name: Verify Universal Binary
|
||||
run: |
|
||||
vtool -show-build /tmp/lib/libvulkan.dylib | grep 'architecture x86_64'
|
||||
vtool -show-build /tmp/lib/libvulkan.dylib | grep 'architecture arm64'
|
||||
|
||||
# Building a universal binary disables assembly automatically
|
||||
# Furthermore the Vulkan SDK ships universal binaries
|
||||
mac-univeral:
|
||||
name: "Universal Binary Testing (STATIC ${{ matrix.static }}) w/ ${{ matrix.generator }}"
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
config: [ Debug, Release ]
|
||||
|
||||
static: [ 'ON', 'OFF' ]
|
||||
generator: [ Ninja, Xcode ]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Get depot tools
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- uses: lukka/get-cmake@latest
|
||||
- run: |
|
||||
cmake -S. -B build \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D APPLE_STATIC_LOADER=${{matrix.static}} \
|
||||
"-D CMAKE_OSX_ARCHITECTURES=arm64;x86_64" \
|
||||
-D BUILD_TESTS=ON \
|
||||
-D UPDATE_DEPS=ON \
|
||||
-D BUILD_WERROR=ON \
|
||||
-G ${{ matrix.generator }}
|
||||
env:
|
||||
LDFLAGS: -Wl,-fatal_warnings
|
||||
- run: cmake --build build --config Release
|
||||
- run: ctest --output-on-failure --build-config Release -E UnknownFunction --test-dir build/
|
||||
- run: cmake --install build --config Release --prefix /tmp
|
||||
- name: Verify Universal Binary
|
||||
if: ${{ matrix.static == 'OFF' }}
|
||||
run: |
|
||||
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git depot_tools
|
||||
echo "$GITHUB_WORKSPACE/depot_tools" >> $GITHUB_PATH
|
||||
vtool -show-build /tmp/lib/libvulkan.dylib | grep 'architecture x86_64'
|
||||
vtool -show-build /tmp/lib/libvulkan.dylib | grep 'architecture arm64'
|
||||
|
||||
- name: Fetch and install headers
|
||||
run: ./build-gn/update_deps.sh
|
||||
chromium:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: scripts/gn/gn.py
|
||||
|
||||
- name: Generate build files
|
||||
run: gn gen out/${{matrix.config}} --args="is_debug=true"
|
||||
if: matrix.config != 'Release'
|
||||
mingw:
|
||||
runs-on: windows-2022
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.8'
|
||||
- uses: lukka/get-cmake@latest
|
||||
- name: Setup uasm
|
||||
run: |
|
||||
C:/msys64/usr/bin/pacman -Sy --noconfirm --needed mingw-w64-x86_64-uasm
|
||||
printf '%s\n' 'C:/msys64/mingw64/bin' >> $GITHUB_PATH
|
||||
- name: UASM Check
|
||||
run: uasm -?
|
||||
- run: |
|
||||
cmake -S. -B build \
|
||||
-D UPDATE_DEPS=ON \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D BUILD_WERROR=ON \
|
||||
-G Ninja
|
||||
- run: cmake --build build
|
||||
- run: cmake --install build --prefix /tmp
|
||||
|
||||
- name: Generate build files
|
||||
run: gn gen out/${{matrix.config}} --args="is_debug=false"
|
||||
if: matrix.config == 'Release'
|
||||
mingw-no-asm:
|
||||
runs-on: windows-2022
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.8'
|
||||
- uses: lukka/get-cmake@latest
|
||||
# Make sure this doesn't fail even without explicitly setting '-D USE_MASM=OFF' and without uasm
|
||||
- run: |
|
||||
cmake -S. -B build \
|
||||
-D UPDATE_DEPS=ON \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D BUILD_WERROR=ON \
|
||||
-G Ninja
|
||||
- run: cmake --build build
|
||||
- run: cmake --install build --prefix /tmp
|
||||
|
||||
- name: Build the loader
|
||||
run: ninja -C out/${{matrix.config}}
|
||||
mingw-no-asm-explicit:
|
||||
runs-on: windows-2022
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: lukka/get-cmake@latest
|
||||
- run: |
|
||||
cmake -S. -B build \
|
||||
-D UPDATE_DEPS=ON \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D BUILD_WERROR=ON \
|
||||
-D USE_MASM=OFF \
|
||||
-G Ninja
|
||||
- run: cmake --build build
|
||||
- run: cmake --install build --prefix /tmp
|
||||
|
101
.github/workflows/codeql.yml
vendored
Normal file
101
.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
# Copyright 2023 Google LLC
|
||||
#
|
||||
# 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: Joyce Brum <joycebrum@google.com>
|
||||
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "main" ]
|
||||
schedule:
|
||||
- cron: '26 7 * * 1'
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners
|
||||
# Consider using larger runners for possible analysis time improvements.
|
||||
runs-on: 'ubuntu-latest'
|
||||
timeout-minutes: 360
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'cpp', 'python' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@012739e5082ff0c22ca6d6ab32e07c36df03c4a4 # v3.22.12
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
|
||||
# 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: actions/setup-python@v5
|
||||
if: matrix.language == 'cpp'
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- uses: lukka/get-cmake@latest
|
||||
if: matrix.language == 'cpp'
|
||||
with:
|
||||
cmakeVersion: 3.17.2
|
||||
- name: Install Dependencies
|
||||
if: matrix.language == 'cpp'
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install --yes --no-install-recommends libwayland-dev libxrandr-dev
|
||||
|
||||
- name: Generate build files
|
||||
if: matrix.language == 'cpp'
|
||||
run: cmake -S. -B build -D CMAKE_BUILD_TYPE=Release -D UPDATE_DEPS=ON
|
||||
env:
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
|
||||
- name: Build the loader
|
||||
if: matrix.language == 'cpp'
|
||||
run: cmake --build build
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@012739e5082ff0c22ca6d6ab32e07c36df03c4a4 # v3.22.12
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
43
.github/workflows/format.yml
vendored
Normal file
43
.github/workflows/format.yml
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright (c) 2023 Valve Corporation
|
||||
# Copyright (c) 2023 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.
|
||||
|
||||
name: format
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
clang-format:
|
||||
name: clang-format
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
path:
|
||||
- 'loader'
|
||||
- 'tests'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run clang-format
|
||||
uses: jidicula/clang-format-action@v4.11.0
|
||||
with:
|
||||
clang-format-version: '16'
|
||||
check-path: ${{ matrix.path }}
|
26
.gitignore
vendored
26
.gitignore
vendored
@ -1,3 +1,9 @@
|
||||
# By default we install dependencies to the external directory
|
||||
/external/*
|
||||
|
||||
# Ignore any build directories
|
||||
*build*/
|
||||
|
||||
CMakeCache.txt
|
||||
CMakeLists.txt.user
|
||||
CMakeFiles/
|
||||
@ -5,12 +11,7 @@ cmake_install.cmake
|
||||
Makefile
|
||||
scripts/__pycache__
|
||||
VKConfig.h
|
||||
build
|
||||
build32
|
||||
dbuild
|
||||
external/*
|
||||
!external/CMakeLists.txt
|
||||
!external/README.md
|
||||
|
||||
*.so
|
||||
*.so.*
|
||||
*.pyc
|
||||
@ -30,3 +31,16 @@ external/*
|
||||
_out64
|
||||
out32/*
|
||||
out64/*
|
||||
|
||||
# Chromium build artifacts
|
||||
.cipd/
|
||||
.gn
|
||||
.gclient
|
||||
.gclient_entries
|
||||
.gclient_previous_sync_commits
|
||||
out/
|
||||
third_party/
|
||||
buildtools/
|
||||
depot_tools/
|
||||
testing/
|
||||
tools/
|
||||
|
22
.gn
22
.gn
@ -1,22 +0,0 @@
|
||||
# Copyright (C) 2019 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
buildconfig = "//build/config/BUILDCONFIG.gn"
|
||||
secondary_source = "//build-gn/secondary/"
|
||||
|
||||
default_args = {
|
||||
clang_use_chrome_plugins = false
|
||||
use_custom_libcxx = false
|
||||
}
|
||||
|
21
BUILD.gn
21
BUILD.gn
@ -1,4 +1,6 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Copyright (C) 2018-2019 The ANGLE Project Authors.
|
||||
# Copyright (C) 2019-2023 LunarG, Inc.
|
||||
# Copyright (c) 2023-2024 Huawei Device Co., Ltd.
|
||||
# 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
|
||||
@ -18,14 +20,10 @@ import("//build/ohos.gni")
|
||||
## Build libvulkan.so {{{
|
||||
|
||||
config("vulkan_internal_config") {
|
||||
defines = [
|
||||
"VULKAN_NON_CMAKE_BUILD",
|
||||
"VK_ENABLE_BETA_EXTENSIONS",
|
||||
]
|
||||
defines = [ "VK_ENABLE_BETA_EXTENSIONS" ]
|
||||
cflags = [
|
||||
"-Wno-conversion",
|
||||
"-Wno-extra-semi",
|
||||
"-Wno-implicit-fallthrough",
|
||||
"-Wno-sign-compare",
|
||||
"-Wno-unreachable-code",
|
||||
"-Wno-unused-function",
|
||||
@ -46,10 +44,7 @@ config("vulkan_loader_config") {
|
||||
"loader",
|
||||
"openharmony",
|
||||
]
|
||||
defines = [
|
||||
"API_NAME=\"Vulkan\"",
|
||||
"USE_UNSAFE_FILE_SEARCH=1",
|
||||
]
|
||||
defines = [ "LOADER_USE_UNSAFE_FILE_SEARCH=1" ]
|
||||
}
|
||||
|
||||
ohos_shared_library("vulkan_loader") {
|
||||
@ -67,16 +62,18 @@ ohos_shared_library("vulkan_loader") {
|
||||
"loader/generated/vk_layer_dispatch_table.h",
|
||||
"loader/generated/vk_loader_extensions.h",
|
||||
"loader/generated/vk_object_types.h",
|
||||
"loader/get_environment.c",
|
||||
"loader/get_environment.h",
|
||||
"loader/gpa_helper.c",
|
||||
"loader/gpa_helper.h",
|
||||
"loader/loader.c",
|
||||
"loader/loader.h",
|
||||
"loader/loader_common.h",
|
||||
"loader/loader_environment.c",
|
||||
"loader/loader_environment.h",
|
||||
"loader/log.c",
|
||||
"loader/log.h",
|
||||
"loader/phys_dev_ext.c",
|
||||
"loader/settings.c",
|
||||
"loader/settings.h",
|
||||
"loader/stack_allocation.h",
|
||||
"loader/terminator.c",
|
||||
"loader/trampoline.c",
|
||||
|
547
BUILD.md
547
BUILD.md
@ -4,33 +4,58 @@ Instructions for building this repository on Linux, Windows, and MacOS.
|
||||
|
||||
## Table Of Contents
|
||||
|
||||
- [Contributing to the Repository](#contributing-to-the-repository)
|
||||
- [Repository Content](#repository-content)
|
||||
- [Installed Files](#installed-files)
|
||||
- [Repository Set-Up](#repository-set-up)
|
||||
- [Display Drivers](#display-drivers)
|
||||
- [Download the Repository](#download-the-repository)
|
||||
- [Repository Dependencies](#repository-dependencies)
|
||||
- [Build and Install Directories](#build-and-install-directories)
|
||||
- [Building Dependent Repositories with Known-Good Revisions](#building-dependent-repositories-with-known-good-revisions)
|
||||
- [Generated source code](#generated-source-code)
|
||||
- [Build Options](#build-options)
|
||||
- [Building On Windows](#building-on-windows)
|
||||
- [Windows Development Environment Requirements](#windows-development-environment-requirements)
|
||||
- [Windows Build - Microsoft Visual Studio](#windows-build---microsoft-visual-studio)
|
||||
- [Windows Notes](#windows-notes)
|
||||
- [CMake Visual Studio Generators](#cmake-visual-studio-generators)
|
||||
- [Using The Vulkan Loader Library in this Repository on Windows](#using-the-vulkan-loader-library-in-this-repository-on-windows)
|
||||
- [Building On Linux](#building-on-linux)
|
||||
- [Linux Development Environment Requirements](#linux-development-environment-requirements)
|
||||
- [Linux Build](#linux-build)
|
||||
- [Building on MacOS](#building-on-macos)
|
||||
- [MacOS Development Environment Requirements](#macos-development-environment-requirements)
|
||||
- [Clone the Repository](#clone-the-repository)
|
||||
- [MacOS build](#macos-build)
|
||||
- [Building on Fuchsia](#building-on-fuchsia)
|
||||
- [Building on QNX](#building-on-qnx)
|
||||
- [SDK Symbols](#sdk-symbols)
|
||||
- [Build Instructions](#build-instructions)
|
||||
- [Table Of Contents](#table-of-contents)
|
||||
- [Contributing to the Repository](#contributing-to-the-repository)
|
||||
- [Repository Content](#repository-content)
|
||||
- [Installed Files](#installed-files)
|
||||
- [Build Requirements](#build-requirements)
|
||||
- [Test Requirements](#test-requirements)
|
||||
- [Repository Set-Up](#repository-set-up)
|
||||
- [Display Drivers](#display-drivers)
|
||||
- [Repository Dependencies](#repository-dependencies)
|
||||
- [Vulkan-Headers](#vulkan-headers)
|
||||
- [Test Dependencies](#test-dependencies)
|
||||
- [Build and Install Directory Locations](#build-and-install-directory-locations)
|
||||
- [Building Dependent Repositories with Known-Good Revisions](#building-dependent-repositories-with-known-good-revisions)
|
||||
- [Automatically](#automatically)
|
||||
- [Manually](#manually)
|
||||
- [Notes About the Manual Option](#notes-about-the-manual-option)
|
||||
- [Generated source code](#generated-source-code)
|
||||
- [Build Options](#build-options)
|
||||
- [Building On Windows](#building-on-windows)
|
||||
- [Windows Development Environment Requirements](#windows-development-environment-requirements)
|
||||
- [Windows Build - Microsoft Visual Studio](#windows-build---microsoft-visual-studio)
|
||||
- [Windows Quick Start](#windows-quick-start)
|
||||
- [Use `CMake` to Create the Visual Studio Project Files](#use-cmake-to-create-the-visual-studio-project-files)
|
||||
- [Build the Solution From the Command Line](#build-the-solution-from-the-command-line)
|
||||
- [Build the Solution With Visual Studio](#build-the-solution-with-visual-studio)
|
||||
- [Windows Install Target](#windows-install-target)
|
||||
- [Building On Linux](#building-on-linux)
|
||||
- [Linux Development Environment Requirements](#linux-development-environment-requirements)
|
||||
- [Required Package List](#required-package-list)
|
||||
- [Linux Build](#linux-build)
|
||||
- [Linux Quick Start](#linux-quick-start)
|
||||
- [Use CMake to Create the Make Files](#use-cmake-to-create-the-make-files)
|
||||
- [Build the Project](#build-the-project)
|
||||
- [Linux Notes](#linux-notes)
|
||||
- [WSI Support Build Options](#wsi-support-build-options)
|
||||
- [Linux Install to System Directories](#linux-install-to-system-directories)
|
||||
- [Linux 32-bit support](#linux-32-bit-support)
|
||||
- [Building on MacOS](#building-on-macos)
|
||||
- [MacOS Development Environment Requirements](#macos-development-environment-requirements)
|
||||
- [Clone the Repository](#clone-the-repository)
|
||||
- [MacOS build](#macos-build)
|
||||
- [Building with the Unix Makefiles Generator](#building-with-the-unix-makefiles-generator)
|
||||
- [Building with the Xcode Generator](#building-with-the-xcode-generator)
|
||||
- [Building on Fuchsia](#building-on-fuchsia)
|
||||
- [SDK Symbols](#sdk-symbols)
|
||||
- [Building on QNX](#building-on-qnx)
|
||||
- [Cross Compilation](#cross-compilation)
|
||||
- [Unknown function handling which requires explicit assembly implementations](#unknown-function-handling-which-requires-explicit-assembly-implementations)
|
||||
- [Platforms which fully support unknown function handling](#platforms-which-fully-support-unknown-function-handling)
|
||||
- [Link Time Optimization](#link-time-optimization)
|
||||
- [Tests](#tests)
|
||||
|
||||
|
||||
## Contributing to the Repository
|
||||
@ -53,8 +78,15 @@ indicated by *install_dir*:
|
||||
- *install_dir*`/lib` : The Vulkan loader library
|
||||
- *install_dir*`/bin` : The Vulkan loader library DLL (Windows)
|
||||
|
||||
The `uninstall` target can be used to remove the above files from the install
|
||||
directory.
|
||||
## Build Requirements
|
||||
|
||||
1. `C99` capable compiler
|
||||
2. `CMake` version 3.17.2 or greater
|
||||
3. `Git`
|
||||
|
||||
### Test Requirements
|
||||
|
||||
1. `C++17` capable compiler
|
||||
|
||||
## Repository Set-Up
|
||||
|
||||
@ -64,20 +96,14 @@ This repository does not contain a Vulkan-capable driver. You will need to
|
||||
obtain and install a Vulkan driver from your graphics hardware vendor or from
|
||||
some other suitable source if you intend to run Vulkan applications.
|
||||
|
||||
### Download the Repository
|
||||
|
||||
To create your local git repository:
|
||||
|
||||
git clone https://github.com/KhronosGroup/Vulkan-Loader.git
|
||||
|
||||
### Repository Dependencies
|
||||
|
||||
This repository attempts to resolve some of its dependencies by using
|
||||
components found from the following places, in this order:
|
||||
|
||||
1. CMake or Environment variable overrides (e.g., -DVULKAN_HEADERS_INSTALL_DIR)
|
||||
1. LunarG Vulkan SDK, located by the `VULKAN_SDK` environment variable
|
||||
1. System-installed packages, mostly applicable on Linux
|
||||
1. CMake or Environment variable overrides (e.g., -D VULKAN_HEADERS_INSTALL_DIR)
|
||||
2. System-installed packages, mostly applicable on Linux
|
||||
|
||||
Dependencies that cannot be resolved by the SDK or installed packages must be
|
||||
resolved with the "install directory" override and are listed below. The
|
||||
@ -87,24 +113,31 @@ version of that dependency.
|
||||
#### Vulkan-Headers
|
||||
|
||||
This repository has a required dependency on the [Vulkan Headers repository](https://github.com/KhronosGroup/Vulkan-Headers).
|
||||
You must clone the headers repository and build its `install` target before
|
||||
building this repository. The Vulkan-Headers repository is required because it
|
||||
contains the Vulkan API definition files (registry) that are required to build
|
||||
the loader. You must also take note of the headers install directory and pass
|
||||
it on the CMake command line for building this repository, as described below.
|
||||
The Vulkan-Headers repository contains the Vulkan API definition files that are
|
||||
required to build the loader.
|
||||
|
||||
#### Test Dependencies
|
||||
|
||||
The loader tests depend on the [Google Test](https://github.com/google/googletest) library and
|
||||
on Windows platforms depends on the [Microsoft Detours](https://github.com/microsoft/Detours) library.
|
||||
|
||||
To build the tests, pass the `-DUPDATE_DEPS=ON` and `-DBUILD_TESTS=ON` options when generating the project:
|
||||
To build the tests, pass both `-D UPDATE_DEPS=ON` and `-D BUILD_TESTS=ON` options when generating the project:
|
||||
```bash
|
||||
cmake ... -DUPDATE_DEPS=ON -DBUILD_TESTS=ON ...
|
||||
cmake ... -D UPDATE_DEPS=ON -D BUILD_TESTS=ON ...
|
||||
```
|
||||
This will ensure googletest and detours is downloaded and the appropriate version is used.
|
||||
|
||||
### Build and Install Directories
|
||||
### Warnings as errors off by default!
|
||||
|
||||
By default `BUILD_WERROR` is `OFF`. The idiom for open source projects is to NOT enable warnings as errors.
|
||||
|
||||
System/language package managers have to build on multiple different platforms and compilers.
|
||||
|
||||
By defaulting to `ON` we cause issues for package managers since there is no standard way to disable warnings.
|
||||
|
||||
Add `-D BUILD_WERROR=ON` to your workflow
|
||||
|
||||
### Build and Install Directory Locations
|
||||
|
||||
A common convention is to place the `build` directory in the top directory of
|
||||
the repository and place the `install` directory as a child of the `build`
|
||||
@ -115,11 +148,11 @@ although you can place these directories in any location.
|
||||
|
||||
There is a Python utility script, `scripts/update_deps.py`, that you can use
|
||||
to gather and build the dependent repositories mentioned above.
|
||||
This program also uses information stored in the `scripts/known-good.json` file
|
||||
This program uses information stored in the `scripts/known-good.json` file
|
||||
to checkout dependent repository revisions that are known to be compatible with
|
||||
the revision of this repository that you currently have checked out.
|
||||
|
||||
You can choose to do this manually or automatically.
|
||||
You can choose to do this automatically or manually.
|
||||
The first step to either is cloning the Vulkan-Loader repo and stepping into
|
||||
that newly cloned folder:
|
||||
|
||||
@ -128,6 +161,16 @@ that newly cloned folder:
|
||||
cd Vulkan-Loader
|
||||
```
|
||||
|
||||
#### Automatically
|
||||
|
||||
On the other hand, if you choose to let the CMake scripts do all the
|
||||
heavy-lifting, you may just trigger the following CMake commands:
|
||||
|
||||
```
|
||||
cmake -S . -B build -D UPDATE_DEPS=On
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
#### Manually
|
||||
|
||||
To manually update the dependencies you now must create the build folder, and
|
||||
@ -136,7 +179,7 @@ run the update deps script followed by the necessary CMake build commands:
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
../scripts/update_deps.py
|
||||
python ../scripts/update_deps.py
|
||||
cmake -C helper.cmake ..
|
||||
cmake --build .
|
||||
```
|
||||
@ -146,22 +189,16 @@ run the update deps script followed by the necessary CMake build commands:
|
||||
- You may need to adjust some of the CMake options based on your platform. See
|
||||
the platform-specific sections later in this document.
|
||||
- The `update_deps.py` script fetches and builds the dependent repositories in
|
||||
the current directory when it is invoked. In this case, they are built in
|
||||
the `build` directory.
|
||||
- The `build` directory is also being used to build this
|
||||
(Vulkan-ValidationLayers) repository. But there shouldn't be any conflicts
|
||||
inside the `build` directory between the dependent repositories and the
|
||||
build files for this repository.
|
||||
the current directory when it is invoked.
|
||||
- The `--dir` option for `update_deps.py` can be used to relocate the
|
||||
dependent repositories to another arbitrary directory using an absolute or
|
||||
relative path.
|
||||
- The `update_deps.py` script generates a file named `helper.cmake` and places
|
||||
it in the same directory as the dependent repositories (`build` in this
|
||||
case). This file contains CMake commands to set the CMake `*_INSTALL_DIR`
|
||||
variables that are used to point to the install artifacts of the dependent
|
||||
repositories. You can use this file with the `cmake -C` option to set these
|
||||
variables when you generate your build files with CMake. This lets you avoid
|
||||
entering several `*_INSTALL_DIR` variable settings on the CMake command line.
|
||||
it in the same directory as the dependent repositories.
|
||||
This file contains CMake commands to set the CMake `*_INSTALL_DIR` variables
|
||||
that are used to point to the install artifacts of the dependent repositories.
|
||||
The `-C helper.cmake` option is used to set these variables when you generate
|
||||
the build files.
|
||||
- If using "MINGW" (Git For Windows), you may wish to run
|
||||
`winpty update_deps.py` in order to avoid buffering all of the script's
|
||||
"print" output until the end and to retain the ability to interrupt script
|
||||
@ -169,69 +206,56 @@ run the update deps script followed by the necessary CMake build commands:
|
||||
- Please use `update_deps.py --help` to list additional options and read the
|
||||
internal documentation in `update_deps.py` for further information.
|
||||
|
||||
|
||||
#### Automatically
|
||||
|
||||
On the other hand, if you choose to let the CMake scripts do all the
|
||||
heavy-lifting, you may just trigger the following CMake commands:
|
||||
|
||||
```
|
||||
cmake -S. -Bbuild -DUPDATE_DEPS=On
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
##### Notes About the Automatic Option
|
||||
|
||||
- You may need to adjust some of the CMake options based on your platform. See
|
||||
the platform-specific sections later in this document.
|
||||
- The `build` directory is also being used to build this
|
||||
(Vulkan-ValidationLayers) repository. But there shouldn't be any conflicts
|
||||
inside the `build` directory between the dependent repositories and the
|
||||
build files for this repository.
|
||||
|
||||
|
||||
### Generated source code
|
||||
|
||||
This repository contains generated source code in the `loader/generated`
|
||||
directory which is not intended to be modified directly. Instead, changes should be
|
||||
made to the corresponding generator in the `scripts` directory. The source files can
|
||||
then be regenerated using `scripts/generate_source.py`:
|
||||
directory which is not intended to be modified directly.
|
||||
Instead, changes should be made to the corresponding generator in the `scripts` directory.
|
||||
The source files can then be regenerated using `scripts/generate_source.py`.
|
||||
|
||||
python3 scripts/generate_source.py PATH_TO_VULKAN_HEADERS_REGISTRY_DIR
|
||||
Run `python scripts/generate_source.py --help` to see how to invoke it.
|
||||
|
||||
A helper CMake target `VulkanLoader_generated_source` is also provided to simplify
|
||||
the invocation of `scripts/generate_source.py` from the build directory:
|
||||
A helper CMake target `loader_codegen` is also provided to simplify the invocation of `scripts/generate_source.py`.
|
||||
|
||||
cmake --build . --target VulkanLoader_generated_source
|
||||
Note: By default this helper target is disabled. To enable it, add `-D LOADER_CODEGEN=ON`
|
||||
to CMake, as shown below.
|
||||
|
||||
```
|
||||
cmake -S . -B build -D LOADER_CODEGEN=ON
|
||||
cmake --build . --target loader_codegen
|
||||
```
|
||||
|
||||
### Build Options
|
||||
|
||||
When generating native platform build files through CMake, several options can
|
||||
be specified to customize the build. Some of the options are binary on/off
|
||||
options, while others take a string as input. The following is a table of all
|
||||
on/off options currently supported by this repository:
|
||||
When generating build files through CMake, several options can be specified to
|
||||
customize the build.
|
||||
The following is a table of all on/off options currently supported by this repository:
|
||||
|
||||
| Option | Platform | Default | Description |
|
||||
| ------------------------------- | ------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BUILD_TESTS | All | `OFF` | Controls whether or not the loader tests are built. |
|
||||
| BUILD_WSI_XCB_SUPPORT | Linux | `ON` | Build the loader with the XCB entry points enabled. Without this, the XCB headers should not be needed, but the extension `VK_KHR_xcb_surface` won't be available. |
|
||||
| BUILD_WSI_XLIB_SUPPORT | Linux | `ON` | Build the loader with the Xlib entry points enabled. Without this, the X11 headers should not be needed, but the extension `VK_KHR_xlib_surface` won't be available. |
|
||||
| BUILD_WSI_WAYLAND_SUPPORT | Linux | `ON` | Build the loader with the Wayland entry points enabled. Without this, the Wayland headers should not be needed, but the extension `VK_KHR_wayland_surface` won't be available. |
|
||||
| BUILD_WSI_DIRECTFB_SUPPORT | Linux | `OFF` | Build the loader with the DirectFB entry points enabled. Without this, the DirectFB headers should not be needed, but the extension `VK_EXT_directfb_surface` won't be available. |
|
||||
| BUILD_WSI_SCREEN_QNX_SUPPORT | QNX | `OFF` | Build the loader with the QNX Screen entry points enabled. Without this the extension `VK_QNX_screen_surface` won't be available. |
|
||||
| ENABLE_WIN10_ONECORE | Windows | `OFF` | Link the loader to the [OneCore](https://msdn.microsoft.com/en-us/library/windows/desktop/mt654039.aspx) umbrella library, instead of the standard Win32 ones. |
|
||||
| USE_GAS | Linux | `ON` | Controls whether to build assembly files with the GNU assembler, else fallback to C code. |
|
||||
| USE_MASM | Windows | `ON` | Controls whether to build assembly files with MS assembler, else fallback to C code |
|
||||
| LOADER_ENABLE_ADDRESS_SANITIZER | Linux & macOS | `OFF` | Enables Address Sanitizer in the loader and tests. |
|
||||
| LOADER_ENABLE_THREAD_SANITIZER | Linux & macOS | `OFF` | Enables Thread Sanitizer in the loader and tests. |
|
||||
| LOADER_USE_UNSAFE_FILE_SEARCH | All | `OFF` | Disables security policies that prevent unsecure locations from being used when running with elevated permissions. |
|
||||
| LOADER_CODEGEN | All | `OFF` | Creates a helper CMake target to generate code. |
|
||||
|
||||
NOTE: `LOADER_USE_UNSAFE_FILE_SEARCH` should NOT be enabled except in very specific contexts (like isolated test environments)!
|
||||
|
||||
| Option | Platform | Default | Description |
|
||||
| ---------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BUILD_TESTS | All | `OFF` | Controls whether or not the loader tests are built. |
|
||||
| BUILD_WSI_XCB_SUPPORT | Linux | `ON` | Build the loader with the XCB entry points enabled. Without this, the XCB headers should not be needed, but the extension `VK_KHR_xcb_surface` won't be available. |
|
||||
| BUILD_WSI_XLIB_SUPPORT | Linux | `ON` | Build the loader with the Xlib entry points enabled. Without this, the X11 headers should not be needed, but the extension `VK_KHR_xlib_surface` won't be available. |
|
||||
| BUILD_WSI_WAYLAND_SUPPORT | Linux | `ON` | Build the loader with the Wayland entry points enabled. Without this, the Wayland headers should not be needed, but the extension `VK_KHR_wayland_surface` won't be available. |
|
||||
| BUILD_WSI_DIRECTFB_SUPPORT | Linux | `OFF` | Build the loader with the DirectFB entry points enabled. Without this, the DirectFB headers should not be needed, but the extension `VK_EXT_directfb_surface` won't be available. |
|
||||
| BUILD_WSI_SCREEN_QNX_SUPPORT | QNX | `OFF` | Build the loader with the QNX Screen entry points enabled. Without this the extension `VK_QNX_screen_surface` won't be available. |
|
||||
| ENABLE_WIN10_ONECORE | Windows | `OFF` | Link the loader to the [OneCore](https://msdn.microsoft.com/en-us/library/windows/desktop/mt654039.aspx) umbrella library, instead of the standard Win32 ones. |
|
||||
| USE_CCACHE | Linux | `OFF` | Enable caching with the CCache program. |
|
||||
| USE_GAS | Linux | `ON` | Controls whether to build assembly files with the GNU assembler, else fallback to C code. |
|
||||
| USE_MASM | Windows | `ON` | Controls whether to build assembly files with MS assembler, else fallback to C code |
|
||||
| BUILD_STATIC_LOADER | macOS | `OFF` | This allows the loader to be built as a static library on macOS. Not tested, use at your own risk. |
|
||||
The following is a table of all string options currently supported by this repository:
|
||||
|
||||
| Option | Platform | Default | Description |
|
||||
| --------------------------- | ----------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| CMAKE_OSX_DEPLOYMENT_TARGET | MacOS | `10.12` | The minimum version of MacOS for loader deployment. |
|
||||
| FALLBACK_CONFIG_DIRS | Linux/MacOS | `/etc/xdg` | Configuration path(s) to use instead of `XDG_CONFIG_DIRS` if that environment variable is unavailable. The default setting is freedesktop compliant. |
|
||||
| FALLBACK_DATA_DIRS | Linux/MacOS | `/usr/local/share:/usr/share` | Configuration path(s) to use instead of `XDG_DATA_DIRS` if that environment variable is unavailable. The default setting is freedesktop compliant. |
|
||||
| BUILD_DLL_VERSIONINFO | Windows | `""` (empty string) | Allows setting the Windows specific version information for the Loader DLL. Format is "major.minor.patch.build". |
|
||||
| Option | Platform | Default | Description |
|
||||
| --------------------- | ----------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| FALLBACK_CONFIG_DIRS | Linux/MacOS | `/etc/xdg` | Configuration path(s) to use instead of `XDG_CONFIG_DIRS` if that environment variable is unavailable. The default setting is freedesktop compliant. |
|
||||
| FALLBACK_DATA_DIRS | Linux/MacOS | `/usr/local/share:/usr/share` | Configuration path(s) to use instead of `XDG_DATA_DIRS` if that environment variable is unavailable. The default setting is freedesktop compliant. |
|
||||
| BUILD_DLL_VERSIONINFO | Windows | `""` (empty string) | Allows setting the Windows specific version information for the Loader DLL. Format is "major.minor.patch.build". |
|
||||
|
||||
These variables should be set using the `-D` option when invoking CMake to generate the native platform files.
|
||||
|
||||
@ -243,12 +267,11 @@ These variables should be set using the `-D` option when invoking CMake to gener
|
||||
- Any Personal Computer version supported by Microsoft
|
||||
- Microsoft [Visual Studio](https://www.visualstudio.com/)
|
||||
- Versions
|
||||
- [2015](https://www.visualstudio.com/vs/older-downloads/)
|
||||
- [2017](https://www.visualstudio.com/vs/older-downloads/)
|
||||
- [2019](https://www.visualstudio.com/vs/downloads/)
|
||||
- [2022](https://www.visualstudio.com/vs/downloads/)
|
||||
- [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.10.2](https://cmake.org/files/v3.10/cmake-3.10.2-win64-x64.zip) is recommended.
|
||||
- [CMake 3.17.2](https://cmake.org/files/v3.17/cmake-3.17.2-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
|
||||
@ -271,7 +294,7 @@ Open a developer command prompt and enter:
|
||||
cd Vulkan-Loader
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -A x64 -DVULKAN_HEADERS_INSTALL_DIR=absolute_path_to_install_dir ..
|
||||
cmake -A x64 -D UPDATE_DEPS=ON ..
|
||||
cmake --build .
|
||||
|
||||
The above commands instruct CMake to find and use the default Visual Studio
|
||||
@ -279,10 +302,6 @@ installation to generate a Visual Studio solution and projects for the x64
|
||||
architecture. The second CMake command builds the Debug (default)
|
||||
configuration of the solution.
|
||||
|
||||
Note that if you do not wish to use a developer command prompt, you may either
|
||||
run either `vcvars64.bat` or `vcvars32.bat` to set the required environment
|
||||
variables.
|
||||
|
||||
#### Use `CMake` to Create the Visual Studio Project Files
|
||||
|
||||
Change your current directory to the top of the cloned repository directory,
|
||||
@ -291,26 +310,24 @@ create a build directory and generate the Visual Studio project files:
|
||||
cd Vulkan-Loader
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -A x64 -DVULKAN_HEADERS_INSTALL_DIR=absolute_path_to_install_dir ..
|
||||
cmake -D UPDATE_DEPS=ON -G "Visual Studio 16 2019" -A x64 ..
|
||||
|
||||
> Note: The `..` parameter tells `cmake` the location of the top of the
|
||||
> repository. If you place your build directory someplace else, you'll need to
|
||||
> specify the location of the repository top differently.
|
||||
> specify the location of the repository differently.
|
||||
|
||||
The `-A` option is used to select either the "Win32" or "x64" architecture.
|
||||
The `-G` option is used to select the generator
|
||||
|
||||
If a generator for a specific version of Visual Studio is required, you can
|
||||
specify it for Visual Studio 2015, for example, with:
|
||||
Supported Visual Studio generators:
|
||||
* `Visual Studio 17 2022`
|
||||
* `Visual Studio 16 2019`
|
||||
|
||||
64-bit: -G "Visual Studio 14 2015 Win64"
|
||||
32-bit: -G "Visual Studio 14 2015"
|
||||
|
||||
See this [list](#cmake-visual-studio-generators) of other possible generators
|
||||
for Visual Studio.
|
||||
The `-A` option is used to select either the "Win32", "x64", or "ARM64 architecture.
|
||||
|
||||
When generating the project files, the absolute path to a Vulkan-Headers
|
||||
install directory must be provided. This can be done by setting the
|
||||
`VULKAN_HEADERS_INSTALL_DIR` environment variable or by setting the
|
||||
install directory must be provided. This can be done automatically by the
|
||||
`-D UPDATE_DEPS=ON` option, by directly setting the
|
||||
`VULKAN_HEADERS_INSTALL_DIR` environment variable, or by setting the
|
||||
`VULKAN_HEADERS_INSTALL_DIR` CMake variable with the `-D` CMake option. In
|
||||
either case, the variable should point to the installation directory of a
|
||||
Vulkan-Headers repository built with the install target.
|
||||
@ -347,8 +364,8 @@ the primary build artifacts to a specific location using a "bin, include, lib"
|
||||
style directory structure. This may be useful for collecting the artifacts and
|
||||
providing them to another project that is dependent on them.
|
||||
|
||||
The default location is `$CMAKE_BINARY_DIR\install`, but can be changed with
|
||||
the `CMAKE_INSTALL_PREFIX` variable when first generating the project build
|
||||
The default location is `$CMAKE_CURRENT_BINARY_DIR\install`, but can be changed
|
||||
with the `CMAKE_INSTALL_PREFIX` variable when first generating the project build
|
||||
files with CMake.
|
||||
|
||||
You can build the install target from the command line with:
|
||||
@ -357,81 +374,15 @@ You can build the install target from the command line with:
|
||||
|
||||
or build the `INSTALL` target from the Visual Studio solution explorer.
|
||||
|
||||
### Windows Tests
|
||||
|
||||
The Vulkan-Loader repository contains some simple unit tests for the loader
|
||||
but no other test clients.
|
||||
|
||||
To run the loader test script, open a Powershell Console, change to the
|
||||
`build\tests` directory, and run:
|
||||
|
||||
For Release builds:
|
||||
|
||||
.\run_all_tests.ps1
|
||||
|
||||
For Debug builds:
|
||||
|
||||
.\run_all_tests.ps1 -Debug
|
||||
|
||||
This script will run the following tests:
|
||||
|
||||
- `vk_loader_validation_tests`:
|
||||
Vulkan loader handle wrapping, allocation callback, and loader/layer interface tests
|
||||
|
||||
You can also change to either `build\tests\Debug` or `build\tests\Release`
|
||||
(depending on which one you built) and run the executable tests (`*.exe`)
|
||||
files from there.
|
||||
|
||||
### Windows Notes
|
||||
|
||||
#### CMake Visual Studio Generators
|
||||
|
||||
The chosen generator should match one of the Visual Studio versions that you
|
||||
have installed. Generator strings that correspond to versions of Visual Studio
|
||||
include:
|
||||
|
||||
| Build Platform | 64-bit Generator | 32-bit Generator |
|
||||
| ---------------------------- | ----------------------------- | ----------------------- |
|
||||
| Microsoft Visual Studio 2015 | "Visual Studio 14 2015 Win64" | "Visual Studio 14 2015" |
|
||||
| Microsoft Visual Studio 2017 | "Visual Studio 15 2017 Win64" | "Visual Studio 15 2017" |
|
||||
| Microsoft Visual Studio 2019 | "Visual Studio 16 2019" | "Visual Studio 16 2019" |
|
||||
|
||||
Note that with Visual Studio 2019, the architecture will need to be specified with the `-A`
|
||||
flag for 64-bit builds.
|
||||
|
||||
#### Using The Vulkan Loader Library in this Repository on Windows
|
||||
|
||||
Vulkan programs must be able to find and use the Vulkan loader
|
||||
(`vulkan-1.dll`) library as well as any other libraries the program requires.
|
||||
One convenient way to do this is to copy the required libraries into the same
|
||||
directory as the program. The projects in this solution copy the Vulkan loader
|
||||
library and the "googletest" libraries to the `build\tests\Debug` or the
|
||||
`build\tests\Release` directory, which is where the
|
||||
`vk_loader_validation_test.exe` executable is found, depending on what
|
||||
configuration you built. (The loader validation tests use the "googletest"
|
||||
testing framework.)
|
||||
|
||||
Other techniques include placing the library in a system folder
|
||||
(C:\Windows\System32) or in a directory that appears in the `PATH` environment
|
||||
variable.
|
||||
|
||||
See the `LoaderAndLayerInterface` document in the `loader` folder in this
|
||||
repository for more information on how the loader finds driver libraries and
|
||||
layer libraries. The document also describes both how ICDs and layers should
|
||||
be packaged, and how developers can point to ICDs and layers within their
|
||||
builds.
|
||||
|
||||
## Building On Linux
|
||||
|
||||
### Linux Development Environment Requirements
|
||||
|
||||
This repository has been built and tested on the two most recent Ubuntu LTS
|
||||
versions. Currently, the oldest supported version is Ubuntu 16.04, meaning
|
||||
that the minimum officially supported C++11 compiler version is GCC 5.4.0,
|
||||
although earlier versions may work. It should be straightforward to adapt this
|
||||
repository to other Linux distributions.
|
||||
versions, although earlier versions may work.
|
||||
It is be straightforward to adapt this repository to other Linux distributions.
|
||||
|
||||
[CMake 3.10.2](https://cmake.org/files/v3.10/cmake-3.10.2-Linux-x86_64.tar.gz) is recommended.
|
||||
[CMake 3.17.2](https://cmake.org/files/v3.17/cmake-3.17.2-Linux-x86_64.tar.gz) is recommended.
|
||||
|
||||
#### Required Package List
|
||||
|
||||
@ -448,7 +399,7 @@ CMake with the `--build` option or `make` to build from the command line.
|
||||
cd Vulkan-Loader
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DVULKAN_HEADERS_INSTALL_DIR=absolute_path_to_install_dir ..
|
||||
cmake -D UPDATE_DEPS=ON ..
|
||||
make
|
||||
|
||||
See below for the details.
|
||||
@ -461,21 +412,22 @@ create a build directory and generate the make files.
|
||||
cd Vulkan-Loader
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug \
|
||||
-DVULKAN_HEADERS_INSTALL_DIR=absolute_path_to_install_dir \
|
||||
-DCMAKE_INSTALL_PREFIX=install ..
|
||||
cmake -D CMAKE_BUILD_TYPE=Debug \
|
||||
-D VULKAN_HEADERS_INSTALL_DIR=absolute_path_to_install_dir \
|
||||
-D CMAKE_INSTALL_PREFIX=install ..
|
||||
|
||||
> Note: The `..` parameter tells `cmake` the location of the top of the
|
||||
> repository. If you place your `build` directory someplace else, you'll need
|
||||
> to specify the location of the repository top differently.
|
||||
|
||||
Use `-DCMAKE_BUILD_TYPE` to specify a Debug or Release build.
|
||||
Use `-D CMAKE_BUILD_TYPE` to specify a Debug or Release build.
|
||||
|
||||
When generating the project files, the absolute path to a Vulkan-Headers
|
||||
install directory must be provided. This can be done by setting the
|
||||
`VULKAN_HEADERS_INSTALL_DIR` environment variable or by setting the
|
||||
`VULKAN_HEADERS_INSTALL_DIR` CMake variable with the `-D` CMake option. In
|
||||
either case, the variable should point to the installation directory of a
|
||||
install directory must be provided. This can be done automatically by the
|
||||
`-D UPDATE_DEPS=ON` option, by directly setting the `VULKAN_HEADERS_INSTALL_DIR`
|
||||
environment variable, or by setting the `VULKAN_HEADERS_INSTALL_DIR` CMake
|
||||
variable with the `-D` CMake option.
|
||||
In either case, the variable should point to the installation directory of a
|
||||
Vulkan-Headers repository built with the install target.
|
||||
|
||||
> Note: For Linux, the default value for `CMAKE_INSTALL_PREFIX` is
|
||||
@ -496,25 +448,8 @@ You can also use
|
||||
|
||||
cmake --build .
|
||||
|
||||
If your build system supports ccache, you can enable that via CMake option
|
||||
`-DUSE_CCACHE=On`
|
||||
|
||||
### Linux Notes
|
||||
|
||||
#### Using The Vulkan Loader Library in this Repository on Linux
|
||||
|
||||
The `vk_loader_validation_tests` executable is linked with an RPATH setting to
|
||||
allow it to find the Vulkan loader library in the repository's build
|
||||
directory. This allows the test executable to run and find this Vulkan loader
|
||||
library without installing the loader library to a directory searched by the
|
||||
system loader or in the `LD_LIBRARY_PATH`.
|
||||
|
||||
If you want to test a Vulkan application that is not built within this
|
||||
repository with the loader you just built from this repository, you can direct
|
||||
the application to load it from your build directory:
|
||||
|
||||
export LD_LIBRARY_PATH=<path to your repository root>/build/loader
|
||||
|
||||
#### WSI Support Build Options
|
||||
|
||||
By default, the Vulkan Loader is built with support for the Vulkan-defined WSI
|
||||
@ -550,7 +485,7 @@ CMake variables to override their defaults. For example, if you would like to
|
||||
install to `/tmp/build` instead of `/usr/local`, on your CMake command line
|
||||
specify:
|
||||
|
||||
-DCMAKE_INSTALL_PREFIX=/tmp/build
|
||||
-D CMAKE_INSTALL_PREFIX=/tmp/build
|
||||
|
||||
Then run `make install` as before. The install step places the files in
|
||||
`/tmp/build`. This may be useful for collecting the artifacts and providing
|
||||
@ -573,76 +508,43 @@ variables `CMAKE_INSTALL_SYSCONFDIR` to rename the `etc` directory and
|
||||
See the CMake documentation for more details on using these variables to
|
||||
further customize your installation.
|
||||
|
||||
Also see the `LoaderAndLayerInterface` document in the `loader` folder in this
|
||||
Also see the `LoaderInterfaceArchitecture.md` document in the `docs` folder in this
|
||||
repository for more information about loader operation.
|
||||
|
||||
Note that some executables in this repository (e.g.,
|
||||
`vk_loader_validation_tests`) use the RPATH linker directive to load the
|
||||
Vulkan loader from the build directory, `build` in this example. This means
|
||||
that even after installing the loader to the system directories, these
|
||||
executables still use the loader from the build directory.
|
||||
|
||||
#### Linux Uninstall
|
||||
|
||||
To uninstall the files from the system directories, you can execute:
|
||||
|
||||
sudo make uninstall
|
||||
|
||||
#### Linux Tests
|
||||
|
||||
The Vulkan-Loader repository contains some simple unit tests for the loader
|
||||
but no other test clients.
|
||||
|
||||
To run the loader test script, change to the `build/tests` directory, and run:
|
||||
|
||||
./run_all_tests.sh
|
||||
|
||||
This script will run the following tests:
|
||||
|
||||
- `vk_loader_validation_tests`: Vulkan loader handle wrapping, allocation
|
||||
callback, and loader/layer interface tests
|
||||
|
||||
#### Linux 32-bit support
|
||||
|
||||
Usage of this repository's contents in 32-bit Linux environments is not
|
||||
officially supported. However, since this repository is supported on 32-bit
|
||||
Windows, these modules should generally work on 32-bit Linux.
|
||||
|
||||
Here are some notes for building 32-bit targets on a 64-bit Ubuntu "reference"
|
||||
platform:
|
||||
The loader supports building in 32-bit Linux environments.
|
||||
However, it is not nearly as straightforward as it is for Windows.
|
||||
Here are some notes for building this repo as 32-bit on a 64-bit Ubuntu
|
||||
"reference" platform:
|
||||
|
||||
If not already installed, install the following 32-bit development libraries:
|
||||
|
||||
`gcc-multilib g++-multilib libx11-dev:i386`
|
||||
`gcc-multilib gcc-multilib g++-multilib libc6:i386 libc6-dev-i386 libgcc-s1:i386 libwayland-dev:i386 libxrandr-dev:i386`
|
||||
|
||||
This list may vary depending on your distribution and which windowing systems
|
||||
you are building for.
|
||||
|
||||
Set up your environment for building 32-bit targets:
|
||||
|
||||
export ASFLAGS=--32
|
||||
export CFLAGS=-m32
|
||||
export CXXFLAGS=-m32
|
||||
export PKG_CONFIG_LIBDIR=/usr/lib/i386-linux-gnu
|
||||
export LDFLAGS=-m32
|
||||
export ASFLAGS=--32
|
||||
|
||||
Again, your PKG_CONFIG configuration may be different, depending on your
|
||||
distribution.
|
||||
Your PKG_CONFIG configuration may be different, depending on your distribution.
|
||||
|
||||
Finally, rebuild the repository using `cmake` and `make`, as explained above.
|
||||
Finally, build the repository normally as explained above.
|
||||
|
||||
These notes are taken from the Github Actions workflow `linux-32` which is run
|
||||
regularly as a part of CI.
|
||||
|
||||
## Building on MacOS
|
||||
|
||||
### MacOS Development Environment Requirements
|
||||
|
||||
Tested on OSX version 10.12.6
|
||||
|
||||
Setup Homebrew and components
|
||||
|
||||
- Follow instructions on [brew.sh](http://brew.sh) to get Homebrew installed.
|
||||
|
||||
/usr/bin/ruby -e "$(curl -fsSL \
|
||||
https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
|
||||
- Ensure Homebrew is at the beginning of your PATH:
|
||||
|
||||
export PATH=/usr/local/bin:$PATH
|
||||
@ -653,37 +555,29 @@ Setup Homebrew and components
|
||||
|
||||
### Clone the Repository
|
||||
|
||||
Clone the Vulkan-ValidationLayers repository:
|
||||
Clone the Vulkan-Loader repository:
|
||||
|
||||
git clone https://github.com/KhronosGroup/Vulkan-ValidationLayers.git
|
||||
git clone https://github.com/KhronosGroup/Vulkan-Loader.git
|
||||
|
||||
### MacOS build
|
||||
|
||||
[CMake 3.10.2](https://cmake.org/files/v3.10/cmake-3.10.2-Darwin-x86_64.tar.gz) is recommended.
|
||||
|
||||
#### CMake Generators
|
||||
|
||||
This repository uses CMake to generate build or project files that are then
|
||||
used to build the repository. The CMake generators explicitly supported in
|
||||
this repository are:
|
||||
|
||||
- Unix Makefiles
|
||||
- Xcode
|
||||
[CMake 3.17.2](https://cmake.org/files/v3.17/cmake-3.17.2-Darwin-x86_64.tar.gz) is recommended.
|
||||
|
||||
#### Building with the Unix Makefiles Generator
|
||||
|
||||
This generator is the default generator.
|
||||
|
||||
When generating the project files, the absolute path to a Vulkan-Headers
|
||||
install directory must be provided. This can be done by setting the
|
||||
`VULKAN_HEADERS_INSTALL_DIR` environment variable or by setting the
|
||||
install directory must be provided. This can be done automatically by the
|
||||
`-D UPDATE_DEPS=ON` option, by directly setting the
|
||||
`VULKAN_HEADERS_INSTALL_DIR` environment variable, or by setting the
|
||||
`VULKAN_HEADERS_INSTALL_DIR` CMake variable with the `-D` CMake option. In
|
||||
either case, the variable should point to the installation directory of a
|
||||
Vulkan-Headers repository built with the install target.
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DVULKAN_HEADERS_INSTALL_DIR=absolute_path_to_install_dir -DCMAKE_BUILD_TYPE=Debug ..
|
||||
cmake -D UPDATE_DEPS=ON -D VULKAN_HEADERS_INSTALL_DIR=absolute_path_to_install_dir -D CMAKE_BUILD_TYPE=Debug ..
|
||||
make
|
||||
|
||||
To speed up the build on a multi-core machine, use the `-j` option for `make`
|
||||
@ -703,44 +597,59 @@ To create and open an Xcode project:
|
||||
Within Xcode, you can select Debug or Release builds in the project's Build
|
||||
Settings.
|
||||
|
||||
### Using the new macOS loader
|
||||
|
||||
If you want to test a Vulkan application with the loader you just built, you
|
||||
can direct the application to load it from your build directory:
|
||||
|
||||
export DYLD_LIBRARY_PATH=<path to your repository>/build/loader
|
||||
|
||||
### MacOS Tests
|
||||
|
||||
The Vulkan-Loader repository contains some simple unit tests for the loader
|
||||
but no other test clients.
|
||||
|
||||
Before you run these tests, you will need to clone and build the
|
||||
[MoltenVK](https://github.com/KhronosGroup/MoltenVK) repository.
|
||||
|
||||
You will also need to direct your new loader to the MoltenVK ICD:
|
||||
|
||||
export VK_DRIVER_FILES=<path to MoltenVK repository>/Package/Latest/MoltenVK/macOS/MoltenVK_icd.json
|
||||
|
||||
To run the loader test script, change to the `build/tests` directory in your
|
||||
Vulkan-Loader repository, and run:
|
||||
|
||||
./vk_loader_validation_tests
|
||||
|
||||
## Building on Fuchsia
|
||||
|
||||
Fuchsia uses the project's GN build system to integrate with the Fuchsia platform build.
|
||||
|
||||
### SDK Symbols
|
||||
|
||||
The Vulkan Loader is a component of the Fuchsia SDK, so it must explicitly declare its exported symbols in
|
||||
the file vulkan.symbols.api; see [SDK](https://fuchsia.dev/fuchsia-src/development/sdk).
|
||||
|
||||
## Building on QNX
|
||||
|
||||
QNX is using its own build system. The proper build environment must be set
|
||||
under the QNX host development system (Linux, Win64, MacOS) by invoking
|
||||
the shell/batch script provided with QNX installation.
|
||||
|
||||
Then change working directory to the "build-qnx" in this project and type "make".
|
||||
Then change working directory to the "scripts/qnx" in this project and type "make".
|
||||
It will build the ICD loader for all CPU targets supported by QNX.
|
||||
|
||||
### SDK Symbols
|
||||
## Cross Compilation
|
||||
|
||||
The Vulkan Loader is a component of the Fuchsia SDK, so it must explicitly declare its exported symbols in
|
||||
the file vulkan.symbols.api; see [SDK](https://fuchsia.dev/fuchsia-src/development/sdk).
|
||||
While this repo is capable of cross compilation, there are a handful of caveats.
|
||||
|
||||
### Unknown function handling which requires explicit assembly implementations
|
||||
|
||||
Unknown function handling is only fully supported on select platforms due to the
|
||||
need for assembly in the implementation.
|
||||
Platforms not fully supported will have assembly disabled automatically, or
|
||||
can be manually disabled by setting `USE_GAS` or `USE_MASM` to `OFF`.
|
||||
|
||||
#### Platforms which fully support unknown function handling
|
||||
|
||||
* 64 bit Windows (x64)
|
||||
* 32 bit Windows (x86)
|
||||
* 64 bit Linux (x64)
|
||||
* 32 bit Linux (x86)
|
||||
* 64 bit Arm (aarch64)
|
||||
|
||||
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
|
||||
the command line, this looks like `-D BUILD_TESTS=ON`.
|
||||
|
||||
This project is configured to run with `ctest`, which makes it easy to run the
|
||||
tests. To run the tests, change the directory to that of the build direction, and
|
||||
execute `ctest`.
|
||||
|
||||
More details can be found in the [README.md](./tests/README.md) for the tests
|
||||
directory of this project.
|
||||
|
445
CMakeLists.txt
445
CMakeLists.txt
@ -1,6 +1,8 @@
|
||||
# ~~~
|
||||
# Copyright (c) 2014-2022 Valve Corporation
|
||||
# Copyright (c) 2014-2022 LunarG, Inc.
|
||||
# Copyright (c) 2014-2023 Valve Corporation
|
||||
# Copyright (c) 2014-2023 LunarG, Inc.
|
||||
# Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# Copyright (c) 2023-2023 RasterGrid Kft.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -14,89 +16,27 @@
|
||||
# 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.10.2)
|
||||
project(VULKAN_LOADER VERSION 1.3.275 LANGUAGES C)
|
||||
|
||||
# Apple: Must be set before enable_language() or project() as it may influence configuration of the toolchain and flags.
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.12" CACHE STRING "Minimum OS X deployment version")
|
||||
# This variable enables downstream users to customize the target API
|
||||
# variant (e.g. Vulkan SC)
|
||||
set(API_TYPE "vulkan")
|
||||
|
||||
# If we are building in Visual Studio 2015 and with a CMake version 3.19 or greater, we need to set this variable
|
||||
# so that CMake will choose a Windows SDK version higher than 10.0.14393.0, as dxgi1_6.h is only found in Windows SDK
|
||||
# 10.0.17763 and higher.
|
||||
set(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM OFF)
|
||||
add_subdirectory(scripts)
|
||||
|
||||
project(Vulkan-Loader)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
set(CMAKE_C_VISIBILITY_PRESET "hidden")
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
if (UPDATE_DEPS)
|
||||
find_package(PythonInterp 3 REQUIRED)
|
||||
|
||||
if (CMAKE_GENERATOR_PLATFORM)
|
||||
set(_target_arch ${CMAKE_GENERATOR_PLATFORM})
|
||||
else()
|
||||
if (MSVC_IDE)
|
||||
message(WARNING "CMAKE_GENERATOR_PLATFORM not set. Using x64 as target architecture.")
|
||||
endif()
|
||||
set(_target_arch x64)
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
message(WARNING "CMAKE_BUILD_TYPE not set. Using Debug for dependency build type")
|
||||
set(_build_type Debug)
|
||||
else()
|
||||
set(_build_type ${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
|
||||
set(_build_tests_arg "")
|
||||
if (NOT BUILD_TESTS)
|
||||
set(_build_tests_arg "--optional=tests")
|
||||
endif()
|
||||
|
||||
message("********************************************************************************")
|
||||
message("* NOTE: Adding target vl_update_deps to run as needed for updating *")
|
||||
message("* dependencies. *")
|
||||
message("********************************************************************************")
|
||||
|
||||
# Add a target so that update_deps.py will run when necessary
|
||||
# NOTE: This is triggered off of the timestamps of known_good.json and helper.cmake
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_LIST_DIR}/external/helper.cmake
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/scripts/update_deps.py --dir ${CMAKE_CURRENT_LIST_DIR}/external --arch ${_target_arch} --config ${_build_type} --generator "${CMAKE_GENERATOR}" ${_build_tests_arg}
|
||||
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/scripts/known_good.json)
|
||||
|
||||
add_custom_target(vl_update_deps DEPENDS ${CMAKE_CURRENT_LIST_DIR}/external/helper.cmake)
|
||||
|
||||
# Check if update_deps.py needs to be run on first cmake run
|
||||
if (${CMAKE_CURRENT_LIST_DIR}/scripts/known_good.json IS_NEWER_THAN ${CMAKE_CURRENT_LIST_DIR}/external/helper.cmake)
|
||||
execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/scripts/update_deps.py --dir ${CMAKE_CURRENT_LIST_DIR}/external --arch ${_target_arch} --config ${_build_type} --generator "${CMAKE_GENERATOR}" ${_build_tests_arg}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
RESULT_VARIABLE _update_deps_result
|
||||
)
|
||||
if (NOT (${_update_deps_result} EQUAL 0))
|
||||
message(FATAL_ERROR "Could not run update_deps.py which is necessary to download dependencies.")
|
||||
endif()
|
||||
endif()
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/external/helper.cmake)
|
||||
else()
|
||||
message("********************************************************************************")
|
||||
message("* NOTE: Not adding target to run update_deps.py automatically. *")
|
||||
message("********************************************************************************")
|
||||
find_package(PythonInterp 3 QUIET)
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
find_package(PythonInterp 3 QUIET)
|
||||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
option(BUILD_TESTS "Build Tests" OFF)
|
||||
|
||||
if(BUILD_TESTS)
|
||||
enable_testing()
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
option(BUILD_STATIC_LOADER "Build a loader that can be statically linked" OFF)
|
||||
# By default, loader & tests are built without sanitizers
|
||||
# Use these options to force a specific sanitizer on the loader and test executables
|
||||
if (UNIX)
|
||||
option(LOADER_ENABLE_ADDRESS_SANITIZER "Linux & macOS only: Advanced memory checking" OFF)
|
||||
option(LOADER_ENABLE_THREAD_SANITIZER "Linux & macOS only: Advanced thread checking" OFF)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
@ -105,51 +45,10 @@ if(WIN32)
|
||||
set(BUILD_DLL_VERSIONINFO "" CACHE STRING "Set the version to be used in the loader.rc file. Default value is the currently generated header version")
|
||||
endif()
|
||||
|
||||
if(BUILD_STATIC_LOADER)
|
||||
message(WARNING "The BUILD_STATIC_LOADER option has been set. Note that this will only work on MacOS and is not supported "
|
||||
"or tested as part of the loader. Use it at your own risk.")
|
||||
endif()
|
||||
|
||||
if (TARGET Vulkan::Headers)
|
||||
message(STATUS "Using Vulkan headers from Vulkan::Headers target")
|
||||
get_target_property(VulkanHeaders_INCLUDE_DIRS Vulkan::Headers INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_target_property(VulkanRegistry_DIR Vulkan::Registry INTERFACE_INCLUDE_DIRECTORIES)
|
||||
else()
|
||||
find_package(VulkanHeaders)
|
||||
if(NOT ${VulkanHeaders_FOUND})
|
||||
message(FATAL_ERROR "Could not find Vulkan headers path. This can be fixed by setting VULKAN_HEADERS_INSTALL_DIR to an "
|
||||
"installation of the Vulkan-Headers repository.")
|
||||
endif()
|
||||
if(NOT ${VulkanRegistry_FOUND})
|
||||
message(FATAL_ERROR "Could not find Vulkan registry path. This can be fixed by setting VULKAN_HEADERS_INSTALL_DIR to an "
|
||||
"installation of the Vulkan-Headers repository.")
|
||||
endif()
|
||||
|
||||
# set up the Vulkan::Headers target for consistency
|
||||
add_library(vulkan-headers INTERFACE)
|
||||
target_include_directories(vulkan-headers SYSTEM INTERFACE "${VulkanHeaders_INCLUDE_DIRS}")
|
||||
add_library(Vulkan::Headers ALIAS vulkan-headers)
|
||||
endif()
|
||||
|
||||
option(USE_CCACHE "Use ccache" OFF)
|
||||
if(USE_CCACHE)
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
||||
endif()
|
||||
endif()
|
||||
find_package(VulkanHeaders CONFIG QUIET)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(UNIX AND NOT APPLE) # i.e.: Linux
|
||||
include(FindPkgConfig)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
# CMake versions 3 or later need CMAKE_MACOSX_RPATH defined. This avoids the CMP0042 policy message.
|
||||
set(CMAKE_MACOSX_RPATH 1)
|
||||
endif()
|
||||
|
||||
set(GIT_BRANCH_NAME "--unknown--")
|
||||
set(GIT_TAG_INFO "--unknown--")
|
||||
find_package (Git)
|
||||
@ -172,11 +71,6 @@ if (GIT_FOUND AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/.git/HEAD")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32 AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
# Windows: if install locations not set by user, set install prefix to "<build_dir>\install".
|
||||
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "default install path" FORCE)
|
||||
endif()
|
||||
|
||||
# Enable IDE GUI folders. "Helper targets" that don't have interesting source code should set their FOLDER property to this
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
set(LOADER_HELPER_FOLDER "Helper Targets")
|
||||
@ -190,145 +84,104 @@ if(UNIX)
|
||||
"System-wide search directory. If not set or empty, CMAKE_INSTALL_FULL_SYSCONFDIR and /etc are used.")
|
||||
endif()
|
||||
|
||||
# Because we use CMake 3.10.2, we can't use the policy which would disable adding /W3 by default. In the interim, replace the flags
|
||||
# When this project is updated to 3.15 and above, use the following line.
|
||||
# cmake_policy(SET CMP0092 NEW)
|
||||
string(REGEX REPLACE "/W3" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
string(REGEX REPLACE "/W3" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# 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(UNIX AND NOT APPLE) # i.e.: Linux
|
||||
option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON)
|
||||
option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON)
|
||||
option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON)
|
||||
option(BUILD_WSI_DIRECTFB_SUPPORT "Build DirectFB WSI support" OFF)
|
||||
option(BUILD_WSI_SCREEN_QNX_SUPPORT "Build QNX Screen WSI support" OFF)
|
||||
|
||||
if(BUILD_WSI_XCB_SUPPORT)
|
||||
find_package(XCB REQUIRED)
|
||||
include_directories(SYSTEM ${XCB_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if(BUILD_WSI_XLIB_SUPPORT)
|
||||
find_package(X11 REQUIRED)
|
||||
endif()
|
||||
|
||||
if(BUILD_WSI_DIRECTFB_SUPPORT)
|
||||
find_package(DirectFB REQUIRED)
|
||||
include_directories(SYSTEM ${DIRECTFB_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if(BUILD_WSI_SCREEN_QNX_SUPPORT)
|
||||
# Part of OS, no additional include directories are required
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
option(ENABLE_WIN10_ONECORE "Link the loader with OneCore umbrella libraries" OFF)
|
||||
endif()
|
||||
|
||||
add_library(platform_wsi_defines INTERFACE)
|
||||
add_library(platform_wsi INTERFACE)
|
||||
if(WIN32)
|
||||
target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_WIN32_KHR)
|
||||
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_WIN32_KHR)
|
||||
elseif(ANDROID)
|
||||
target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_ANDROID_KHR)
|
||||
message(FATAL_ERROR "Android build not supported!")
|
||||
elseif(APPLE)
|
||||
target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_MACOS_MVK VK_USE_PLATFORM_METAL_EXT)
|
||||
elseif(UNIX AND NOT APPLE) # i.e.: Linux
|
||||
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_METAL_EXT)
|
||||
if (IOS)
|
||||
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_IOS_MVK)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_MACOS_MVK)
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|DragonFly|GNU")
|
||||
option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON)
|
||||
option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON)
|
||||
option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON)
|
||||
option(BUILD_WSI_DIRECTFB_SUPPORT "Build DirectFB WSI support" OFF)
|
||||
|
||||
find_package(PkgConfig REQUIRED QUIET) # Use PkgConfig to find Linux system libraries
|
||||
|
||||
if(BUILD_WSI_XCB_SUPPORT)
|
||||
target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_XCB_KHR)
|
||||
pkg_check_modules(XCB REQUIRED QUIET IMPORTED_TARGET xcb)
|
||||
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_XCB_KHR)
|
||||
target_link_libraries(platform_wsi INTERFACE PkgConfig::XCB)
|
||||
endif()
|
||||
if(BUILD_WSI_XLIB_SUPPORT)
|
||||
target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_XLIB_KHR VK_USE_PLATFORM_XLIB_XRANDR_EXT)
|
||||
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)
|
||||
endif()
|
||||
if(BUILD_WSI_WAYLAND_SUPPORT)
|
||||
target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
endif()
|
||||
if(BUILD_WSI_DIRECTFB_SUPPORT)
|
||||
target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_DIRECTFB_EXT)
|
||||
endif()
|
||||
if(BUILD_WSI_SCREEN_QNX_SUPPORT)
|
||||
target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_SCREEN_QNX)
|
||||
pkg_check_modules(DirectFB QUIET REQUIRED IMPORTED_TARGET directfb)
|
||||
target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_DIRECTFB_EXT)
|
||||
target_link_libraries(platform_wsi INTERFACE PkgConfig::DirectFB)
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "QNX")
|
||||
message(FATAL_ERROR "See BUILD.md for QNX build")
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Fuchsia")
|
||||
message(FATAL_ERROR "Fuchsia uses Chromium build. See BUILD.gn")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported Platform!")
|
||||
endif()
|
||||
|
||||
add_library(loader_common_options INTERFACE)
|
||||
target_compile_definitions(loader_common_options INTERFACE API_NAME="Vulkan")
|
||||
target_link_libraries(loader_common_options INTERFACE platform_wsi_defines)
|
||||
target_link_libraries(loader_common_options INTERFACE platform_wsi)
|
||||
|
||||
# Enable beta Vulkan extensions
|
||||
target_compile_definitions(loader_common_options INTERFACE VK_ENABLE_BETA_EXTENSIONS)
|
||||
|
||||
target_compile_features(loader_common_options INTERFACE c_std_99)
|
||||
target_compile_features(loader_common_options INTERFACE cxx_std_11)
|
||||
set(LOADER_STANDARD_C_PROPERTIES PROPERTIES C_STANDARD 99 C_STANDARD_REQUIRED YES C_EXTENSIONS OFF)
|
||||
set(LOADER_STANDARD_CXX_PROPERTIES PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS OFF)
|
||||
|
||||
option(ENABLE_WERROR "Enable warnings as errors" ON)
|
||||
option(BUILD_WERROR "Enable warnings as errors")
|
||||
|
||||
# Set warnings as errors and the main diagnostic flags
|
||||
# Must be set first so the warning silencing later on works properly
|
||||
# Note that clang-cl.exe should use MSVC flavor flags, not GNU
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" MATCHES "MSVC"))
|
||||
if (ENABLE_WERROR)
|
||||
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)
|
||||
endif()
|
||||
target_compile_options(loader_common_options INTERFACE /W4)
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
|
||||
# using GCC or Clang with the regular front end
|
||||
if (ENABLE_WERROR)
|
||||
if (BUILD_WERROR)
|
||||
target_compile_options(loader_common_options INTERFACE -Werror)
|
||||
endif()
|
||||
target_compile_options(loader_common_options INTERFACE -Wall -Wextra)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
target_compile_options(loader_common_options INTERFACE -Wno-unused-parameter -Wno-unused-function -Wno-missing-field-initializers)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
|
||||
target_compile_options(loader_common_options INTERFACE -Wno-missing-field-initializers)
|
||||
|
||||
# need to prepend /clang: to compiler arguments when using clang-cl
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" MATCHES "MSVC")
|
||||
target_compile_options(loader_common_options INTERFACE /clang:-fno-strict-aliasing /clang:-fno-builtin-memcmp)
|
||||
else()
|
||||
target_compile_options(loader_common_options INTERFACE -fno-strict-aliasing -fno-builtin-memcmp)
|
||||
endif()
|
||||
|
||||
# For GCC version 7.1 or greater, we need to disable the implicit fallthrough warning since there's no consistent way to satisfy
|
||||
# all compilers until they all accept the C++17 standard
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
target_compile_options(loader_common_options INTERFACE -Wno-stringop-truncation -Wno-stringop-overflow)
|
||||
if(CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 7.1)
|
||||
target_compile_options(loader_common_options INTERFACE -Wimplicit-fallthrough=0)
|
||||
if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 7.1)
|
||||
target_compile_options(loader_common_options INTERFACE -Wshadow=local) #only added in GCC 7
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
target_compile_options(loader_common_options INTERFACE -fvisibility=hidden)
|
||||
endif()
|
||||
|
||||
target_compile_options(loader_common_options INTERFACE -Wpointer-arith)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" MATCHES "MSVC"))
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "MSVC" OR (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "MSVC"))
|
||||
# /sdl: Enable additional security checks
|
||||
# /GR-: Disable RTTI
|
||||
# /guard:cf: Enable control flow guard
|
||||
# /wd4100: Disable warning on unreferenced formal parameter
|
||||
# /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 /GR- /guard:cf /wd4100 /wd4152 /wd4201)
|
||||
target_compile_options(loader_common_options INTERFACE /sdl /GR- /guard:cf /wd4152 /wd4201)
|
||||
|
||||
# Enable control flow guard
|
||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
|
||||
target_link_options(loader_common_options INTERFACE "LINKER:/guard:cf")
|
||||
else()
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /guard:cf")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /guard:cf")
|
||||
endif()
|
||||
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)
|
||||
@ -338,34 +191,34 @@ endif()
|
||||
# Add git branch and tag info in debug mode
|
||||
target_compile_definitions(loader_common_options INTERFACE $<$<CONFIG:DEBUG>:DEBUG;GIT_BRANCH_NAME="${GIT_BRANCH_NAME}";GIT_TAG_INFO="${GIT_TAG_INFO}">)
|
||||
|
||||
# Check for the existance of the secure_getenv or __secure_getenv commands
|
||||
include(CheckFunctionExists)
|
||||
include(CheckIncludeFile)
|
||||
if (NOT (WIN32 OR APPLE))
|
||||
# Check for the existance of the secure_getenv or __secure_getenv commands
|
||||
include(CheckFunctionExists)
|
||||
|
||||
check_function_exists(secure_getenv HAVE_SECURE_GETENV)
|
||||
check_function_exists(__secure_getenv HAVE___SECURE_GETENV)
|
||||
check_function_exists(secure_getenv HAVE_SECURE_GETENV)
|
||||
check_function_exists(__secure_getenv HAVE___SECURE_GETENV)
|
||||
|
||||
if (HAVE_SECURE_GETENV)
|
||||
target_compile_definitions(loader_common_options INTERFACE HAVE_SECURE_GETENV)
|
||||
endif()
|
||||
if (HAVE___SECURE_GETENV)
|
||||
target_compile_definitions(loader_common_options INTERFACE HAVE___SECURE_GETENV)
|
||||
endif()
|
||||
if(NOT MSVC AND NOT (HAVE_SECURE_GETENV OR HAVE___SECURE_GETENV))
|
||||
message(WARNING "Using non-secure environmental lookups. This loader will not properly disable environent variables when run with elevated permissions.")
|
||||
if (HAVE_SECURE_GETENV)
|
||||
target_compile_definitions(loader_common_options INTERFACE HAVE_SECURE_GETENV)
|
||||
endif()
|
||||
if (HAVE___SECURE_GETENV)
|
||||
target_compile_definitions(loader_common_options INTERFACE HAVE___SECURE_GETENV)
|
||||
endif()
|
||||
if (NOT (HAVE_SECURE_GETENV OR HAVE___SECURE_GETENV))
|
||||
message(WARNING "Using non-secure environmental lookups. This loader will not properly disable environent variables when run with elevated permissions.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Optional codegen target
|
||||
if(PYTHONINTERP_FOUND)
|
||||
add_custom_target(VulkanLoader_generated_source
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/generate_source.py
|
||||
${VulkanRegistry_DIR} --incremental
|
||||
)
|
||||
else()
|
||||
message("WARNING: VulkanLoader_generated_source target requires python 3")
|
||||
option(LOADER_CODEGEN "Enable vulkan loader code generation")
|
||||
if(LOADER_CODEGEN)
|
||||
find_package(Python3 REQUIRED)
|
||||
add_custom_target(loader_codegen
|
||||
COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/scripts/generate_source.py
|
||||
"${VULKAN_HEADERS_INSTALL_DIR}/${CMAKE_INSTALL_DATADIR}/vulkan/registry"
|
||||
--generated-version ${VulkanHeaders_VERSION} --incremental --api ${API_TYPE}
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
if(UNIX)
|
||||
target_compile_definitions(loader_common_options INTERFACE FALLBACK_CONFIG_DIRS="${FALLBACK_CONFIG_DIRS}" FALLBACK_DATA_DIRS="${FALLBACK_DATA_DIRS}")
|
||||
|
||||
@ -382,120 +235,10 @@ if(UNIX)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# uninstall target
|
||||
if(NOT TARGET uninstall)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE
|
||||
@ONLY)
|
||||
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
set_target_properties(uninstall PROPERTIES FOLDER ${LOADER_HELPER_FOLDER})
|
||||
endif()
|
||||
|
||||
add_subdirectory(loader)
|
||||
|
||||
if(BUILD_TESTS)
|
||||
# Set gtest build configuration
|
||||
# Attempt to enable if it is available.
|
||||
if(TARGET gtest)
|
||||
# Already enabled as a target (perhaps by a project enclosing this one)
|
||||
message(STATUS "Vulkan-Loader/external: " "googletest already configured - using it")
|
||||
elseif(IS_DIRECTORY "${GOOGLETEST_INSTALL_DIR}/googletest")
|
||||
set(BUILD_GTEST ON CACHE BOOL "Builds the googletest subproject")
|
||||
set(BUILD_GMOCK OFF CACHE BOOL "Builds the googlemock subproject")
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "Link gtest runtimes dynamically" FORCE)
|
||||
set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries")
|
||||
# The googletest directory exists, so enable it as a target.
|
||||
message(STATUS "Vulkan-Loader/external: " "googletest found - configuring it for tests")
|
||||
add_subdirectory("${GOOGLETEST_INSTALL_DIR}")
|
||||
else()
|
||||
message(SEND_ERROR "Could not find googletest directory. Be sure to run update_deps.py with the --tests option to download the appropriate version of googletest")
|
||||
set(BUILD_TESTS OFF)
|
||||
endif()
|
||||
if (WIN32)
|
||||
if(TARGET detours)
|
||||
# Already enabled as a target (perhaps by a project enclosing this one)
|
||||
message(STATUS "Vulkan-Loader/external: " "detours already configured - using it")
|
||||
else()
|
||||
if(IS_DIRECTORY ${DETOURS_INSTALL_DIR})
|
||||
# The detours directory exists, so enable it as a target.
|
||||
message(STATUS "Vulkan-Loader/external: " "detours found - configuring it for tests")
|
||||
else()
|
||||
message(SEND_ERROR "Could not find detours directory. Be sure to run update_deps.py with the --tests option to download the appropriate version of detours")
|
||||
set(BUILD_TESTS OFF)
|
||||
endif()
|
||||
add_library(detours STATIC
|
||||
${DETOURS_INSTALL_DIR}/src/creatwth.cpp
|
||||
${DETOURS_INSTALL_DIR}/src/detours.cpp
|
||||
${DETOURS_INSTALL_DIR}/src/detours.h
|
||||
${DETOURS_INSTALL_DIR}/src/detver.h
|
||||
${DETOURS_INSTALL_DIR}/src/disasm.cpp
|
||||
${DETOURS_INSTALL_DIR}/src/disolarm.cpp
|
||||
${DETOURS_INSTALL_DIR}/src/disolarm64.cpp
|
||||
${DETOURS_INSTALL_DIR}/src/disolia64.cpp
|
||||
${DETOURS_INSTALL_DIR}/src/disolx64.cpp
|
||||
${DETOURS_INSTALL_DIR}/src/disolx86.cpp
|
||||
${DETOURS_INSTALL_DIR}/src/image.cpp
|
||||
${DETOURS_INSTALL_DIR}/src/modules.cpp
|
||||
)
|
||||
target_include_directories(detours PUBLIC ${DETOURS_INSTALL_DIR}/src)
|
||||
|
||||
macro(GET_WIN32_WINNT version)
|
||||
if(WIN32 AND CMAKE_SYSTEM_VERSION)
|
||||
set(ver ${CMAKE_SYSTEM_VERSION})
|
||||
string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver})
|
||||
string(REGEX MATCH "^([0-9]+)" verMajor ${ver})
|
||||
# Check for Windows 10, b/c we'll need to convert to hex 'A'.
|
||||
if("${verMajor}" MATCHES "10")
|
||||
set(verMajor "A")
|
||||
string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver})
|
||||
endif("${verMajor}" MATCHES "10")
|
||||
# Remove all remaining '.' characters.
|
||||
string(REPLACE "." "" ver ${ver})
|
||||
# Prepend each digit with a zero.
|
||||
string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver})
|
||||
set(${version} "0x${ver}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
set(DETOURS_MAJOR_VERSION "4")
|
||||
set(DETOURS_MINOR_VERSION "0")
|
||||
set(DETOURS_PATCH_VERSION "1")
|
||||
set(DETOURS_VERSION "${DETOURS_MAJOR_VERSION}.${DETOURS_MINOR_VERSION}.${DETOURS_PATCH_VERSION}")
|
||||
|
||||
target_include_directories(detours PUBLIC ${DETOURS_INSTALL_DIR}/src)
|
||||
|
||||
if(MSVC_VERSION GREATER_EQUAL 1700)
|
||||
target_compile_definitions(detours PUBLIC DETOURS_CL_17_OR_NEWER)
|
||||
endif(MSVC_VERSION GREATER_EQUAL 1700)
|
||||
GET_WIN32_WINNT(ver)
|
||||
if(ver EQUAL 0x0700)
|
||||
target_compile_definitions(detours PUBLIC _USING_V110_SDK71_ DETOURS_WIN_7)
|
||||
endif(ver EQUAL 0x0700)
|
||||
target_compile_definitions(detours PUBLIC "_WIN32_WINNT=${ver}")
|
||||
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
target_compile_definitions(detours PUBLIC "DETOURS_TARGET_PROCESSOR=X64" DETOURS_X64 DETOURS_64BIT _AMD64_)
|
||||
else("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
target_compile_definitions(detours PUBLIC "DETOURS_TARGET_PROCESSOR=X86" DETOURS_X86 _X86_)
|
||||
endif("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
|
||||
target_compile_definitions(detours PUBLIC "DETOURS_VERSION=0x4c0c1" WIN32_LEAN_AND_MEAN)
|
||||
|
||||
if(MSVC)
|
||||
target_compile_definitions(detours PUBLIC "_CRT_SECURE_NO_WARNINGS=1")
|
||||
set_target_properties(detours PROPERTIES COMPILE_FLAGS /EHsc)
|
||||
endif()
|
||||
|
||||
# Silence errors found in clang-cl
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" MATCHES "MSVC")
|
||||
target_compile_options(detours PRIVATE -Wno-sizeof-pointer-memaccess -Wno-microsoft-goto -Wno-microsoft-cast)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (BUILD_TESTS)
|
||||
add_subdirectory(tests ${CMAKE_BINARY_DIR}/tests)
|
||||
endif()
|
||||
|
||||
option(BUILD_TESTS "Build Tests")
|
||||
if (BUILD_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
@ -42,7 +42,7 @@ current assignee.
|
||||
[submitting a pull request](https://help.github.com/articles/using-pull-requests/).
|
||||
* Please read and adhere to the style and process
|
||||
[guidelines](#coding-conventions-and-formatting) enumerated below.
|
||||
* Please base your fixes on the master branch.
|
||||
* Please base your fixes on the `main` branch.
|
||||
SDK branches are generally not updated except for critical fixes needed to
|
||||
repair an SDK release.
|
||||
* Provide one or more tests which show a failure for the issue before your changes
|
||||
@ -74,7 +74,7 @@ current assignee.
|
||||
clang-format settings which are found and used automatically by clang-format.
|
||||
* **clang-format** binaries are available from the LLVM orginization, here:
|
||||
[LLVM](https://clang.llvm.org/).
|
||||
Our CI system (Travis-CI) currently uses clang-format version 5.0.0 to
|
||||
Our CI system currently uses clang-format version 16 to
|
||||
check that the lines of code you have changed are formatted properly.
|
||||
It is recommended that you use the same version to format your code prior
|
||||
to submission.
|
||||
@ -107,7 +107,7 @@ Please ensure that the repository compiles and passes tests without
|
||||
error for each commit in your pull request.
|
||||
Note that to be accepted into the repository, the pull request must
|
||||
pass all tests on all supported platforms.
|
||||
The automatic Github Travis and AppVeyor continuous integration features
|
||||
The automatic Github continuous integration features
|
||||
will assist in enforcing this requirement.*
|
||||
|
||||
#### Generated Source Code
|
||||
@ -115,9 +115,8 @@ will assist in enforcing this requirement.*
|
||||
The `loader/generated` directory contains source code that is created by several
|
||||
generator scripts in the `scripts` directory. All changes to these scripts _must_ be submitted with the
|
||||
corresponding generated output to keep the repository self-consistent. This requirement is enforced by both
|
||||
Travis CI and AppVeyor test configurations. Regenerate source files after modifying any of the generator
|
||||
scripts and before building and testing your changes. More details can be found in
|
||||
[BUILD.md](https://github.com/KhronosGroup/Vulkan-Loader/blob/master/BUILD.md#generated-source-code).
|
||||
GitHub actions. Regenerate source files after modifying any of the generator scripts and before building
|
||||
and testing your changes. More details can be found in [BUILD.md](BUILD.md#generated-source-code).
|
||||
|
||||
#### Testing Your Changes
|
||||
|
||||
@ -139,21 +138,6 @@ scripts and before building and testing your changes. More details can be found
|
||||
* The indent is 4 spaces.
|
||||
* CMake functions are lower-case.
|
||||
* Variable and keyword names are upper-case.
|
||||
* The format is defined by
|
||||
[cmake-format](https://github.com/cheshirekow/cmake_format)
|
||||
using the `.cmake-format.py` file in the repository to define the settings.
|
||||
See the cmake-format page for information about its simple markup for comments.
|
||||
* Disable reformatting of a block of comment lines by inserting
|
||||
a `# ~~~` comment line before and after that block.
|
||||
* Disable any formatting of a block of lines by surrounding that block with
|
||||
`# cmake-format: off` and `# cmake-format: on` comment lines.
|
||||
* To install: `sudo pip install cmake_format`
|
||||
* To run: `cmake-format --in-place $FILENAME`
|
||||
* **IMPORTANT (June 2018)** cmake-format v0.3.6 has a
|
||||
[bug]( https://github.com/cheshirekow/cmake_format/issues/50)
|
||||
that can corrupt the formatting of comment lines in CMake files.
|
||||
A workaround is to use the following command _before_ running cmake-format:
|
||||
`sed --in-place='' 's/^ *#/#/' $FILENAME`
|
||||
|
||||
### Contributor License Agreement (CLA)
|
||||
|
||||
|
26
README.md
26
README.md
@ -1,10 +1,6 @@
|
||||
# Vulkan Ecosystem Components
|
||||
# Vulkan Loader
|
||||
|
||||
This project provides the Khronos official Vulkan ICD desktop loader for Windows, Linux, and MacOS.
|
||||
|
||||
## CI Build Status
|
||||
|
||||
[![Build Status](https://github.com/KhronosGroup/Vulkan-Loader/workflows/CI%20Build/badge.svg?branch=master)](https://github.com/KhronosGroup/Vulkan-Loader/actions)
|
||||
This project provides the Khronos official Vulkan Loader for all platforms except [Android](https://android.googlesource.com/platform/frameworks/native/+/master/vulkan/)
|
||||
|
||||
## Introduction
|
||||
|
||||
@ -31,29 +27,25 @@ The following components are available in this repository:
|
||||
## Information for Developing or Contributing
|
||||
|
||||
Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file in this repository for more details.
|
||||
Please see the [GOVERNANCE.md](GOVERNANCE.md) file in this repository for repository
|
||||
management details.
|
||||
Please see the [GOVERNANCE.md](GOVERNANCE.md) file in this repository for repository management details.
|
||||
|
||||
## How to Build and Run
|
||||
|
||||
[BUILD.md](BUILD.md)
|
||||
Includes directions for building all components.
|
||||
[BUILD.md](BUILD.md) includes directions for building all components.
|
||||
|
||||
Architecture and interface information for the loader is in
|
||||
[docs/LoaderInterfaceArchitecture.md](docs/LoaderInterfaceArchitecture.md).
|
||||
Architecture and interface information for the loader is in [docs/LoaderInterfaceArchitecture.md](docs/LoaderInterfaceArchitecture.md).
|
||||
|
||||
## Version Tagging Scheme
|
||||
|
||||
Updates to the `Vulkan-Loader` repository which correspond to a new Vulkan specification release are tagged using the following format: `v<`_`version`_`>` (e.g., `v1.1.96`).
|
||||
Updates to this repository which correspond to a new Vulkan specification release are tagged using the following format: `v<`_`version`_`>` (e.g., `v1.3.266`).
|
||||
|
||||
**Note**: Marked version releases have undergone thorough testing but do not imply the same quality level as SDK tags. SDK tags follow the `sdk-<`_`version`_`>.<`_`patch`_`>` format (e.g., `sdk-1.1.92.0`).
|
||||
**Note**: Marked version releases have undergone thorough testing but do not imply the same quality level as SDK tags. SDK tags follow the `vulkan-sdk-<`_`version`_`>.<`_`patch`_`>` format (e.g., `vulkan-sdk-1.3.266.0`).
|
||||
|
||||
This scheme was adopted following the 1.1.96 Vulkan specification release.
|
||||
This scheme was adopted following the `1.3.266` Vulkan specification release.
|
||||
|
||||
## License
|
||||
|
||||
This work is released as open source under a Apache-style license from Khronos
|
||||
including a Khronos copyright.
|
||||
This work is released as open source under a Apache-style license from Khronos including a Khronos copyright.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
|
13
SECURITY.md
Normal file
13
SECURITY.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Security updates are applied only to the latest release.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
|
||||
|
||||
Please disclose it at [security advisory](https://github.com/KhronosGroup/Vulkan-Loader/security/advisories/new).
|
||||
|
||||
This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.
|
@ -1,57 +0,0 @@
|
||||
vars = {
|
||||
'chromium_git': 'https://chromium.googlesource.com',
|
||||
}
|
||||
|
||||
deps = {
|
||||
|
||||
'build': {
|
||||
'url': '{chromium_git}/chromium/src/build.git@45ab3c89af6fc3126b0ca5a7836f0db85ad1ba0e',
|
||||
},
|
||||
|
||||
'buildtools': {
|
||||
'url': '{chromium_git}/chromium/src/buildtools.git@204a35a2a64f7179f8b76d7a0385653690839e21',
|
||||
},
|
||||
|
||||
'testing': {
|
||||
'url': '{chromium_git}/chromium/src/testing@3993ef1f527b206d8d3bf3f9824f4fe0e4bbdb0e',
|
||||
},
|
||||
|
||||
'tools/clang': {
|
||||
'url': '{chromium_git}/chromium/src/tools/clang.git@04b99e7bf9160d551c3a5562f583014b6afc90f9',
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
hooks = [
|
||||
# Pull clang-format binaries using checked-in hashes.
|
||||
{
|
||||
'name': 'clang_format_linux',
|
||||
'pattern': '.',
|
||||
'condition': 'host_os == "linux"',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=linux*',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-clang-format',
|
||||
'-s', 'buildtools/linux64/clang-format.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'sysroot_x64',
|
||||
'pattern': '.',
|
||||
'condition': 'checkout_linux and checkout_x64',
|
||||
'action': ['python', 'build/linux/sysroot_scripts/install-sysroot.py',
|
||||
'--arch=x64'],
|
||||
},
|
||||
{
|
||||
# Note: On Win, this should run after win_toolchain, as it may use it.
|
||||
'name': 'clang',
|
||||
'pattern': '.',
|
||||
'action': ['python', 'tools/clang/scripts/update.py'],
|
||||
},
|
||||
]
|
||||
|
||||
recursedeps = [
|
||||
# buildtools provides clang_format.
|
||||
'buildtools',
|
||||
]
|
@ -1,18 +0,0 @@
|
||||
# Copyright (c) 2019 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
build_with_chromium = false
|
||||
ignore_elf32_limitations = true
|
||||
linux_use_bundled_binutils_override = false
|
||||
use_system_xcode = true
|
@ -1,15 +0,0 @@
|
||||
# Copyright (c) 2020 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
vulkan_use_x11 = true
|
@ -1,23 +0,0 @@
|
||||
# Copyright (c) 2019 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
# Paths to loader dependencies
|
||||
vulkan_headers_dir = "//external/Vulkan-Headers"
|
||||
|
||||
# Subdirectories for generated files
|
||||
vulkan_gen_subdir = ""
|
||||
|
||||
# Vulkan loader build options
|
||||
vulkan_loader_shared = true
|
||||
|
@ -1,2 +0,0 @@
|
||||
LIST=OS
|
||||
include recurse.mk
|
@ -1,8 +0,0 @@
|
||||
LIST=CPU
|
||||
ifndef QRECURSE
|
||||
QRECURSE=recurse.mk
|
||||
ifdef QCONFIG
|
||||
QRDIR=$(dir $(QCONFIG))
|
||||
endif
|
||||
endif
|
||||
include $(QRDIR)$(QRECURSE)
|
@ -1,8 +0,0 @@
|
||||
LIST=VARIANT
|
||||
ifndef QRECURSE
|
||||
QRECURSE=recurse.mk
|
||||
ifdef QCONFIG
|
||||
QRDIR=$(dir $(QCONFIG))
|
||||
endif
|
||||
endif
|
||||
include $(QRDIR)$(QRECURSE)
|
@ -1 +0,0 @@
|
||||
include ../../../common.mk
|
@ -1,8 +0,0 @@
|
||||
LIST=VARIANT
|
||||
ifndef QRECURSE
|
||||
QRECURSE=recurse.mk
|
||||
ifdef QCONFIG
|
||||
QRDIR=$(dir $(QCONFIG))
|
||||
endif
|
||||
endif
|
||||
include $(QRDIR)$(QRECURSE)
|
@ -1 +0,0 @@
|
||||
include ../../../common.mk
|
@ -1,8 +0,0 @@
|
||||
LIST=VARIANT
|
||||
ifndef QRECURSE
|
||||
QRECURSE=recurse.mk
|
||||
ifdef QCONFIG
|
||||
QRDIR=$(dir $(QCONFIG))
|
||||
endif
|
||||
endif
|
||||
include $(QRDIR)$(QRECURSE)
|
@ -1 +0,0 @@
|
||||
include ../../../common.mk
|
@ -1,126 +0,0 @@
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2018 Kitware, Inc. and Contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Kitware, Inc. nor the names of Contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The following individuals and institutions are among the Contributors:
|
||||
|
||||
* Aaron C. Meadows <cmake@shadowguarddev.com>
|
||||
* Adriaan de Groot <groot@kde.org>
|
||||
* Aleksey Avdeev <solo@altlinux.ru>
|
||||
* Alexander Neundorf <neundorf@kde.org>
|
||||
* Alexander Smorkalov <alexander.smorkalov@itseez.com>
|
||||
* Alexey Sokolov <sokolov@google.com>
|
||||
* Alex Turbov <i.zaufi@gmail.com>
|
||||
* Andreas Pakulat <apaku@gmx.de>
|
||||
* Andreas Schneider <asn@cryptomilk.org>
|
||||
* André Rigland Brodtkorb <Andre.Brodtkorb@ifi.uio.no>
|
||||
* Axel Huebl, Helmholtz-Zentrum Dresden - Rossendorf
|
||||
* Benjamin Eikel
|
||||
* Bjoern Ricks <bjoern.ricks@gmail.com>
|
||||
* Brad Hards <bradh@kde.org>
|
||||
* Christopher Harvey
|
||||
* Christoph Grüninger <foss@grueninger.de>
|
||||
* Clement Creusot <creusot@cs.york.ac.uk>
|
||||
* Daniel Blezek <blezek@gmail.com>
|
||||
* Daniel Pfeifer <daniel@pfeifer-mail.de>
|
||||
* Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
|
||||
* Eran Ifrah <eran.ifrah@gmail.com>
|
||||
* Esben Mose Hansen, Ange Optimization ApS
|
||||
* Geoffrey Viola <geoffrey.viola@asirobots.com>
|
||||
* Google Inc
|
||||
* Gregor Jasny
|
||||
* Helio Chissini de Castro <helio@kde.org>
|
||||
* Ilya Lavrenov <ilya.lavrenov@itseez.com>
|
||||
* Insight Software Consortium <insightsoftwareconsortium.org>
|
||||
* Jan Woetzel
|
||||
* Kelly Thompson <kgt@lanl.gov>
|
||||
* Konstantin Podsvirov <konstantin@podsvirov.pro>
|
||||
* Mario Bensi <mbensi@ipsquad.net>
|
||||
* Mathieu Malaterre <mathieu.malaterre@gmail.com>
|
||||
* Matthaeus G. Chajdas
|
||||
* Matthias Kretz <kretz@kde.org>
|
||||
* Matthias Maennich <matthias@maennich.net>
|
||||
* Michael Stürmer
|
||||
* Miguel A. Figueroa-Villanueva
|
||||
* Mike Jackson
|
||||
* Mike McQuaid <mike@mikemcquaid.com>
|
||||
* Nicolas Bock <nicolasbock@gmail.com>
|
||||
* Nicolas Despres <nicolas.despres@gmail.com>
|
||||
* Nikita Krupen'ko <krnekit@gmail.com>
|
||||
* NVIDIA Corporation <www.nvidia.com>
|
||||
* OpenGamma Ltd. <opengamma.com>
|
||||
* Patrick Stotko <stotko@cs.uni-bonn.de>
|
||||
* Per Øyvind Karlsen <peroyvind@mandriva.org>
|
||||
* Peter Collingbourne <peter@pcc.me.uk>
|
||||
* Petr Gotthard <gotthard@honeywell.com>
|
||||
* Philip Lowman <philip@yhbt.com>
|
||||
* Philippe Proulx <pproulx@efficios.com>
|
||||
* Raffi Enficiaud, Max Planck Society
|
||||
* Raumfeld <raumfeld.com>
|
||||
* Roger Leigh <rleigh@codelibre.net>
|
||||
* Rolf Eike Beer <eike@sf-mail.de>
|
||||
* Roman Donchenko <roman.donchenko@itseez.com>
|
||||
* Roman Kharitonov <roman.kharitonov@itseez.com>
|
||||
* Ruslan Baratov
|
||||
* Sebastian Holtermann <sebholt@xwmw.org>
|
||||
* Stephen Kelly <steveire@gmail.com>
|
||||
* Sylvain Joubert <joubert.sy@gmail.com>
|
||||
* Thomas Sondergaard <ts@medical-insight.com>
|
||||
* Tobias Hunger <tobias.hunger@qt.io>
|
||||
* Todd Gamblin <tgamblin@llnl.gov>
|
||||
* Tristan Carel
|
||||
* University of Dundee
|
||||
* Vadim Zhukov
|
||||
* Will Dicharry <wdicharry@stellarscience.com>
|
||||
|
||||
See version control history for details of individual contributions.
|
||||
|
||||
The above copyright and license notice applies to distributions of
|
||||
CMake in source and binary form. Third-party software packages supplied
|
||||
with CMake under compatible licenses provide their own copyright notices
|
||||
documented in corresponding subdirectories or source files.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
CMake was initially developed by Kitware with the following sponsorship:
|
||||
|
||||
* National Library of Medicine at the National Institutes of Health
|
||||
as part of the Insight Segmentation and Registration Toolkit (ITK).
|
||||
|
||||
* US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
|
||||
Visualization Initiative.
|
||||
|
||||
* National Alliance for Medical Image Computing (NAMIC) is funded by the
|
||||
National Institutes of Health through the NIH Roadmap for Medical Research,
|
||||
Grant U54 EB005149.
|
||||
|
||||
* Kitware, Inc.
|
@ -1,28 +0,0 @@
|
||||
# Try to find DirectFB
|
||||
#
|
||||
# This will define:
|
||||
#
|
||||
# DIRECTFB_FOUND - True if DirectFB is found
|
||||
# DIRECTFB_LIBRARIES - Link these to use DirectFB
|
||||
# DIRECTFB_INCLUDE_DIR - Include directory for DirectFB
|
||||
# DIRECTFB_DEFINITIONS - Compiler flags for using DirectFB
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
IF (NOT WIN32)
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
PKG_CHECK_MODULES(PKG_DIRECTFB QUIET directfb)
|
||||
|
||||
SET(DIRECTFB_DEFINITIONS ${PKG_DIRECTFB_CFLAGS})
|
||||
|
||||
FIND_PATH(DIRECTFB_INCLUDE_DIR NAMES directfb.h HINTS ${PKG_DIRECTFB_INCLUDE_DIRS})
|
||||
|
||||
FIND_LIBRARY(DIRECTFB_LIBRARIES NAMES directfb HINTS ${PKG_DIRECTFB_LIBRARY_DIRS})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(DIRECTFB DEFAULT_MSG DIRECTFB_LIBRARIES DIRECTFB_INCLUDE_DIR)
|
||||
|
||||
MARK_AS_ADVANCED(DIRECTFB_INCLUDE_DIR DIRECTFB_LIBRARIES)
|
||||
ENDIF ()
|
@ -1,28 +0,0 @@
|
||||
# - FindPCIAccess
|
||||
#
|
||||
# Copyright 2015 Valve Corporation
|
||||
|
||||
find_package(PkgConfig)
|
||||
|
||||
pkg_check_modules(PC_PCIACCESS QUIET pciaccess)
|
||||
|
||||
find_path(PCIACCESS_INCLUDE_DIR NAMES pciaccess.h
|
||||
HINTS
|
||||
${PC_PCIACCESS_INCLUDEDIR}
|
||||
${PC_PCIACCESS_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(PCIACCESS_LIBRARY NAMES pciaccess
|
||||
HINTS
|
||||
${PC_PCIACCESS_LIBDIR}
|
||||
${PC_PCIACCESS_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PCIAccess DEFAULT_MSG
|
||||
PCIACCESS_INCLUDE_DIR PCIACCESS_LIBRARY)
|
||||
|
||||
mark_as_advanced(PCIACCESS_INCLUDE_DIR PCIACCESS_LIBRARY)
|
||||
|
||||
set(PCIACCESS_INCLUDE_DIRS ${PCIACCESS_INCLUDE_DIR})
|
||||
set(PCIACCESS_LIBRARIES ${PCIACCESS_LIBRARY})
|
@ -1,14 +0,0 @@
|
||||
# - FindPthreadStubs
|
||||
#
|
||||
# Copyright (C) 2015 Valve Corporation
|
||||
|
||||
find_package(PkgConfig)
|
||||
|
||||
pkg_check_modules(PC_PTHREADSTUBS QUIET pthread-stubs)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PthreadStubs DEFAULT_MSG
|
||||
PC_PTHREADSTUBS_FOUND)
|
||||
|
||||
set(PTHREADSTUBS_INCLUDE_DIRS "")
|
||||
set(PTHREADSTUBS_LIBRARIES "")
|
@ -1,28 +0,0 @@
|
||||
# - FindUDev
|
||||
#
|
||||
# Copyright (C) 2015 Valve Corporation
|
||||
|
||||
find_package(PkgConfig)
|
||||
|
||||
pkg_check_modules(PC_LIBUDEV QUIET libudev)
|
||||
|
||||
find_path(UDEV_INCLUDE_DIR NAMES libudev.h
|
||||
HINTS
|
||||
${PC_LIBUDEV_INCLUDEDIR}
|
||||
${PC_LIBUDEV_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(UDEV_LIBRARY NAMES udev
|
||||
HINTS
|
||||
${PC_LIBUDEV_LIBDIR}
|
||||
${PC_LIBUDEV_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(UDev DEFAULT_MSG
|
||||
UDEV_INCLUDE_DIR UDEV_LIBRARY)
|
||||
|
||||
mark_as_advanced(UDEV_INCLUDE_DIR UDEV_LIBRARY)
|
||||
|
||||
set(UDEV_INCLUDE_DIRS ${UDEV_INCLUDE_DIR})
|
||||
set(UDEV_LIBRARIES ${UDEV_LIBRARY})
|
@ -1,22 +0,0 @@
|
||||
# - FindValgrind
|
||||
#
|
||||
# Copyright (C) 2015 Valve Corporation
|
||||
|
||||
find_package(PkgConfig)
|
||||
|
||||
pkg_check_modules(PC_VALGRIND QUIET valgrind)
|
||||
|
||||
find_path(VALGRIND_INCLUDE_DIR NAMES valgrind.h memcheck.h
|
||||
HINTS
|
||||
${PC_VALGRIND_INCLUDEDIR}
|
||||
${PC_VALGRIND_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Valgrind DEFAULT_MSG
|
||||
VALGRIND_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(VALGRIND_INCLUDE_DIR)
|
||||
|
||||
set(VALGRIND_INCLUDE_DIRS ${VALGRIND_INCLUDE_DIR})
|
||||
set(VALGRIND_LIBRARIES "")
|
@ -1,154 +0,0 @@
|
||||
#.rst:
|
||||
# FindVulkanHeaders
|
||||
# -----------------
|
||||
#
|
||||
# Try to find Vulkan Headers and Registry.
|
||||
#
|
||||
# This module is intended to be used by projects that build Vulkan
|
||||
# "system" components such as the loader and layers.
|
||||
# Vulkan applications should instead use the FindVulkan (or similar)
|
||||
# find module that locates the headers and the loader library.
|
||||
#
|
||||
# When using this find module to locate the headers and registry
|
||||
# in a Vulkan-Headers repository, the Vulkan-Headers repository
|
||||
# should be built with 'install' target and the following environment
|
||||
# or CMake variable set to the location of the install directory.
|
||||
#
|
||||
# VULKAN_HEADERS_INSTALL_DIR
|
||||
#
|
||||
# IMPORTED Targets
|
||||
# ^^^^^^^^^^^^^^^^
|
||||
#
|
||||
# This module defines no IMPORTED targets
|
||||
#
|
||||
# Result Variables
|
||||
# ^^^^^^^^^^^^^^^^
|
||||
#
|
||||
# This module defines the following variables::
|
||||
#
|
||||
# VulkanHeaders_FOUND - True if VulkanHeaders was found
|
||||
# VulkanHeaders_INCLUDE_DIRS - include directories for VulkanHeaders
|
||||
#
|
||||
# VulkanRegistry_FOUND - True if VulkanRegistry was found
|
||||
# VulkanRegistry_DIRS - directories for VulkanRegistry
|
||||
#
|
||||
# VulkanHeaders_VERSION_MAJOR - The Major API version of the latest version
|
||||
# contained in the Vulkan header
|
||||
# VulkanHeaders_VERSION_MINOR - The Minor API version of the latest version
|
||||
# contained in the Vulkan header
|
||||
# VulkanHeaders_VERSION_PATCH - The Patch API version of the latest version
|
||||
# contained in the Vulkan header
|
||||
#
|
||||
# The module will also define two cache variables::
|
||||
#
|
||||
# VulkanHeaders_INCLUDE_DIR - the VulkanHeaders include directory
|
||||
# VulkanRegistry_DIR - the VulkanRegistry directory
|
||||
#
|
||||
|
||||
# Probe command-line arguments and the environment to see if they specify the
|
||||
# Vulkan headers installation path.
|
||||
if(NOT DEFINED VULKAN_HEADERS_INSTALL_DIR)
|
||||
if (DEFINED ENV{VULKAN_HEADERS_INSTALL_DIR})
|
||||
set(VULKAN_HEADERS_INSTALL_DIR "$ENV{VULKAN_HEADERS_INSTALL_DIR}")
|
||||
elseif(DEFINED ENV{VULKAN_SDK})
|
||||
set(VULKAN_HEADERS_INSTALL_DIR "$ENV{VULKAN_SDK}/include")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(DEFINED VULKAN_HEADERS_INSTALL_DIR)
|
||||
# When CMAKE_FIND_ROOT_PATH_INCLUDE is set to ONLY, the HINTS in find_path()
|
||||
# are re-rooted, which prevents VULKAN_HEADERS_INSTALL_DIR to work as
|
||||
# expected. So use NO_CMAKE_FIND_ROOT_PATH to avoid it.
|
||||
|
||||
# Use HINTS instead of PATH to search these locations before
|
||||
# searching system environment variables like $PATH that may
|
||||
# contain SDK directories.
|
||||
find_path(VulkanHeaders_INCLUDE_DIR
|
||||
NAMES vulkan/vulkan.h
|
||||
HINTS ${VULKAN_HEADERS_INSTALL_DIR}/include
|
||||
NO_CMAKE_FIND_ROOT_PATH)
|
||||
find_path(VulkanRegistry_DIR
|
||||
NAMES vk.xml
|
||||
HINTS ${VULKAN_HEADERS_INSTALL_DIR}/share/vulkan/registry
|
||||
NO_CMAKE_FIND_ROOT_PATH)
|
||||
else()
|
||||
# If VULKAN_HEADERS_INSTALL_DIR, or one of its variants was not specified,
|
||||
# do a normal search without hints.
|
||||
find_path(VulkanHeaders_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS "${CMAKE_CURRENT_SOURCE_DIR}/external/Vulkan-Headers/include" NO_CMAKE_FIND_ROOT_PATH)
|
||||
get_filename_component(VULKAN_REGISTRY_PATH_HINT ${VulkanHeaders_INCLUDE_DIR} DIRECTORY)
|
||||
find_path(VulkanRegistry_DIR NAMES vk.xml HINTS ${VULKAN_REGISTRY_PATH_HINT}/share/vulkan/registry
|
||||
"${VULKAN_REGISTRY_PATH_HINT}/registry" NO_CMAKE_FIND_ROOT_PATH)
|
||||
endif()
|
||||
|
||||
set(VulkanHeaders_INCLUDE_DIRS ${VulkanHeaders_INCLUDE_DIR})
|
||||
set(VulkanRegistry_DIRS ${VulkanRegistry_DIR})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(VulkanHeaders
|
||||
DEFAULT_MSG
|
||||
VulkanHeaders_INCLUDE_DIR)
|
||||
set(FPHSA_NAME_MISMATCHED TRUE)
|
||||
find_package_handle_standard_args(VulkanRegistry
|
||||
DEFAULT_MSG
|
||||
VulkanRegistry_DIR)
|
||||
unset(FPHSA_NAME_MISMATCHED)
|
||||
|
||||
mark_as_advanced(VulkanHeaders_INCLUDE_DIR VulkanRegistry_DIR)
|
||||
|
||||
# Determine the major/minor/patch version from the vulkan header
|
||||
set(VulkanHeaders_VERSION_MAJOR "0")
|
||||
set(VulkanHeaders_VERSION_MINOR "0")
|
||||
set(VulkanHeaders_VERSION_PATCH "0")
|
||||
|
||||
# First, determine which header we need to grab the version information from.
|
||||
# Starting with Vulkan 1.1, we should use vulkan_core.h, but prior to that,
|
||||
# the information was in vulkan.h.
|
||||
if (EXISTS "${VulkanHeaders_INCLUDE_DIR}/vulkan/vulkan_core.h")
|
||||
set(VulkanHeaders_main_header ${VulkanHeaders_INCLUDE_DIR}/vulkan/vulkan_core.h)
|
||||
else()
|
||||
set(VulkanHeaders_main_header ${VulkanHeaders_INCLUDE_DIR}/vulkan/vulkan.h)
|
||||
endif()
|
||||
|
||||
# Find all lines in the header file that contain any version we may be interested in
|
||||
# NOTE: They start with #define and then have other keywords
|
||||
file(STRINGS
|
||||
${VulkanHeaders_main_header}
|
||||
VulkanHeaders_lines
|
||||
REGEX "^#define VK_HEADER_VERSION(_COMPLETE)? ")
|
||||
|
||||
foreach(VulkanHeaders_line ${VulkanHeaders_lines})
|
||||
|
||||
# First, handle the case where we have a major/minor version
|
||||
# Format is:
|
||||
# #define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, X, Y, VK_HEADER_VERSION)
|
||||
# We grab the major version (X) and minor version (Y) out of the parentheses
|
||||
string(REGEX MATCH "VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION\\(.*\\)" VulkanHeaders_out ${VulkanHeaders_line})
|
||||
string(REGEX MATCHALL "[0-9]+" VulkanHeaders_MAJOR_MINOR "${VulkanHeaders_out}")
|
||||
if (VulkanHeaders_MAJOR_MINOR)
|
||||
list (GET VulkanHeaders_MAJOR_MINOR 1 VulkanHeaders_cur_major)
|
||||
list (GET VulkanHeaders_MAJOR_MINOR 2 VulkanHeaders_cur_minor)
|
||||
if (${VulkanHeaders_cur_major} GREATER ${VulkanHeaders_VERSION_MAJOR})
|
||||
set(VulkanHeaders_VERSION_MAJOR ${VulkanHeaders_cur_major})
|
||||
set(VulkanHeaders_VERSION_MINOR ${VulkanHeaders_cur_minor})
|
||||
endif()
|
||||
if (${VulkanHeaders_cur_major} EQUAL ${VulkanHeaders_VERSION_MAJOR} AND
|
||||
${VulkanHeaders_cur_minor} GREATER ${VulkanHeaders_VERSION_MINOR})
|
||||
set(VulkanHeaders_VERSION_MINOR ${VulkanHeaders_cur_minor})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Second, handle the case where we have the patch version
|
||||
# Format is:
|
||||
# #define VK_HEADER_VERSION Z
|
||||
# Where Z is the patch version which we just grab off the end
|
||||
string(REGEX MATCH "define.*VK_HEADER_VERSION[^_].*[0-9]+" VulkanHeaders_out ${VulkanHeaders_line})
|
||||
list(LENGTH VulkanHeaders_out VulkanHeaders_len)
|
||||
if (VulkanHeaders_len)
|
||||
string(REGEX MATCH "[0-9]+" VulkanHeaders_VERSION_PATCH "${VulkanHeaders_out}")
|
||||
endif()
|
||||
|
||||
endforeach()
|
||||
MESSAGE(STATUS
|
||||
"Detected Vulkan Version ${VulkanHeaders_VERSION_MAJOR}."
|
||||
"${VulkanHeaders_VERSION_MINOR}."
|
||||
"${VulkanHeaders_VERSION_PATCH}")
|
@ -1,32 +0,0 @@
|
||||
# - Try to find libX11-xcb
|
||||
# Once done this will define
|
||||
#
|
||||
# X11_XCB_FOUND - system has libX11-xcb
|
||||
# X11_XCB_LIBRARIES - Link these to use libX11-xcb
|
||||
# X11_XCB_INCLUDE_DIR - the libX11-xcb include dir
|
||||
# X11_XCB_DEFINITIONS - compiler switches required for using libX11-xcb
|
||||
|
||||
# Copyright (c) 2011 Fredrik Höglund <fredrik@kde.org>
|
||||
# Copyright (c) 2008 Helio Chissini de Castro, <helio@kde.org>
|
||||
# Copyright (c) 2007 Matthias Kretz, <kretz@kde.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
IF (NOT WIN32)
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
PKG_CHECK_MODULES(PKG_X11_XCB QUIET x11-xcb)
|
||||
|
||||
SET(X11_XCB_DEFINITIONS ${PKG_X11_XCB_CFLAGS})
|
||||
|
||||
FIND_PATH(X11_XCB_INCLUDE_DIR NAMES X11/Xlib-xcb.h HINTS ${PKG_X11_XCB_INCLUDE_DIRS})
|
||||
FIND_LIBRARY(X11_XCB_LIBRARIES NAMES X11-xcb HINTS ${PKG_X11_XCB_LIBRARY_DIRS})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(X11_XCB DEFAULT_MSG X11_XCB_LIBRARIES X11_XCB_INCLUDE_DIR)
|
||||
|
||||
MARK_AS_ADVANCED(X11_XCB_INCLUDE_DIR X11_XCB_LIBRARIES)
|
||||
ENDIF (NOT WIN32)
|
||||
|
@ -1,54 +0,0 @@
|
||||
# - FindXCB
|
||||
#
|
||||
# Copyright (C) 2015 Valve Corporation
|
||||
|
||||
find_package(PkgConfig)
|
||||
|
||||
if(NOT XCB_FIND_COMPONENTS)
|
||||
set(XCB_FIND_COMPONENTS xcb)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
set(XCB_FOUND true)
|
||||
set(XCB_INCLUDE_DIRS "")
|
||||
set(XCB_LIBRARIES "")
|
||||
foreach(comp ${XCB_FIND_COMPONENTS})
|
||||
# component name
|
||||
string(TOUPPER ${comp} compname)
|
||||
string(REPLACE "-" "_" compname ${compname})
|
||||
# header name
|
||||
string(REPLACE "xcb-" "" headername xcb/${comp}.h)
|
||||
# library name
|
||||
set(libname ${comp})
|
||||
|
||||
pkg_check_modules(PC_${comp} QUIET ${comp})
|
||||
|
||||
find_path(${compname}_INCLUDE_DIR NAMES ${headername}
|
||||
HINTS
|
||||
${PC_${comp}_INCLUDEDIR}
|
||||
${PC_${comp}_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(${compname}_LIBRARY NAMES ${libname}
|
||||
HINTS
|
||||
${PC_${comp}_LIBDIR}
|
||||
${PC_${comp}_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
set(FPHSA_NAME_MISMATCHED TRUE)
|
||||
find_package_handle_standard_args(${comp}
|
||||
FOUND_VAR ${comp}_FOUND
|
||||
REQUIRED_VARS ${compname}_INCLUDE_DIR ${compname}_LIBRARY)
|
||||
unset(FPHSA_NAME_MISMATCHED)
|
||||
|
||||
mark_as_advanced(${compname}_INCLUDE_DIR ${compname}_LIBRARY)
|
||||
|
||||
list(APPEND XCB_INCLUDE_DIRS ${${compname}_INCLUDE_DIR})
|
||||
list(APPEND XCB_LIBRARIES ${${compname}_LIBRARY})
|
||||
|
||||
if(NOT ${comp}_FOUND)
|
||||
set(XCB_FOUND false)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
list(REMOVE_DUPLICATES XCB_INCLUDE_DIRS)
|
@ -1,21 +0,0 @@
|
||||
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
|
||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif(NOT "${rm_retval}" STREQUAL 0)
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
endforeach(file)
|
@ -4,15 +4,15 @@
|
||||
[1]: https://vulkan.lunarg.com/img/Vulkan_100px_Dec16.png "https://www.khronos.org/vulkan/"
|
||||
[2]: https://www.khronos.org/vulkan/
|
||||
|
||||
# Application Interface to Loader
|
||||
# Application Interface to Loader <!-- omit from toc -->
|
||||
[![Creative Commons][3]][4]
|
||||
|
||||
<!-- Copyright © 2015-2021 LunarG, Inc. -->
|
||||
<!-- Copyright © 2015-2023 LunarG, Inc. -->
|
||||
|
||||
[3]: https://i.creativecommons.org/l/by-nd/4.0/88x31.png "Creative Commons License"
|
||||
[4]: https://creativecommons.org/licenses/by-nd/4.0/
|
||||
|
||||
## Table of Contents
|
||||
## Table of Contents <!-- omit from toc -->
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Interfacing with Vulkan Functions](#interfacing-with-vulkan-functions)
|
||||
@ -36,9 +36,6 @@
|
||||
- [Forcing Layers to be Enabled on Windows, Linux and macOS](#forcing-layers-to-be-enabled-on-windows-linux-and-macos)
|
||||
- [Overall Layer Ordering](#overall-layer-ordering)
|
||||
- [Debugging Possible Layer Issues](#debugging-possible-layer-issues)
|
||||
- [Enable Loader Debug Layer Output](#enable-loader-debug-layer-output)
|
||||
- [Disable All Layers](#disable-all-layers)
|
||||
- [Enable More Loader Debug Output](#enable-more-loader-debug-output)
|
||||
- [Application Usage of Extensions](#application-usage-of-extensions)
|
||||
- [Instance and Device Extensions](#instance-and-device-extensions)
|
||||
- [WSI Extensions](#wsi-extensions)
|
||||
@ -376,7 +373,7 @@ layer, dropping the need for meta layers.
|
||||
While not necessary for validation anymore, VkConfig does use meta layers to
|
||||
group layers together based on user's preferences.
|
||||
More can be found out about this functionality through both the
|
||||
[VkConfig documentation](https://github.com/LunarG/VulkanTools/blob/master/vkconfig/README.md)
|
||||
[VkConfig documentation](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md)
|
||||
and the section later on the [Override Layer](#override-layer).
|
||||
|
||||
Meta-layers are detailed more in the
|
||||
@ -411,7 +408,7 @@ On Desktop platforms (Windows, Linux, and macOS), these enable/disable settings
|
||||
are defined in the layer's JSON file.
|
||||
|
||||
Discovery of system-installed implicit and explicit layers is described later
|
||||
in the [Layer discovery](LoaderLayerInterface#layer-discovery)
|
||||
in the [Layer discovery](LoaderLayerInterface.md#layer-discovery)
|
||||
section in the
|
||||
[LoaderLayerInterface.md](LoaderLayerInterface.md) document.
|
||||
|
||||
@ -449,7 +446,7 @@ The table below details more information:
|
||||
#### Override Layer
|
||||
|
||||
The "Override Layer" is a special implicit meta-layer created by the
|
||||
[VkConfig](https://github.com/LunarG/VulkanTools/blob/master/vkconfig/README.md)
|
||||
[VkConfig](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md)
|
||||
tool and available by default when the tool is running.
|
||||
Once VkConfig exits, the override layer is removed, and the system should
|
||||
return to standard Vulkan behavior.
|
||||
@ -472,9 +469,9 @@ the system-installed layers.
|
||||
This can be accomplished in one of two ways:
|
||||
|
||||
1. Selecting specific layer paths using the
|
||||
[VkConfig](https://github.com/LunarG/VulkanTools/blob/master/vkconfig/README.md)
|
||||
[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 folders by using the
|
||||
2. Directing the loader to look for layers in specific files and/or folders by using the
|
||||
`VK_LAYER_PATH` environment variable.
|
||||
|
||||
The `VK_LAYER_PATH` environment variable can contain multiple paths separated by
|
||||
@ -482,7 +479,7 @@ 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 folders listed in it will be scanned for explicit
|
||||
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
|
||||
@ -515,7 +512,7 @@ application they are using.
|
||||
This can be also be accomplished in one of two ways:
|
||||
|
||||
1. Selecting specific layers using the
|
||||
[VkConfig](https://github.com/LunarG/VulkanTools/blob/master/vkconfig/README.md)
|
||||
[VkConfig](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md)
|
||||
tool shipped with the Vulkan SDK.
|
||||
2. Directing the loader to look for additional layers by name using the
|
||||
`VK_INSTANCE_LAYERS` environment variable.
|
||||
@ -572,140 +569,10 @@ make to function.
|
||||
### Debugging Possible Layer Issues
|
||||
|
||||
If it is possible that a layer is causing issues, there are several things that
|
||||
can be tried.
|
||||
|
||||
|
||||
#### Enable Loader Debug Layer Output
|
||||
|
||||
First, enable the "layer" debug output option (`VK_LOADER_DEBUG`) in the loader,
|
||||
See the
|
||||
[Table of Debug Environment Variables](LoaderInterfaceArchitecture.md##table-of-debug-environment-variables)
|
||||
for more info.
|
||||
|
||||
When enabled, the loader will output information on:
|
||||
* Where it looks for implicit layers
|
||||
* Where it looks for explicit layers
|
||||
* What manifest files it finds
|
||||
* Which layer manifest files are loaded
|
||||
* What libraries are associated with a layer
|
||||
* What the layer callstack looks like for both the instance and device chain
|
||||
|
||||
For example, the layer output for searching for implicit layers on Linux may
|
||||
look like:
|
||||
|
||||
```
|
||||
LAYER: Searching for layer manifest files
|
||||
LAYER: In following folders:
|
||||
LAYER: /home/linust/.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/linust/.local/share/vulkan/implicit_layer.d
|
||||
LAYER: /home/linust/.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/linust/.local/share/vulkan/implicit_layer.d/renderdoc_capture.json
|
||||
LAYER: /home/linust/.local/share/vulkan/implicit_layer.d/steamfossilize_i386.json
|
||||
LAYER: /home/linust/.local/share/vulkan/implicit_layer.d/steamfossilize_x86_64.json
|
||||
LAYER: /home/linust/.local/share/vulkan/implicit_layer.d/steamoverlay_i386.json
|
||||
LAYER: /home/linust/.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
|
||||
```
|
||||
|
||||
In the above scenario, seven implicit layers were discovered in two different
|
||||
folders.
|
||||
Just because they were found does not mean that they will be loaded, but this
|
||||
information can be used to make sure a layer JSON file was properly discovered.
|
||||
|
||||
When the loader actually loads a layer, the messages may look like the
|
||||
following:
|
||||
|
||||
```
|
||||
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)
|
||||
```
|
||||
|
||||
This information does not indicate the order the layers are used in.
|
||||
That information is displayed later showing all the callstack during both
|
||||
`vkCreateInstance` and `vkCreateDevice`.
|
||||
In the same sample above, the callstack for `vkCreateInstance` looks like the
|
||||
following:
|
||||
|
||||
```
|
||||
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>
|
||||
```
|
||||
|
||||
In this scenario, two layers were used (the same two that were loaded earlier):
|
||||
* `VK_LAYER_MESA_device_select`
|
||||
* `VK_LAYER_KHRONOS_validation`
|
||||
|
||||
This information now shows us that the `VK_LAYER_MESA_device_select` is loaded
|
||||
first, followed by `VK_LAYER_KHRONOS_validation` which will then continue into
|
||||
any available drivers.
|
||||
It also shows that `VK_LAYER_MESA_device_select` is an implicit layer which
|
||||
implies that it wasn't directly enabled by the application.
|
||||
On the other hand, `VK_LAYER_KHRONOS_validation` is shown as an explicit layer
|
||||
which indicates that it was likely enabled by the application.
|
||||
|
||||
Sometimes, implicit layers can cause issues with an application.
|
||||
Because of this, the next step is to try to disable one or more of the listed
|
||||
implicit layers.
|
||||
This can be done by defining the disable environment variable for that layer.
|
||||
Each layer has it's own disable environment variable as mentioned in the
|
||||
[Layer Manifest File Format](LoaderLayerInterface.md#layer-manifest-file-format).
|
||||
However, it can be difficult to find this variable in the manifest files, so
|
||||
the loader now outputs it as part of the callstack information.
|
||||
Looking at the above `vkCreateInstance` callstack output, under the
|
||||
section for `VK_LAYER_MESA_device_select` exists a section listed as
|
||||
"Disable Env Var:".
|
||||
This is the disable environment variable that can be used to disable the
|
||||
`VK_LAYER_MESA_device_select` layer from being loaded by the loader.
|
||||
In the above output, the disable environment variable is listed as
|
||||
"NODEVICE_SELECT" which can be defined to a non-zero value to cause the loader
|
||||
to ignore this layer.
|
||||
|
||||
|
||||
#### Disable All Layers
|
||||
|
||||
Because implicit layers are virtually unknown to the application, it is best to
|
||||
next try to disable each one of them.
|
||||
Using the above debug output, define each environment variable to disable the
|
||||
corresponding implicit layer that was used.
|
||||
|
||||
Once all are disabled, re-run the application again.
|
||||
|
||||
If the failure still occurs, try disabling all explicit layers loaded by the
|
||||
application by modifying the application or using a tool such as
|
||||
[VkConfig](https://github.com/LunarG/VulkanTools/blob/master/vkconfig/README.md).
|
||||
|
||||
|
||||
#### Enable More Loader Debug Output
|
||||
|
||||
If the failure continues after disabling all layers, then enable all loader
|
||||
debug warnings and errors by setting `VK_LOADER_DEBUG` to "error,warn" or
|
||||
even "all".
|
||||
This will output any other issues that the loader has encountered.
|
||||
can be tried which are documented in the
|
||||
[Debugging Possible Layer Issues](LoaderDebugging.md#debugging-possible-layer-issues)
|
||||
section of the [LoaderDebugging.mg](LoaderDebugging.md) document in the docs
|
||||
folder.
|
||||
|
||||
|
||||
## Application Usage of Extensions
|
||||
|
361
docs/LoaderDebugging.md
Normal file
361
docs/LoaderDebugging.md
Normal file
@ -0,0 +1,361 @@
|
||||
<!-- markdownlint-disable MD041 -->
|
||||
[![Khronos Vulkan][1]][2]
|
||||
|
||||
[1]: https://vulkan.lunarg.com/img/Vulkan_100px_Dec16.png "https://www.khronos.org/vulkan/"
|
||||
[2]: https://www.khronos.org/vulkan/
|
||||
|
||||
# Debugging The Vulkan Desktop Loader <!-- omit from toc -->
|
||||
[![Creative Commons][3]][4]
|
||||
|
||||
<!-- Copyright © 2015-2023 LunarG, Inc. -->
|
||||
|
||||
[3]: https://i.creativecommons.org/l/by-nd/4.0/88x31.png "Creative Commons License"
|
||||
[4]: https://creativecommons.org/licenses/by-nd/4.0/
|
||||
## Table of Contents <!-- omit from toc -->
|
||||
|
||||
- [Debugging Issues](#debugging-issues)
|
||||
- [Loader Logging](#loader-logging)
|
||||
- [Debugging Possible Layer Issues](#debugging-possible-layer-issues)
|
||||
- [Enable Layer Logging](#enable-layer-logging)
|
||||
- [Disable Layers](#disable-layers)
|
||||
- [Selectively Re-enable Layers](#selectively-re-enable-layers)
|
||||
- [Allow specific layers to be ignored by VK\_LOADER\_LAYERS\_DISABLE](#allow-specific-layers-to-be-ignored-by-vk_loader_layers_disable)
|
||||
- [Debugging Possible Driver Issues](#debugging-possible-driver-issues)
|
||||
- [Enable Driver Logging](#enable-driver-logging)
|
||||
- [Selectively Enable Specific Drivers](#selectively-enable-specific-drivers)
|
||||
|
||||
## Debugging Issues
|
||||
|
||||
If your application is crashing or behaving weirdly, the loader provides
|
||||
several mechanisms for you to debug the issues.
|
||||
|
||||
**NOTE**: This functionality is all specific to the desktop Vulkan loader and
|
||||
does not work for the Android loader.
|
||||
|
||||
## Loader Logging
|
||||
|
||||
The Vulkan desktop loader has added logging functionality that can be enabled by
|
||||
using the `VK_LOADER_DEBUG` environment variable.
|
||||
The results will be output to the standard output, but will also be passed to
|
||||
any `VK_EXT_debug_utils` messengers present as well.
|
||||
The variable can be set to a comma-delimited list of debug level options which
|
||||
include:
|
||||
|
||||
* error Report any errors encountered by
|
||||
the loader
|
||||
* warn Report any warnings encountered by
|
||||
the loader
|
||||
* info Report info-level
|
||||
messages generated by the loader
|
||||
* debug Report debug-level messages generated by the
|
||||
loader
|
||||
* layer Report all layer-specific messages
|
||||
generated by the loader
|
||||
* driver Report all driver-specific messages
|
||||
generated by the loader
|
||||
* all Report all
|
||||
messages generated by the loader (includes all of the above)
|
||||
|
||||
If you're not sure where the issue comes from, at least set it to output all
|
||||
messages through the "info" level:
|
||||
|
||||
```
|
||||
set VK_LOADER_DEBUG=error,warn,info
|
||||
```
|
||||
|
||||
Then, you can search the list for any errors or warnings that might provide a
|
||||
hint at why you're seeing issues.
|
||||
|
||||
For more info on enabling loader logging, refer to the
|
||||
[Enable Loader Debug Layer Output](LoaderApplicationInterface.md#enable-loader-debug-layer-output)
|
||||
and the
|
||||
[Table of Debug Environment Variables](LoaderInterfaceArchitecture.md#table-of-debug-environment-variables)
|
||||
below.
|
||||
|
||||
## Debugging Possible Layer Issues
|
||||
|
||||
### Enable Layer Logging
|
||||
|
||||
If you suspect a layer issue, set the loader logging to specifically output
|
||||
layer messages in addition to warnings and errors:
|
||||
|
||||
```
|
||||
set VK_LOADER_DEBUG=error,warn,layer
|
||||
```
|
||||
|
||||
Most important layer messages should go out with error or warning levels set,
|
||||
but this will provide more layer-specific info as well such as:
|
||||
* What layers are found
|
||||
* Where they were found
|
||||
* If they are implicit, what environment variables can be used to disable them
|
||||
* If there is any incompatibility with a given layer, this could include:
|
||||
* The layer library file (.so/.dll) wasn't found
|
||||
* The layer library is the wrong bit-depth for the executing application
|
||||
(i.e. 32-bit vs 64-bit)
|
||||
* The layer itself doesn't support the application desired version of Vulkan
|
||||
* If any environment variables are disabling any layers
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
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)
|
||||
```
|
||||
|
||||
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>
|
||||
```
|
||||
|
||||
In this scenario, two layers were used (the same two that were loaded earlier):
|
||||
* `VK_LAYER_MESA_device_select`
|
||||
* `VK_LAYER_KHRONOS_validation`
|
||||
|
||||
This information now shows us that the `VK_LAYER_MESA_device_select` is loaded
|
||||
first, followed by `VK_LAYER_KHRONOS_validation` which will then continue into
|
||||
any available drivers.
|
||||
It also shows that `VK_LAYER_MESA_device_select` is an implicit layer which
|
||||
implies that it wasn't directly enabled by the application.
|
||||
On the other hand, `VK_LAYER_KHRONOS_validation` is shown as an explicit layer
|
||||
which indicates that it was likely enabled by the application.
|
||||
|
||||
### Disable Layers
|
||||
|
||||
**NOTE:** This functionality is only available with Loaders built with version
|
||||
1.3.234 of the Vulkan headers and later.
|
||||
|
||||
Sometimes, implicit layers can cause issues with an application.
|
||||
Because of this, the next step is to try to disable one or more of the listed
|
||||
implicit layers.
|
||||
You can use the filtering environment variables
|
||||
(`VK_LOADER_LAYERS_ENABLE` and `VK_LOADER_LAYERS_DISABLE`) to selectively enable
|
||||
or disable various layers.
|
||||
If you're not sure what to do, try disabling all implicit layers manually by
|
||||
setting `VK_LOADER_LAYERS_DISABLE` to `~implicit~`.
|
||||
|
||||
```
|
||||
set VK_LOADER_LAYERS_DISABLE=~implicit~
|
||||
```
|
||||
|
||||
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'.
|
||||
```
|
||||
|
||||
### Selectively Re-enable Layers
|
||||
|
||||
**NOTE:** This functionality is only available with Loaders built with version
|
||||
1.3.234 of the Vulkan headers and later.
|
||||
|
||||
When trying to diagnose problems caused by layers, it is useful to first disable
|
||||
all layers and re-enable each layer individually.
|
||||
If the problem reappears, then it is immediately clear which layer is the source
|
||||
of the issue.
|
||||
|
||||
For example, from the above given list of disabled layers, let’s selectively
|
||||
re-enable one:
|
||||
|
||||
```
|
||||
set VK_LOADER_LAYERS_DISABLE=~implicit~
|
||||
set VK_LOADER_LAYERS_ENABLE=*AMD*
|
||||
```
|
||||
|
||||
This would keep both the "VK_LAYER_MESA_device_select" and
|
||||
"VK_LAYER_Twitch_Overlay" layers disabled, while enabling the
|
||||
"VK_LAYER_AMD_switchable_graphics_64" layer.
|
||||
If everything continues to work, then the evidence seems to suggest the issue is
|
||||
likely not related to the AMD layer.
|
||||
This would lead to enabling one other layer and trying again:
|
||||
|
||||
```
|
||||
set VK_LOADER_LAYERS_DISABLE=~implicit~
|
||||
set VK_LOADER_LAYERS_ENABLE=*AMD*,*twitch*
|
||||
```
|
||||
|
||||
And so forth.
|
||||
|
||||
For more info on how to use the filtering environment variables, refer to the
|
||||
[Layer Filtering](LoaderLayerInterface.md#layer-filtering) section of the
|
||||
[LoaderLayerInterface](LoaderLayerInterface.md) document.
|
||||
|
||||
## Allow specific layers to be ignored by VK_LOADER_LAYERS_DISABLE
|
||||
|
||||
**NOTE:** VK_LOADER_LAYERS_DISABLE is only available with Loaders built with version
|
||||
1.3.262 of the Vulkan headers and later.
|
||||
|
||||
When using `VK_LOADER_LAYERS_DISABLE` to disable implicit layers, it is possible
|
||||
to allow specific layers to be enabled using `VK_LOADER_LAYERS_ENABLE`.
|
||||
However, this has the effect of *forcing* layers to be enabled, which is not
|
||||
always desired.
|
||||
Implicit layers have the ability to only be enabled when a layer specified
|
||||
environment variable is set, allow for context dependent enablement.
|
||||
`VK_LOADER_LAYERS_ENABLE` ignores that context.
|
||||
|
||||
Thus, a different environment variable is needed: `VK_LOADER_LAYERS_ALLOW`
|
||||
|
||||
The behavior of `VK_LOADER_LAYERS_ALLOW` is similar to `VK_LOADER_LAYERS_ENABLE`
|
||||
except that it does not force a layer to be enabled.
|
||||
The way to think about this environment variable is that every layer matching
|
||||
`VK_LOADER_LAYERS_ALLOW` is excluded from being forcibly disabled by
|
||||
`VK_LOADER_LAYERS_DISABLE`.
|
||||
this allows for implicit layers that are context dependent to be enabled
|
||||
depending on the relevant context instead of force enabling them.
|
||||
|
||||
Example: Disable all implicit layers except for any layers that have steam or
|
||||
mesa in their name.
|
||||
```
|
||||
set VK_LOADER_LAYERS_DISABLE=~implicit~
|
||||
set VK_LOADER_LAYERS_ALLOW=*steam*,*Mesa*
|
||||
```
|
||||
|
||||
## Debugging Possible Driver Issues
|
||||
|
||||
### Enable Driver Logging
|
||||
|
||||
**NOTE:** This functionality is only available with Loaders built with version
|
||||
1.3.234 of the Vulkan headers and later.
|
||||
|
||||
If you suspect a driver issue, set the loader logging to specifically output
|
||||
driver messages:
|
||||
|
||||
```
|
||||
set VK_LOADER_DEBUG=error,warn,driver
|
||||
```
|
||||
|
||||
Most important driver messages should go out with error or warning levels set,
|
||||
but this will provide more driver-specific info as well such as:
|
||||
* What drivers are found
|
||||
* Where they were found
|
||||
* If there is any incompatibility with a given driver
|
||||
* If any environment variables are disabling any of the drivers
|
||||
|
||||
For example, the output of the loader looking for drivers on a Linux system may
|
||||
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"
|
||||
```
|
||||
|
||||
Then when the application selects the device to use, you will see the Vulkan
|
||||
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"
|
||||
```
|
||||
|
||||
|
||||
### Selectively Enable Specific Drivers
|
||||
|
||||
**NOTE:** This functionality is only available with Loaders built with version
|
||||
1.3.234 of the Vulkan headers and later.
|
||||
|
||||
You can now use the filtering environment variables
|
||||
(`VK_LOADER_DRIVERS_SELECT` and `VK_LOADER_DRIVERS_DISABLE`) to control what
|
||||
drivers the loader will attempt to load.
|
||||
For drivers, the string globs passed into the above environment variables will
|
||||
be compared against the driver JSON file name since there is no driver name
|
||||
known to the loader until much later in the Vulkan initialization process.
|
||||
|
||||
For example, to disable all drivers except Nvidia you could do the following:
|
||||
|
||||
```
|
||||
set VK_LOADER_DRIVERS_DISABLE=*
|
||||
set VK_LOADER_DRIVERS_SELECT=*nvidia*
|
||||
```
|
||||
|
||||
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'
|
||||
```
|
||||
|
||||
For more info on how to use the filtering environment variables, refer to the
|
||||
[Driver Filtering](LoaderDriverInterface.md#driver-filtering) section of the
|
||||
[LoaderDriverInterface](LoaderDriverInterface.md) document.
|
||||
|
@ -4,22 +4,25 @@
|
||||
[1]: https://vulkan.lunarg.com/img/Vulkan_100px_Dec16.png "https://www.khronos.org/vulkan/"
|
||||
[2]: https://www.khronos.org/vulkan/
|
||||
|
||||
# Driver interface to the Vulkan Loader
|
||||
# Driver interface to the Vulkan Loader <!-- omit from toc -->
|
||||
[![Creative Commons][3]][4]
|
||||
|
||||
<!-- Copyright © 2015-2021 LunarG, Inc. -->
|
||||
<!-- Copyright © 2015-2023 LunarG, Inc. -->
|
||||
|
||||
[3]: https://i.creativecommons.org/l/by-nd/4.0/88x31.png "Creative Commons License"
|
||||
[4]: https://creativecommons.org/licenses/by-nd/4.0/
|
||||
|
||||
|
||||
## Table of Contents
|
||||
## Table of Contents <!-- omit from toc -->
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Driver Discovery](#driver-discovery)
|
||||
- [Overriding the Default Driver Discovery](#overriding-the-default-driver-discovery)
|
||||
- [Additional Driver Discovery](#additional-driver-discovery)
|
||||
- [Exception for Elevated Privileges](#exception-for-elevated-privileges)
|
||||
- [Driver Filtering](#driver-filtering)
|
||||
- [Driver Select Filtering](#driver-select-filtering)
|
||||
- [Driver Disable Filtering](#driver-disable-filtering)
|
||||
- [Exception for Elevated Privileges](#exception-for-elevated-privileges)
|
||||
- [Examples](#examples)
|
||||
- [On Windows](#on-windows)
|
||||
- [On Linux](#on-linux)
|
||||
@ -32,10 +35,14 @@
|
||||
- [Driver Discovery on macOS](#driver-discovery-on-macos)
|
||||
- [Example macOS Driver Search Path](#example-macos-driver-search-path)
|
||||
- [Additional Settings For Driver Debugging](#additional-settings-for-driver-debugging)
|
||||
- [Driver Discovery using the`VK_LUNARG_direct_driver_loading` extension](#driver-discovery-using-thevk_lunarg_direct_driver_loading-extension)
|
||||
- [How to use `VK_LUNARG_direct_driver_loading`](#how-to-use-vk_lunarg_direct_driver_loading)
|
||||
- [Interactions with other driver discovery mechanisms](#interactions-with-other-driver-discovery-mechanisms)
|
||||
- [Limitations of `VK_LUNARG_direct_driver_loading`](#limitations-of-vk_lunarg_direct_driver_loading)
|
||||
- [Using Pre-Production ICDs or Software Drivers](#using-pre-production-icds-or-software-drivers)
|
||||
- [Driver Discovery on Android](#driver-discovery-on-android)
|
||||
- [Driver Manifest File Format](#driver-manifest-file-format)
|
||||
- [Driver Manifest File Versions](#driver-manifest-file-versions)
|
||||
- [Driver Manifest File Versions](#driver-manifest-file-versions)
|
||||
- [Driver Manifest File Version 1.0.0](#driver-manifest-file-version-100)
|
||||
- [Driver Manifest File Version 1.0.1](#driver-manifest-file-version-101)
|
||||
- [Driver Vulkan Entry Point Discovery](#driver-vulkan-entry-point-discovery)
|
||||
@ -50,18 +57,19 @@
|
||||
- [Handling KHR Surface Objects in WSI Extensions](#handling-khr-surface-objects-in-wsi-extensions)
|
||||
- [Loader and Driver Interface Negotiation](#loader-and-driver-interface-negotiation)
|
||||
- [Windows, Linux and macOS Driver Negotiation](#windows-linux-and-macos-driver-negotiation)
|
||||
- [Version Negotiation Between Loader and Drivers](#version-negotiation-between-loader-and-drivers)
|
||||
- [Version Negotiation Between the Loader and Drivers](#version-negotiation-between-the-loader-and-drivers)
|
||||
- [Interfacing With Legacy Drivers or Loaders](#interfacing-with-legacy-drivers-or-loaders)
|
||||
- [Loader Version 6 Interface Requirements](#loader-version-6-interface-requirements)
|
||||
- [Loader Version 5 Interface Requirements](#loader-version-5-interface-requirements)
|
||||
- [Loader Version 4 Interface Requirements](#loader-version-4-interface-requirements)
|
||||
- [Loader Version 3 Interface Requirements](#loader-version-3-interface-requirements)
|
||||
- [Loader Version 2 Interface Requirements](#loader-version-2-interface-requirements)
|
||||
- [Loader Version 1 Interface Requirements](#loader-version-1-interface-requirements)
|
||||
- [Loader Version 0 Interface Requirements](#loader-version-0-interface-requirements)
|
||||
- [Loader and Driver Interface Version 7 Requirements](#loader-and-driver-interface-version-7-requirements)
|
||||
- [Loader and Driver Interface Version 6 Requirements](#loader-and-driver-interface-version-6-requirements)
|
||||
- [Loader and Driver Interface Version 5 Requirements](#loader-and-driver-interface-version-5-requirements)
|
||||
- [Loader and Driver Interface Version 4 Requirements](#loader-and-driver-interface-version-4-requirements)
|
||||
- [Loader and Driver Interface Version 3 Requirements](#loader-and-driver-interface-version-3-requirements)
|
||||
- [Loader and Driver Interface Version 2 Requirements](#loader-and-driver-interface-version-2-requirements)
|
||||
- [Loader and Driver Interface Version 1 Requirements](#loader-and-driver-interface-version-1-requirements)
|
||||
- [Loader and Driver Interface Version 0 Requirements](#loader-and-driver-interface-version-0-requirements)
|
||||
- [Additional Interface Notes:](#additional-interface-notes)
|
||||
- [Android Driver Negotiation](#android-driver-negotiation)
|
||||
- [Loader implementation of VK_KHR_portability_enumeration](#loader-implementation-of-vk_khr_portability_enumeration)
|
||||
- [Loader implementation of VK\_KHR\_portability\_enumeration](#loader-implementation-of-vk_khr_portability_enumeration)
|
||||
- [Loader and Driver Policy](#loader-and-driver-policy)
|
||||
- [Number Format](#number-format)
|
||||
- [Android Differences](#android-differences)
|
||||
@ -112,8 +120,9 @@ If both `VK_DRIVER_FILES` and `VK_ICD_FILENAMES` environment variables are
|
||||
present, then the newer `VK_DRIVER_FILES` will be used, and the values in
|
||||
`VK_ICD_FILENAMES` will be ignored.
|
||||
|
||||
The `VK_DRIVER_FILES` environment variable is a list of Driver Manifest
|
||||
files, containing the full path to the driver JSON Manifest file.
|
||||
The `VK_DRIVER_FILES` environment variable is a list of paths to Driver Manifest
|
||||
files, containing the full path to the driver JSON Manifest file, and/or paths
|
||||
to folders containing Driver Manifest files.
|
||||
This list is colon-separated on Linux and macOS, and semicolon-separated on
|
||||
Windows.
|
||||
Typically, `VK_DRIVER_FILES` will only contain a full pathname to one info
|
||||
@ -126,7 +135,8 @@ There may be times that a developer wishes to force the loader to use a specific
|
||||
Driver in addition to the standard drivers (without replacing the standard
|
||||
search paths.
|
||||
The `VK_ADD_DRIVER_FILES` environment variable can be used to add a list of
|
||||
Driver Manifest files, containing the full path to the driver JSON Manifest file.
|
||||
Driver Manifest files, containing the full path to the driver JSON Manifest
|
||||
file, and/or paths to folders containing Driver Manifest files.
|
||||
This list is colon-separated on Linux and macOS, and semicolon-separated on
|
||||
Windows.
|
||||
It will be added prior to the standard driver search files.
|
||||
@ -134,11 +144,65 @@ If `VK_DRIVER_FILES` or `VK_ICD_FILENAMES` is present, then
|
||||
`VK_ADD_DRIVER_FILES` will not be used by the loader and any values will be
|
||||
ignored.
|
||||
|
||||
#### Exception for Elevated Privileges
|
||||
### Driver Filtering
|
||||
|
||||
For security reasons, `VK_ICD_FILENAMES`, `VK_DRIVER_FILES` and
|
||||
`VK_ADD_DRIVER_FILES` are all ignored if running the Vulkan application with
|
||||
elevated privileges.
|
||||
**NOTE:** This functionality is only available with Loaders built with version
|
||||
1.3.234 of the Vulkan headers and later.
|
||||
|
||||
The loader supports filter environment variables which can forcibly select and
|
||||
disable known drivers.
|
||||
Known driver manifests are those files that are already found by the loader
|
||||
taking into account default search paths and other environment variables (like
|
||||
`VK_ICD_FILENAMES` or `VK_ADD_DRIVER_FILES`).
|
||||
|
||||
The filter variables will be compared against the driver's manifest filename.
|
||||
|
||||
The filters must also follow the behaviors define in the
|
||||
[Filter Environment Variable Behaviors](LoaderInterfaceArchitecture.md#filter-environment-variable-behaviors)
|
||||
section of the [LoaderLayerInterface](LoaderLayerInterface.md) document.
|
||||
|
||||
#### Driver Select Filtering
|
||||
|
||||
The driver select environment variable `VK_LOADER_DRIVERS_SELECT` is a
|
||||
comma-delimited list of globs to search for in known drivers.
|
||||
|
||||
If a driver is not selected when using the `VK_LOADER_DRIVERS_SELECT` filter,
|
||||
and loader logging is set to emit either warnings or driver messages, then a
|
||||
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'
|
||||
```
|
||||
|
||||
If no drivers are found with a manifest filename that matches any of the
|
||||
provided globs, then no driver is enabled and may result in failures for
|
||||
any Vulkan application that is run.
|
||||
|
||||
#### Driver Disable Filtering
|
||||
|
||||
The driver disable environment variable `VK_LOADER_DRIVERS_DISABLE` is a
|
||||
comma-delimited list of globs to search for in known drivers.
|
||||
|
||||
When a driver is disabled using the `VK_LOADER_DRIVERS_DISABLE` filter, and
|
||||
loader logging is set to emit either warnings or driver messages, then a message
|
||||
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'
|
||||
```
|
||||
|
||||
If no drivers are found with a manifest filename that matches any of the
|
||||
provided globs, then no driver is disabled.
|
||||
|
||||
### Exception for Elevated Privileges
|
||||
|
||||
For security reasons, `VK_ICD_FILENAMES`, `VK_DRIVER_FILES`, and
|
||||
`VK_ADD_DRIVER_FILES` are all 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
|
||||
that do not use elevated privileges.
|
||||
|
||||
@ -292,9 +356,10 @@ middle.
|
||||
This is because the value of 1 for vendor_b_vk.json disables the driver.
|
||||
|
||||
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
|
||||
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).
|
||||
|
||||
The Vulkan loader will open each enabled manifest file found to obtain the name
|
||||
@ -386,7 +451,7 @@ The loader then selects each path, and applies the "/vulkan/icd.d" suffix onto
|
||||
each and looks in that specific folder for manifest files.
|
||||
|
||||
The Vulkan loader will open each manifest file found to obtain the name or
|
||||
pathname of a driver's shared library (".dylib") file.
|
||||
pathname of a driver's shared library (".so") file.
|
||||
|
||||
**NOTE** While the order of folders searched for manifest files is well
|
||||
defined, the order contents are read by the loader in each directory is
|
||||
@ -447,6 +512,17 @@ The order is similar to the search path on Linux with the exception that
|
||||
the application's bundle resources are searched first:
|
||||
`(bundle)/Contents/Resources/`.
|
||||
|
||||
System installed drivers will be ignored if drivers are found inside of the app
|
||||
bundle.
|
||||
This is because there is not a standard mechanism in which to distinguish drivers
|
||||
that happen to be duplicates.
|
||||
For example, MoltenVK is commonly placed inside application bundles.
|
||||
If there exists a system installed MoltenVK, the loader will load both the app
|
||||
bundled and the system installed MoltenVK, leading to potential issues or crashes.
|
||||
Drivers found through environment variables, such as `VK_DRIVER_FILES`, will be
|
||||
used regardless of whether there are bundled drivers present or not.
|
||||
|
||||
|
||||
#### Example macOS Driver Search Path
|
||||
|
||||
For a fictional user "Me" the Driver Manifest search path might look
|
||||
@ -475,6 +551,117 @@ will expose it and cause the Vulkan loader to fail on loading the driver.
|
||||
It is recommended that `LD_BIND_NOW` along with `VK_LOADER_DEBUG=error,warn`
|
||||
to expose any issues.
|
||||
|
||||
### Driver Discovery using the`VK_LUNARG_direct_driver_loading` extension
|
||||
|
||||
The `VK_LUNARG_direct_driver_loading` extension allows for applications to
|
||||
provide a driver or drivers to the Loader during vkCreateInstance.
|
||||
This allows drivers to be included with an application without requiring
|
||||
installation and is capable of being used in any execution environment, such as
|
||||
a process running with elevated privileges.
|
||||
|
||||
When calling `vkEnumeratePhysicalDevices` with the
|
||||
`VK_LUNARG_direct_driver_loading` extension enabled, the `VkPhysicalDevice`s
|
||||
from system installed drivers and environment variable specified drivers will
|
||||
appear before any `VkPhysicalDevice`s that originate from drivers from the
|
||||
`VkDirectDriverLoadingListLUNARG::pDrivers` list.
|
||||
|
||||
#### How to use `VK_LUNARG_direct_driver_loading`
|
||||
|
||||
To use this extension, it must first be enabled on the VkInstance.
|
||||
This requires enabling the `VK_LUNARG_direct_driver_loading` extension through
|
||||
the `enabledExtensionCount` and `ppEnabledExtensionNames`members of
|
||||
`VkInstanceCreateInfo`.
|
||||
|
||||
```c
|
||||
const char* extensions[] = {VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME, <other extensions>};
|
||||
VkInstanceCreateInfo instance_create_info = {};
|
||||
instance_create_info.enabledExtensionCount = <size of extension list>;
|
||||
instance_create_info.ppEnabledExtensionNames = extensions;
|
||||
```
|
||||
|
||||
The `VkDirectDriverLoadingInfoLUNARG` structure contains a
|
||||
`VkDirectDriverLoadingFlagsLUNARG` member (reserved for future use) and a
|
||||
`PFN_vkGetInstanceProcAddrLUNARG` member which provides the loader with the
|
||||
function pointer for the driver's `vkGetInstanceProcAddr`.
|
||||
|
||||
The `VkDirectDriverLoadingListLUNARG` structure contains a count and pointer
|
||||
members which provide the size of and pointer to an application provided array of
|
||||
`VkDirectDriverLoadingInfoLUNARG` structures.
|
||||
|
||||
Creating those structures looks like the following
|
||||
```c
|
||||
VkDirectDriverLoadingInfoLUNARG direct_loading_info = {};
|
||||
direct_loading_info.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG
|
||||
direct_loading_info.pfnGetInstanceProcAddr = <put the PFN_vkGetInstanceProcAddr of the driver here>
|
||||
|
||||
VkDirectDriverLoadingListLUNARG direct_driver_list = {};
|
||||
direct_driver_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
|
||||
direct_driver_list.mode = VK_DIRECT_DRIVER_LOADING_MODE_INCLUSIVE_LUNARG; // or VK_DIRECT_DRIVER_LOADING_MODE_EXCLUSIVE_LUNARG
|
||||
direct_driver_list.driverCount = 1;
|
||||
direct_driver_list.pDrivers = &direct_loading_info; // can include multiple drivers here if so desired
|
||||
```
|
||||
|
||||
The `VkDirectDriverLoadingListLUNARG` structure contains the enum
|
||||
`VkDirectDriverLoadingModeLUNARG`.
|
||||
There are two modes:
|
||||
* `VK_DIRECT_DRIVER_LOADING_MODE_EXCLUSIVE_LUNARG` - specifies that the only drivers
|
||||
to be loaded will come from the `VkDirectDriverLoadingListLUNARG` structure.
|
||||
* `VK_DIRECT_DRIVER_LOADING_MODE_INCLUSIVE_LUNARG` - specifies that drivers
|
||||
from the `VkDirectDriverLoadingModeLUNARG` structure will be used in addition to
|
||||
any system installed drivers and environment variable specified drivers.
|
||||
|
||||
|
||||
|
||||
Then, the `VkDirectDriverLoadingListLUNARG` structure *must* be appended to the
|
||||
`pNext` chain of `VkInstanceCreateInfo`.
|
||||
|
||||
```c
|
||||
instance_create_info.pNext = (const void*)&direct_driver_list;
|
||||
```
|
||||
|
||||
Finally, create the instance like normal.
|
||||
|
||||
#### Interactions with other driver discovery mechanisms
|
||||
|
||||
If the `VK_DIRECT_DRIVER_LOADING_MODE_EXCLUSIVE_LUNARG` mode is specified in the
|
||||
`VkDirectDriverLoadingListLUNARG` structure, then no system installed drivers
|
||||
are loaded.
|
||||
This applies equally to all platforms.
|
||||
Additionally, the following environment variables have no effect:
|
||||
|
||||
* `VK_DRIVER_FILES`
|
||||
* `VK_ICD_FILENAMES`
|
||||
* `VK_ADD_DRIVER_FILES`
|
||||
* `VK_LOADER_DRIVERS_SELECT`
|
||||
* `VK_LOADER_DRIVERS_DISABLE`
|
||||
|
||||
Exclusive mode will also disable MacOS bundle manifest discovery of drivers.
|
||||
|
||||
#### Limitations of `VK_LUNARG_direct_driver_loading`
|
||||
|
||||
Because `VkDirectDriverLoadingListLUNARG` is provided to the loader at instance
|
||||
creation, there is no mechanism for the loader to query the list of instance
|
||||
extensions that originate from `VkDirectDriverLoadingListLUNARG` drivers during
|
||||
`vkEnumerateInstanceExtensionProperties`.
|
||||
Applications can instead manually load the `vkEnumerateInstanceExtensionProperties`
|
||||
function pointer directly from the drivers the application provides to the loader
|
||||
using the `pfnGetInstanceProcAddrLUNARG` for each driver.
|
||||
Then the application can call each driver's
|
||||
`vkEnumerateInstanceExtensionProperties` and append non-duplicate entriees to the
|
||||
list from the loader's `vkEnumerateInstanceExtensionProperties` to get the full
|
||||
list of supported instance extensions.
|
||||
Alternatively, because the Application is providing drivers, it is reasonable for
|
||||
the application to already know which instance extensions are available with the
|
||||
provided drivers, preventing the need to manually query them.
|
||||
|
||||
However, there are limitations.
|
||||
If there are any active implicit layers which intercept
|
||||
`vkEnumerateInstanceExtensionProperties` to remove unsupported extensions, then
|
||||
those layers will not be able to remove unsupported extensions from drivers that
|
||||
are provided by the application.
|
||||
This is due to `vkEnumerateInstanceExtensionProperties` not having a mechanism
|
||||
to extend it.
|
||||
|
||||
|
||||
### Using Pre-Production ICDs or Software Drivers
|
||||
|
||||
@ -510,7 +697,8 @@ The loader will load the driver via `hw_get_module` with the ID of "vulkan".
|
||||
|
||||
## Driver Manifest File Format
|
||||
|
||||
The following section discusses the details of the Driver Manifest JSON file format.
|
||||
The following section discusses the details of the Driver Manifest JSON file
|
||||
format.
|
||||
The JSON file itself does not have any requirements for naming.
|
||||
The only requirement is that the extension suffix of the file is ".json".
|
||||
|
||||
@ -569,18 +757,18 @@ Here is an example driver JSON Manifest file:
|
||||
<td>"api_version" </td>
|
||||
<td>The major.minor.patch version number of the maximum Vulkan API supported
|
||||
by the driver.
|
||||
However, just because the driver supports the specific Vulkan API version,
|
||||
it does not guarantee that the hardware on a user's system can support
|
||||
that version.
|
||||
However, just because the driver supports the specific Vulkan API
|
||||
version, it does not guarantee that the hardware on a user's system can
|
||||
support that version.
|
||||
Information on what the underlying physical device can support must be
|
||||
queried by the user using the <i>vkGetPhysicalDeviceProperties</i> API call.
|
||||
<br/>
|
||||
queried by the user using the <i>vkGetPhysicalDeviceProperties</i> API
|
||||
call.<br/>
|
||||
For example: 1.0.33.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>"is_portability_driver" </td>
|
||||
<td>Defines whether the driver contains any VkPhysicalDevices which implement
|
||||
the VK_KHR_portability_subset extension.<br/>
|
||||
<td>Defines whether the driver contains any VkPhysicalDevices which
|
||||
implement the VK_KHR_portability_subset extension.<br/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -742,11 +930,17 @@ missing support for this extension.
|
||||
## Driver Unknown Physical Device Extensions
|
||||
|
||||
Drivers that implement entrypoints which take a `VkPhysicalDevice` as the first
|
||||
parameter *should* support `vk_icdGetPhysicalDeviceProcAddr`. This function
|
||||
is added to the Driver Interface Version 4 and allows the loader to distinguish
|
||||
between entrypoints which take `VkDevice` and `VkPhysicalDevice` as the first
|
||||
parameter. This allows the loader to properly support entrypoints that are
|
||||
unknown to it gracefully.
|
||||
parameter *should* support `vk_icdGetPhysicalDeviceProcAddr`.
|
||||
This function is added to the Loader and Driver Driver Interface Version 4,
|
||||
allowing the loader to distinguish between entrypoints which take `VkDevice`
|
||||
and `VkPhysicalDevice` as the first parameter.
|
||||
This allows the loader to properly support entrypoints that are unknown to it
|
||||
gracefully.
|
||||
This entry point is not a part of the Vulkan API itself, only a private
|
||||
interface between the loader and drivers.
|
||||
Note: Loader and Driver Interface Version 7 makes exporting
|
||||
`vk_icdGetPhysicalDeviceProcAddr` optional.
|
||||
Instead, drivers *must* expose it through `vk_icdGetInstanceProcAddr`.
|
||||
|
||||
```cpp
|
||||
PFN_vkVoidFunction
|
||||
@ -762,13 +956,13 @@ In this way, it compares "pName" to every physical device function supported in
|
||||
the driver.
|
||||
|
||||
Implementations of the function should have the following behavior:
|
||||
* If `pName` is the name of a Vulkan API entrypoint that takes a `VkPhysicalDevice`
|
||||
as its primary dispatch handle, and the driver supports the entrypoint, then
|
||||
the driver **must** return the valid function pointer to the driver's
|
||||
implementation of that entrypoint.
|
||||
* If `pName` is the name of a Vulkan API entrypoint that takes something other than
|
||||
a `VkPhysicalDevice` as its primary dispatch handle, then the driver **must**
|
||||
return `NULL`.
|
||||
* If `pName` is the name of a Vulkan API entrypoint that takes a
|
||||
`VkPhysicalDevice` as its primary dispatch handle, and the driver supports the
|
||||
entrypoint, then the driver **must** return the valid function pointer to the
|
||||
driver's implementation of that entrypoint.
|
||||
* If `pName` is the name of a Vulkan API entrypoint that takes something other
|
||||
than a `VkPhysicalDevice` as its primary dispatch handle, then the driver
|
||||
**must** return `NULL`.
|
||||
* If the driver is unaware of any entrypoint with the name `pName`, it **must**
|
||||
return `NULL`.
|
||||
|
||||
@ -782,7 +976,9 @@ function.
|
||||
|
||||
If a driver does implement this support, it must export the function from the
|
||||
driver library using the name `vk_icdGetPhysicalDeviceProcAddr` so that the
|
||||
symbol can be located through the platform's dynamic linking utilities.
|
||||
symbol can be located through the platform's dynamic linking utilities, or if
|
||||
the driver supports Loader and Driver Interface Version 7, exposed through
|
||||
`vk_icdGetInstanceProcAddr` instead.
|
||||
|
||||
The behavior of the loader's `vkGetInstanceProcAddr` with support for the
|
||||
`vk_icdGetPhysicalDeviceProcAddr` function is as follows:
|
||||
@ -848,10 +1044,15 @@ preference will be listed first.
|
||||
This mechanism does not force an application to use any particular GPU —
|
||||
it merely changes the order in which they are presented.
|
||||
|
||||
This mechanism requires that a driver provide version 6 of the loader/driver
|
||||
interface.
|
||||
Version 6 of this interface defines a new exported function that the driver may
|
||||
provide on Windows:
|
||||
This mechanism requires that a driver provide The Loader and Driver Interface
|
||||
Version 6.
|
||||
This version defines a new exported function, `vk_icdEnumerateAdapterPhysicalDevices`,
|
||||
detailed below, that Drivers may provide on Windows.
|
||||
This entry point is not a part of the Vulkan API itself, only a private
|
||||
interface between the loader and drivers.
|
||||
Note: Loader and Driver Interface Version 7 makes exporting
|
||||
`vk_icdEnumerateAdapterPhysicalDevices` optional.
|
||||
Instead, drivers *must* expose it through `vk_icdGetInstanceProcAddr`.
|
||||
|
||||
```c
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
@ -862,6 +1063,7 @@ VKAPI_ATTR VkResult VKAPI_CALL
|
||||
VkPhysicalDevice* pPhysicalDevices);
|
||||
```
|
||||
|
||||
|
||||
This function takes an adapter LUID as input, and enumerates all Vulkan physical
|
||||
devices that are associated with that LUID.
|
||||
This works in the same way as other Vulkan enumerations — if
|
||||
@ -886,6 +1088,14 @@ of Windows 10 that support GPU selection through the OS.
|
||||
Other platforms may be included in the future, but they will require separate
|
||||
platform-specific interfaces.
|
||||
|
||||
A requirement of `vk_icdEnumerateAdapterPhysicalDevices` is that it *must*
|
||||
return the same `VkPhysicalDevice` handle values for the same physical
|
||||
devices that are returned by `vkEnumeratePhysicalDevices`.
|
||||
This is because the loader calls both functions on the driver then
|
||||
de-duplicates the physical devices using the `VkPhysicalDevice` handles.
|
||||
Since not all physical devices in a driver will have a LUID, such as for
|
||||
software implementations, this step is necessary to allow drivers to
|
||||
enumerate all available physical devices.
|
||||
|
||||
## Driver Dispatchable Object Creation
|
||||
|
||||
@ -966,8 +1176,8 @@ appropriate `VkIcdSurfaceXXX` structure.
|
||||
|
||||
The driver may choose to handle `VkSurfaceKHR` object creation instead.
|
||||
If a driver desires to handle creating and destroying it must do the following:
|
||||
1. Support version 3 or newer of the loader/driver interface.
|
||||
2. Export and handle all functions that take in a `VkSurfaceKHR` object,
|
||||
1. Support Loader and Driver Interface Version 3 or newer.
|
||||
2. Expose and handle all functions that take in a `VkSurfaceKHR` object,
|
||||
including:
|
||||
* `vkCreateXXXSurfaceKHR`
|
||||
* `vkGetPhysicalDeviceSurfaceSupportKHR`
|
||||
@ -1010,13 +1220,16 @@ These additional requirements are versioned to allow flexibility in the future.
|
||||
### Windows, Linux and macOS Driver Negotiation
|
||||
|
||||
|
||||
#### Version Negotiation Between Loader and Drivers
|
||||
#### Version Negotiation Between the Loader and Drivers
|
||||
|
||||
All drivers (supporting interface version 2 or higher) must export the
|
||||
following function that is used for determination of the interface version that
|
||||
will be used.
|
||||
All drivers supporting Loader and Driver Interface Version 2 or higher must
|
||||
export the following function that is used for determination of the interface
|
||||
version that will be used.
|
||||
This entry point is not a part of the Vulkan API itself, only a private
|
||||
interface between the loader and drivers.
|
||||
Note: Loader and Driver Interface Version 7 makes exporting
|
||||
`vk_icdNegotiateLoaderICDInterfaceVersion` optional.
|
||||
Instead, drivers *must* expose it through `vk_icdGetInstanceProcAddr`.
|
||||
|
||||
```cpp
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
@ -1060,19 +1273,50 @@ during enumeration.
|
||||
|
||||
#### Interfacing With Legacy Drivers or Loaders
|
||||
|
||||
If a loader sees that a driver does not export the
|
||||
If a loader sees that a driver does not export or expose the
|
||||
`vk_icdNegotiateLoaderICDInterfaceVersion` function, then the loader assumes the
|
||||
corresponding driver only supports either interface version 0 or 1.
|
||||
|
||||
From the other side of the interface, if a driver sees a call to
|
||||
`vk_icdGetInstanceProcAddr` before a call to
|
||||
`vk_icdNegotiateLoaderICDInterfaceVersion`, then it knows that loader making the
|
||||
calls is a legacy loader supporting version 0 or 1.
|
||||
If the loader calls `vk_icdGetInstanceProcAddr` first, it supports at least
|
||||
version 1.
|
||||
`vk_icdNegotiateLoaderICDInterfaceVersion`, then the loader is either a legacy
|
||||
loader with only support for interface version 0 or 1, or the loader is using
|
||||
interface version 7 or newer.
|
||||
|
||||
If the first call to `vk_icdGetInstanceProcAddr` is to query for
|
||||
`vk_icdNegotiateLoaderICDInterfaceVersion`, then that means the loader is using
|
||||
interface version 7.
|
||||
This only occurs when the driver does not export
|
||||
`vk_icdNegotiateLoaderICDInterfaceVersion`.
|
||||
Drivers which export `vk_icdNegotiateLoaderICDInterfaceVersion` will have it
|
||||
called first.
|
||||
|
||||
If the first call to `vk_icdGetInstanceProcAddr` is **not** querying for
|
||||
`vk_icdNegotiateLoaderICDInterfaceVersion`, then loader is a legacy loader only
|
||||
which supports version 0 or 1.
|
||||
In this case, if the loader calls `vk_icdGetInstanceProcAddr` first, it supports
|
||||
at least interface version 1.
|
||||
Otherwise, the loader only supports version 0.
|
||||
|
||||
#### Loader Version 6 Interface Requirements
|
||||
#### Loader and Driver Interface Version 7 Requirements
|
||||
|
||||
Version 7 relaxes the requirement that Loader and Driver Interface functions
|
||||
must be exported.
|
||||
Instead, it only requires that those functions be queryable through
|
||||
`vk_icdGetInstanceProcAddr`.
|
||||
The functions are:
|
||||
`vk_icdNegotiateLoaderICDInterfaceVersion`
|
||||
`vk_icdGetPhysicalDeviceProcAddr`
|
||||
`vk_icdEnumerateAdapterPhysicalDevices` (Windows only)
|
||||
These functions are considered global for the purposes of retrieval, so the
|
||||
`VkInstance` parameter of `vk_icdGetInstanceProcAddr` will be **NULL**.
|
||||
While exporting these functions is no longer a requirement, drivers may still
|
||||
export them for compatibility with older loaders.
|
||||
The changes in this version allow drivers provided through the
|
||||
`VK_LUNARG_direct_driver_loading` extension to support the entire Loader and
|
||||
Driver Interface.
|
||||
|
||||
#### Loader and Driver Interface Version 6 Requirements
|
||||
|
||||
Version 6 provides a mechanism to allow the loader to sort physical devices.
|
||||
The loader will only attempt to sort physical devices on a driver if version 6
|
||||
@ -1080,9 +1324,9 @@ of the interface is supported.
|
||||
This version provides the `vk_icdEnumerateAdapterPhysicalDevices` function
|
||||
defined earlier in this document.
|
||||
|
||||
#### Loader Version 5 Interface Requirements
|
||||
#### Loader and Driver Interface Version 5 Requirements
|
||||
|
||||
Version 5 of the loader/driver interface has no changes to the actual interface.
|
||||
This interface version has no changes to the actual interface.
|
||||
If the loader requests interface version 5 or greater, it is simply
|
||||
an indication to drivers that the loader is now evaluating whether the API
|
||||
Version info passed into vkCreateInstance is a valid version for the loader.
|
||||
@ -1139,10 +1383,9 @@ Here is a table of the expected behaviors:
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
#### Loader Version 4 Interface Requirements
|
||||
#### Loader and Driver Interface Version 4 Requirements
|
||||
|
||||
The major change to version 4 of the loader/driver interface is the
|
||||
support of
|
||||
The major change to version 4 of this interface version is the support of
|
||||
[Unknown Physical Device Extensions](#driver-unknown-physical-device-extensions)
|
||||
using the `vk_icdGetPhysicalDeviceProcAddr` function.
|
||||
This function is purely optional.
|
||||
@ -1152,16 +1395,16 @@ Otherwise, the loader will continue to treat any unknown functions as VkDevice
|
||||
functions and cause invalid behavior.
|
||||
|
||||
|
||||
#### Loader Version 3 Interface Requirements
|
||||
#### Loader and Driver Interface Version 3 Requirements
|
||||
|
||||
The primary change that occurred in version 3 of the loader/driver interface was
|
||||
to allow a driver to handle creation/destruction of their own KHR_surfaces.
|
||||
The primary change that occurred in this interface version is to allow a driver
|
||||
to handle creation and destruction of their own KHR_surfaces.
|
||||
Up until this point, the loader created a surface object that was used by all
|
||||
drivers.
|
||||
However, some drivers may want to provide their own surface handles.
|
||||
If a driver chooses to enable this support, it must export support for version 3
|
||||
of the loader/driver interface, as well as any Vulkan function that uses a
|
||||
KHR_surface handle, such as:
|
||||
However, some drivers *may* want to provide their own surface handles.
|
||||
If a driver chooses to enable this support, it must support Loader and Driver
|
||||
Interface Version 3, as well as any Vulkan function that uses a `VkSurfaceKHR`
|
||||
handle, such as:
|
||||
- `vkCreateXXXSurfaceKHR` (where XXX is the platform-specific identifier [i.e.
|
||||
`vkCreateWin32SurfaceKHR` for Windows])
|
||||
- `vkDestroySurfaceKHR`
|
||||
@ -1171,25 +1414,24 @@ KHR_surface handle, such as:
|
||||
- `vkGetPhysicalDeviceSurfaceFormatsKHR`
|
||||
- `vkGetPhysicalDeviceSurfacePresentModesKHR`
|
||||
|
||||
A driver can still choose to not take advantage of this functionality
|
||||
by simply not exposing the above `vkCreateXXXSurfaceKHR` and
|
||||
A driver which does not participate in this functionality can opt out by
|
||||
simply not exposing the above `vkCreateXXXSurfaceKHR` and
|
||||
`vkDestroySurfaceKHR` functions.
|
||||
|
||||
|
||||
#### Loader Version 2 Interface Requirements
|
||||
#### Loader and Driver Interface Version 2 Requirements
|
||||
|
||||
Version 2 interface is the first to implement the new
|
||||
`vk_icdNegotiateLoaderICDInterfaceVersion` functionality, see
|
||||
[Version Negotiation Between Loader and Drivers](#version-negotiation-between-loader-and-drivers) for more details
|
||||
on that function.
|
||||
Interface Version 2 requires that drivers export
|
||||
`vk_icdNegotiateLoaderICDInterfaceVersion`.
|
||||
For more information, see [Version Negotiation Between Loader and Drivers](#version-negotiation-between-loader-and-drivers).
|
||||
|
||||
Additional, version 2 was the first to define that Vulkan dispatchable objects
|
||||
created by drivers must now be created in accordance to the
|
||||
Additional, version 2 requires that Vulkan dispatchable objects created by
|
||||
drivers must be created in accordance to the
|
||||
[Driver Dispatchable Object Creation](#driver-dispatchable-object-creation)
|
||||
section.
|
||||
|
||||
|
||||
#### Loader Version 1 Interface Requirements
|
||||
#### Loader and Driver Interface Version 1 Requirements
|
||||
|
||||
Version 1 of the interface added the driver-specific entry-point
|
||||
`vk_icdGetInstanceProcAddr`.
|
||||
@ -1204,14 +1446,14 @@ No other entry-points need to be exported by the driver as the loader will query
|
||||
the appropriate function pointers using that.
|
||||
|
||||
|
||||
#### Loader Version 0 Interface Requirements
|
||||
#### Loader and Driver Interface Version 0 Requirements
|
||||
|
||||
Version 0 interface does not support either `vk_icdGetInstanceProcAddr` or
|
||||
Version 0 does not support either `vk_icdGetInstanceProcAddr` or
|
||||
`vk_icdNegotiateLoaderICDInterfaceVersion`.
|
||||
Because of this, the loader will assume the driver supports only version 0 of
|
||||
the interface unless one of those functions exists.
|
||||
|
||||
Additionally, for version 0, the driver must expose at least the following core
|
||||
Additionally, for Version 0, the driver must expose at least the following core
|
||||
Vulkan entry-points so the loader may build up the interface to the driver:
|
||||
|
||||
- The function `vkGetInstanceProcAddr` **must be exported** in the driver
|
||||
@ -1257,12 +1499,13 @@ manifest files used by the Windows, Linux and macOS loaders.
|
||||
The loader implements the `VK_KHR_portability_enumeration` instance extension,
|
||||
which filters out any drivers that report support for the portability subset
|
||||
device extension. Unless the application explicitly requests enumeration of
|
||||
portability devices by setting the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR
|
||||
bit in the VkInstanceCreateInfo::flags, the loader does not load any drivers
|
||||
that declare themselves to be portability drivers.
|
||||
portability devices by setting the
|
||||
`VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` bit in the
|
||||
VkInstanceCreateInfo::flags, the loader does not load any drivers that declare
|
||||
themselves to be portability drivers.
|
||||
|
||||
Drivers declare whether they are portability drivers or not in the Driver Manifest
|
||||
Json file, with the `is_portability_driver` boolean field.
|
||||
Drivers declare whether they are portability drivers or not in the Driver
|
||||
Manifest Json file, with the `is_portability_driver` boolean field.
|
||||
[More information here](#driver-manifest-file-version-101)
|
||||
|
||||
The initial support for this extension only reported errors when an application
|
||||
@ -1292,8 +1535,8 @@ best experience to end-users and developers.
|
||||
|
||||
### Number Format
|
||||
|
||||
Loader/Driver policy items start with the prefix `LDP_` (short for
|
||||
Loader/Driver Policy) which is followed by an identifier based on what
|
||||
Loader and Driver policy items start with the prefix `LDP_` (short for
|
||||
Loader and Driver Policy) which is followed by an identifier based on what
|
||||
component the policy is targeted against.
|
||||
In this case there are only two possible components:
|
||||
- Drivers: which will have the string `DRIVER_` as part of the policy number.
|
||||
@ -1355,7 +1598,7 @@ Android Vulkan documentation</a>.
|
||||
<tr>
|
||||
<td><small><b>LDP_DRIVER_3</b></small></td>
|
||||
<td>A driver <b>must</b> be able to negotiate a supported version of the
|
||||
loader/driver interface with the loader in accordance with the stated
|
||||
Loader and Driver Interface with the loader in accordance with the stated
|
||||
negotiation process.
|
||||
</td>
|
||||
<td>The driver will not be loaded.</td>
|
||||
@ -1397,14 +1640,15 @@ Android Vulkan documentation</a>.
|
||||
possibly including crashes or corruption.
|
||||
</td>
|
||||
<td><small>
|
||||
<a href="https://github.com/KhronosGroup/VK-GL-CTS/blob/master/external/openglcts/README.md">
|
||||
<a href="https://github.com/KhronosGroup/VK-GL-CTS/blob/main/external/openglcts/README.md">
|
||||
Vulkan CTS Documentation</a>
|
||||
</small>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small><b>LDP_DRIVER_6</b></small></td>
|
||||
<td>Removed - See <a href="#removed-driver-policies">Removed Driver Policies</a>
|
||||
<td>Removed - See
|
||||
<a href="#removed-driver-policies">Removed Driver Policies</a>
|
||||
</td>
|
||||
<td>-</td>
|
||||
<td>-</td>
|
||||
@ -1414,7 +1658,7 @@ Android Vulkan documentation</a>.
|
||||
<tr>
|
||||
<td><small><b>LDP_DRIVER_7</b></small></td>
|
||||
<td>If a driver desires to support Vulkan API 1.1 or newer, it <b>must</b>
|
||||
expose support of Vulkan loader/driver interface 5 or newer.
|
||||
expose support for Loader and Driver Interface Version 5 or newer.
|
||||
</td>
|
||||
<td>The driver will be used when it shouldn't be and will cause
|
||||
undefined behavior possibly including crashes or corruption.
|
||||
@ -1429,7 +1673,7 @@ Android Vulkan documentation</a>.
|
||||
<tr>
|
||||
<td><small><b>LDP_DRIVER_8</b></small></td>
|
||||
<td>If a driver wishes to handle its own <i>VkSurfaceKHR</i> object
|
||||
creation, it <b>must</b> implement loader/driver interface version 3 or
|
||||
creation, it <b>must</b> implement the Loader and Driver Interface Version 3 or
|
||||
newer and support querying all the relevant surface functions via
|
||||
<i>vk_icdGetInstanceProcAddr</i>.
|
||||
</td>
|
||||
@ -1443,15 +1687,15 @@ Android Vulkan documentation</a>.
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small><b>LDP_DRIVER_9</b></small></td>
|
||||
<td>If a driver negotiation results in it using loader/driver interface
|
||||
version 4 or earlier, the driver <b>must</b> verify that the Vulkan API
|
||||
version passed into <i>vkCreateInstance</i> (through
|
||||
<td>If version negotiation results in a driver using the Loader
|
||||
and Driver Interface Version 4 or earlier, the driver <b>must</b> verify
|
||||
that the Vulkan API version passed into <i>vkCreateInstance</i> (through
|
||||
<i>VkInstanceCreateInfo</i>’s <i>VkApplicationInfo</i>'s
|
||||
<i>apiVersion</i>) is supported.
|
||||
If the requested Vulkan API version can not be supported by the driver,
|
||||
it <b>must</b> return <b>VK_ERROR_INCOMPATIBLE_DRIVER</b>. <br/>
|
||||
This is not required if the interface version is 5 or newer because the
|
||||
responsibility for this check then falls on the loader.
|
||||
loader is responsible for this check.
|
||||
</td>
|
||||
<td>The behavior is undefined and may result in crashes or corruption.</td>
|
||||
<td>No</td>
|
||||
@ -1463,11 +1707,13 @@ Android Vulkan documentation</a>.
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small><b>LDP_DRIVER_10</b></small></td>
|
||||
<td>If a driver negotiation results in it using loader/driver interface
|
||||
version 5 or newer, the driver <b>must</b> ignore the Vulkan API version
|
||||
<td>If version negotiation results in a driver using the Loader and Driver Interface
|
||||
Version 5 or newer, the driver <b>must</b> not return
|
||||
<b>VK_ERROR_INCOMPATIBLE_DRIVER</b> if the Vulkan API version
|
||||
passed into <i>vkCreateInstance</i> (through
|
||||
<i>VkInstanceCreateInfo</i>’s <i>VkApplicationInfo</i>'s
|
||||
<i>apiVersion</i>).
|
||||
<i>apiVersion</i>) is not supported by the driver. This check is performed
|
||||
by the loader on the drivers behalf.
|
||||
</td>
|
||||
<td>The behavior is undefined and may result in crashes or corruption.</td>
|
||||
<td>No</td>
|
||||
@ -1515,7 +1761,8 @@ Android Vulkan documentation</a>.
|
||||
|
||||
#### Removed Driver Policies
|
||||
|
||||
These policies were in the loader source at some point but later removed. They are documented here for reference.
|
||||
These policies were in the loader source at some point but later removed.
|
||||
They are documented here for reference.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@ -1525,7 +1772,7 @@ These policies were in the loader source at some point but later removed. They a
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small><b>LDP_DRIVER_6</b></small></td>
|
||||
<td>A driver supporting loader/driver interface version 1 or newer <b>must
|
||||
<td>A driver supporting Loader and Driver Interface Version 1 or newer <b>must
|
||||
not</b> directly export standard Vulkan entry-points.
|
||||
<br/>
|
||||
Instead, it <b>must</b> export only the loader interface functions
|
||||
@ -1611,7 +1858,7 @@ These policies were in the loader source at some point but later removed. They a
|
||||
<tr>
|
||||
<td><small><b>LDP_LOADER_5</b></small></td>
|
||||
<td>A loader <b>must</b> ignore any driver for which a compatible
|
||||
loader/driver interface version can not be negotiated.
|
||||
Loader and Driver Interface Version can not be negotiated.
|
||||
</td>
|
||||
<td>The loader would load a driver improperly resulting in undefined
|
||||
behavior possibly including crashes or corruption.
|
||||
@ -1624,16 +1871,16 @@ These policies were in the loader source at some point but later removed. They a
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small><b>LDP_LOADER_6</b></small></td>
|
||||
<td>If a driver negotiation results in it using loader/driver interface
|
||||
version 5 or newer, a loader <b>must</b> verify that the Vulkan API
|
||||
version passed into <i>vkCreateInstance</i> (through
|
||||
<td>If a driver negotiation results in the loader using Loader and Driver
|
||||
Interface Version 5 or newer, a loader <b>must</b> verify that the Vulkan
|
||||
API version passed into <i>vkCreateInstance</i> (through
|
||||
<i>VkInstanceCreateInfo</i>’s <i>VkApplicationInfo</i>'s
|
||||
<i>apiVersion</i>) is supported by at least one driver.
|
||||
If the requested Vulkan API version can not be supported by any
|
||||
driver, the loader <b>must</b> return
|
||||
<b>VK_ERROR_INCOMPATIBLE_DRIVER</b>.<br/>
|
||||
This is not required if the interface version is 4 or earlier because
|
||||
the responsibility for this check then falls on the drivers.
|
||||
This is not required if the Loader and Driver Interface Version is 4 or
|
||||
earlier because the responsibility for this check falls on the drivers.
|
||||
</td>
|
||||
<td>The behavior is undefined and may result in crashes or corruption.</td>
|
||||
<td>No</td>
|
||||
|
@ -4,14 +4,14 @@
|
||||
[1]: https://vulkan.lunarg.com/img/Vulkan_100px_Dec16.png "https://www.khronos.org/vulkan/"
|
||||
[2]: https://www.khronos.org/vulkan/
|
||||
|
||||
# Architecture of the Vulkan Loader Interfaces
|
||||
# Architecture of the Vulkan Loader Interfaces <!-- omit from toc -->
|
||||
[![Creative Commons][3]][4]
|
||||
|
||||
<!-- Copyright © 2015-2021 LunarG, Inc. -->
|
||||
<!-- Copyright © 2015-2023 LunarG, Inc. -->
|
||||
|
||||
[3]: https://i.creativecommons.org/l/by-nd/4.0/88x31.png "Creative Commons License"
|
||||
[4]: https://creativecommons.org/licenses/by-nd/4.0/
|
||||
## Table of Contents
|
||||
## Table of Contents <!-- omit from toc -->
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Who Should Read This Document](#who-should-read-this-document)
|
||||
@ -38,8 +38,17 @@
|
||||
- [Application Interface to the Loader](#application-interface-to-the-loader)
|
||||
- [Layer Interface with the Loader](#layer-interface-with-the-loader)
|
||||
- [Driver Interface With the Loader](#driver-interface-with-the-loader)
|
||||
- [Debugging Issues](#debugging-issues)
|
||||
- [Loader Policies](#loader-policies)
|
||||
- [Filter Environment Variable Behaviors](#filter-environment-variable-behaviors)
|
||||
- [Comparison Strings](#comparison-strings)
|
||||
- [Comma-Delimited Lists](#comma-delimited-lists)
|
||||
- [Globs](#globs)
|
||||
- [Case-Insensitive](#case-insensitive)
|
||||
- [Environment Variable Priority](#environment-variable-priority)
|
||||
- [Table of Debug Environment Variables](#table-of-debug-environment-variables)
|
||||
- [Active Environment Variables](#active-environment-variables)
|
||||
- [Deprecated Environment Variables](#deprecated-environment-variables)
|
||||
- [Glossary of Terms](#glossary-of-terms)
|
||||
|
||||
## Overview
|
||||
@ -217,7 +226,7 @@ In the future, VkConfig may have additional interactions with the Vulkan
|
||||
loader.
|
||||
|
||||
More details on VkConfig can be found in its
|
||||
[GitHub documentation](https://github.com/LunarG/VulkanTools/blob/master/vkconfig/README.md).
|
||||
[GitHub documentation](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md).
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
@ -374,7 +383,7 @@ layers to marshall the appropriate information to all available drivers.
|
||||
For example, the diagram below represents what happens in the call chain for
|
||||
`vkCreateInstance`.
|
||||
After initializing the chain, the loader calls into the first layer's
|
||||
`vkCreateInstance`, which will call the next layer's `vkCreateInstance
|
||||
`vkCreateInstance`, which will call the next layer's `vkCreateInstance`
|
||||
before finally terminating in the loader again where it will call
|
||||
every driver's `vkCreateInstance`.
|
||||
This allows every enabled layer in the chain to set up what it needs based on
|
||||
@ -458,6 +467,17 @@ directory as this file.
|
||||
<br/>
|
||||
|
||||
|
||||
## Debugging Issues
|
||||
|
||||
|
||||
If your application is crashing or behaving weirdly, the loader provides
|
||||
several mechanisms for you to debug the issues.
|
||||
These are detailed in the [LoaderDebugging.md](LoaderDebugging.md) document
|
||||
found in the same directory as this file.
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
|
||||
## Loader Policies
|
||||
|
||||
Loader policies with regards to the loader interaction with drivers and layers
|
||||
@ -478,6 +498,62 @@ sections listed below:
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
## Filter Environment Variable Behaviors
|
||||
|
||||
The filter environment variables provided in certain areas have some common
|
||||
restrictions and behaviors that should be listed.
|
||||
|
||||
### Comparison Strings
|
||||
|
||||
The filter variables will be compared against the appropriate strings for either
|
||||
drivers or layers.
|
||||
The appropriate string for layers is the layer name provided in the layer's
|
||||
manifest file.
|
||||
Since drivers don’t have a name like layers, this substring is used to compare
|
||||
against the driver manifest's filename.
|
||||
|
||||
### Comma-Delimited Lists
|
||||
|
||||
All of the filter environment variables accept comma-delimited input.
|
||||
Therefore, you can chain multiple strings together and it will use the strings
|
||||
to individually enable or disable the appropriate item in the current list of
|
||||
available items.
|
||||
|
||||
### Globs
|
||||
|
||||
To provide enough flexibility to limit name searches to only those wanted by the
|
||||
developer, the loader uses a limited glob format for strings.
|
||||
Acceptable globs are:
|
||||
- Prefixes: `"string*"`
|
||||
- Suffixes: `"*string"`
|
||||
- Substrings: `"*string*"`
|
||||
- Whole strings: `"string"`
|
||||
- In the case of whole strings, the string will be compared against each
|
||||
layer or driver file name in its entirety.
|
||||
- Because of this, it will only match the specific target such as:
|
||||
`VK_LAYER_KHRONOS_validation` will match the layer name
|
||||
`VK_LAYER_KHRONOS_validation`, but **not** a layer named
|
||||
`VK_LAYER_KHRONOS_validation2` (not that there is such a layer).
|
||||
|
||||
This is especially useful because it is difficult sometimes to determine the
|
||||
full name of a driver manifest file or even some commonly used layers
|
||||
such as `VK_LAYER_KHRONOS_validation`.
|
||||
|
||||
### Case-Insensitive
|
||||
|
||||
All of the filter environment variables assume the strings inside of the glob
|
||||
are not case-sensitive.
|
||||
Therefore, “Bob”, “bob”, and “BOB” all amount to the same thing.
|
||||
|
||||
### Environment Variable Priority
|
||||
|
||||
The values from the *disable* environment variable will be considered
|
||||
**before** the *enable* or *select* environment variable.
|
||||
Because of this, it is possible to disable a layer/driver using the *disable*
|
||||
environment variable, only to have it be re-enabled by the *enable*/*select*
|
||||
environment variable.
|
||||
This is useful if you disable all layers/drivers with the intent of only
|
||||
enabling a smaller subset of specific layers/drivers for issue triaging.
|
||||
|
||||
## Table of Debug Environment Variables
|
||||
|
||||
@ -556,14 +632,15 @@ discovery.
|
||||
<td><small>
|
||||
Force the loader to use the specific driver JSON files.
|
||||
The value contains a list of delimited full path listings to
|
||||
driver JSON Manifest files.<br/>
|
||||
driver JSON Manifest files and/or
|
||||
paths to folders containing driver JSON files.<br/>
|
||||
<br/>
|
||||
This has replaced the older deprecated environment variable
|
||||
<i>VK_ICD_FILENAMES</i>, however the older environment variable will
|
||||
continue to work for some time.
|
||||
continue to work.
|
||||
</small></td>
|
||||
<td><small>
|
||||
If a global path to the JSON file is not used, issues may be encountered.
|
||||
If a relative path not used, issues may be encountered.
|
||||
<br/> <br/>
|
||||
<a href="#elevated-privilege-caveats">
|
||||
Ignored when running Vulkan application with elevated privileges.
|
||||
@ -580,35 +657,12 @@ discovery.
|
||||
</small>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small>
|
||||
<i>VK_INSTANCE_LAYERS</i>
|
||||
</small></td>
|
||||
<td><small>
|
||||
Force the loader to add the given layers to the list of Enabled layers
|
||||
normally passed into <b>vkCreateInstance</b>.
|
||||
These layers are added first, and the loader will remove any duplicate
|
||||
layers that appear in both this list as well as that passed into
|
||||
<i>ppEnabledLayerNames</i>.
|
||||
</small></td>
|
||||
<td><small>
|
||||
None
|
||||
</small></td>
|
||||
<td><small>
|
||||
export<br/>
|
||||
VK_INSTANCE_LAYERS=<br/>
|
||||
<layer_a>:<layer_b><br/><br/>
|
||||
set<br/>
|
||||
VK_INSTANCE_LAYERS=<br/>
|
||||
<layer_a>;<layer_b>
|
||||
</small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<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 folders to search for explicit layer manifest files.
|
||||
provided delimited file and/or folders to locate explicit layer manifest files.
|
||||
</small></td>
|
||||
<td><small>
|
||||
<a href="#elevated-privilege-caveats">
|
||||
@ -624,6 +678,34 @@ discovery.
|
||||
<path_a>;<path_b>
|
||||
</small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small>
|
||||
<i>VK_LOADER_DEBUG</i>
|
||||
</small></td>
|
||||
<td><small>
|
||||
Enable loader debug messages using a comma-delimited list of level
|
||||
options. These options are:<br/>
|
||||
* error (only errors)<br/>
|
||||
* warn (only warnings)<br/>
|
||||
* info (only info)<br/>
|
||||
* debug (only debug)<br/>
|
||||
* layer (layer-specific output)<br/>
|
||||
* driver (driver-specific output)<br/>
|
||||
* all (report out all messages)<br/><br/>
|
||||
To enable multiple options (outside of "all") like info, warning and
|
||||
error messages, set the value to "error,warn,info".
|
||||
</small></td>
|
||||
<td><small>
|
||||
None
|
||||
</small></td>
|
||||
<td><small>
|
||||
export<br/>
|
||||
VK_LOADER_DEBUG=all<br/>
|
||||
<br/>
|
||||
set<br/>
|
||||
VK_LOADER_DEBUG=warn
|
||||
</small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small>
|
||||
<i>VK_LOADER_DEVICE_SELECT</i>
|
||||
@ -679,30 +761,179 @@ discovery.
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small>
|
||||
<i>VK_LOADER_DEBUG</i>
|
||||
<i>VK_LOADER_DRIVERS_SELECT</i>
|
||||
</small></td>
|
||||
<td><small>
|
||||
Enable loader debug messages using a comma-delimited list of level
|
||||
options. These options are:<br/>
|
||||
* error (only errors)<br/>
|
||||
* warn (only warnings)<br/>
|
||||
* info (only info)<br/>
|
||||
* debug (only debug)<br/>
|
||||
* layer (layer-specific output)<br/>
|
||||
* driver (driver-specific output)<br/>
|
||||
* all (report out all messages)<br/><br/>
|
||||
To enable multiple options (outside of "all") like info, warning and
|
||||
error messages, set the value to "error,warn,info".
|
||||
A comma-delimited list of globs to search for in known drivers and
|
||||
used to select only the drivers whose manifest file names match one or
|
||||
more of the provided globs.<br/>
|
||||
Since drivers don’t have a name like layers, this glob is used to
|
||||
compare against the manifest filename.
|
||||
Known driver manifests being those files that are already found by the
|
||||
loader taking into account default search paths and other environment
|
||||
variables (like <i>VK_ICD_FILENAMES</i> or <i>VK_ADD_DRIVER_FILES</i>).
|
||||
</small></td>
|
||||
<td><small>
|
||||
None
|
||||
This functionality is only available with Loaders built with version
|
||||
1.3.234 of the Vulkan headers and later.<br/>
|
||||
If no drivers are found with a manifest filename that matches any of the
|
||||
provided globs, then no driver is enabled and it <b>may</b> result
|
||||
in Vulkan applications failing to run properly.
|
||||
</small></td>
|
||||
<td><small>
|
||||
export<br/>
|
||||
VK_LOADER_DEBUG=all<br/>
|
||||
VK_LOADER_DRIVERS_SELECT=nvidia*<br/>
|
||||
<br/>
|
||||
set<br/>
|
||||
VK_LOADER_DEBUG=warn
|
||||
VK_LOADER_DRIVERS_SELECT=nvidia*<br/><br/>
|
||||
The above would select only the Nvidia driver if it was present on the
|
||||
system and already visible to the loader.
|
||||
</small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small>
|
||||
<i>VK_LOADER_DRIVERS_DISABLE</i>
|
||||
</small></td>
|
||||
<td><small>
|
||||
A comma-delimited list of globs to search for in known drivers and
|
||||
used to disable only the drivers whose manifest file names match one or
|
||||
more of the provided globs.<br/>
|
||||
Since drivers don’t have a name like layers, this glob is used to
|
||||
compare against the manifest filename.
|
||||
Known driver manifests being those files that are already found by the
|
||||
loader taking into account default search paths and other environment
|
||||
variables (like <i>VK_ICD_FILENAMES</i> or <i>VK_ADD_DRIVER_FILES</i>).
|
||||
</small></td>
|
||||
<td><small>
|
||||
This functionality is only available with Loaders built with version
|
||||
1.3.234 of the Vulkan headers and later.<br/>
|
||||
If all available drivers are disabled using this environment variable,
|
||||
then no drivers will be found by the loader and <b>will</b> result
|
||||
in Vulkan applications failing to run properly.<br/>
|
||||
This is also checked before other driver environment variables (such as
|
||||
<i>VK_LOADER_DRIVERS_SELECT</i>) so that a user may easily disable all
|
||||
drivers and then selectively re-enable individual drivers using the
|
||||
enable environment variable.
|
||||
</small></td>
|
||||
<td><small>
|
||||
export<br/>
|
||||
VK_LOADER_DRIVERS_DISABLE=*amd*,*intel*<br/>
|
||||
<br/>
|
||||
set<br/>
|
||||
VK_LOADER_DRIVERS_DISABLE=*amd*,*intel*<br/><br/>
|
||||
The above would disable both Intel and AMD drivers if both were present
|
||||
on the system and already visible to the loader.
|
||||
</small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small>
|
||||
<i>VK_LOADER_LAYERS_ENABLE</i>
|
||||
</small></td>
|
||||
<td><small>
|
||||
A comma-delimited list of globs to search for in known layers and
|
||||
used to select only the layers whose layer name matches one or more of
|
||||
the provided globs.<br/>
|
||||
Known layers are those which are found by the loader taking into account
|
||||
default search paths and other environment variables
|
||||
(like <i>VK_LAYER_PATH</i>).
|
||||
<br/>
|
||||
This has replaced the older deprecated environment variable
|
||||
<i>VK_INSTANCE_LAYERS</i>
|
||||
</small></td>
|
||||
<td><small>
|
||||
This functionality is only available with Loaders built with version
|
||||
1.3.234 of the Vulkan headers and later.
|
||||
</small></td>
|
||||
<td><small>
|
||||
export<br/>
|
||||
VK_LOADER_LAYERS_ENABLE=*validation,*recon*<br/>
|
||||
<br/>
|
||||
set<br/>
|
||||
VK_LOADER_LAYERS_ENABLE=*validation,*recon*<br/><br/>
|
||||
The above would enable the Khronos validation layer and the
|
||||
GfxReconstruct layer, if both were present on the system and already
|
||||
visible to the loader.
|
||||
</small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small>
|
||||
<i>VK_LOADER_LAYERS_DISABLE</i>
|
||||
</small></td>
|
||||
<td><small>
|
||||
A comma-delimited list of globs to search for in known layers and
|
||||
used to disable only the layers whose layer name matches one or more of
|
||||
the provided globs.<br/>
|
||||
Known layers are those which are found by the loader taking into account
|
||||
default search paths and other environment variables
|
||||
(like <i>VK_LAYER_PATH</i>).
|
||||
</small></td>
|
||||
<td><small>
|
||||
This functionality is only available with Loaders built with version
|
||||
1.3.234 of the Vulkan headers and later.<br/>
|
||||
Disabling a layer that an application intentionally enables as an
|
||||
explicit layer <b>may</b> cause the application to not function
|
||||
properly.<br/>
|
||||
This is also checked before other layer environment variables (such as
|
||||
<i>VK_LOADER_LAYERS_ENABLE</i>) so that a user may easily disable all
|
||||
layers and then selectively re-enable individual layers using the
|
||||
enable environment variable.
|
||||
</small></td>
|
||||
<td><small>
|
||||
export<br/>
|
||||
VK_LOADER_LAYERS_DISABLE=*MESA*,~implicit~<br/>
|
||||
<br/>
|
||||
set<br/>
|
||||
VK_LOADER_LAYERS_DISABLE=*MESA*,~implicit~<br/><br/>
|
||||
The above would disable any Mesa layer and all other implicit layers
|
||||
that would normally be enabled on the system.
|
||||
</small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small>
|
||||
<i>VK_LOADER_LAYERS_ALLOW</i>
|
||||
</small></td>
|
||||
<td><small>
|
||||
A comma-delimited list of globs to search for in known layers and
|
||||
used to prevent layers whose layer name matches one or more of
|
||||
the provided globs from being disabled by <i>VK_LOADER_LAYERS_DISABLE</i>.<br/>
|
||||
Known layers are those which are found by the loader taking into account
|
||||
default search paths and other environment variables
|
||||
(like <i>VK_LAYER_PATH</i>).
|
||||
</small></td>
|
||||
<td><small>
|
||||
This functionality is only available with Loaders built with version
|
||||
1.3.262 of the Vulkan headers and later.<br/>
|
||||
This will not cause layers to be enabled if the normal mechanism to
|
||||
enable them
|
||||
</small></td>
|
||||
<td><small>
|
||||
export<br/>
|
||||
VK_LOADER_LAYERS_ALLOW=*validation*,*recon*<br/>
|
||||
<br/>
|
||||
set<br/>
|
||||
VK_LOADER_LAYERS_ALLOW=*validation*,*recon*<br/><br/>
|
||||
The above would allow any layer whose name is validation or recon to be
|
||||
enabled regardless of the value of <i>VK_LOADER_LAYERS_DISABLE</i>.
|
||||
</small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small>
|
||||
<i>VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING</i>
|
||||
</small></td>
|
||||
<td><small>
|
||||
If set to "1", causes the loader to not unload dynamic libraries during vkDestroyInstance.
|
||||
This option allows leak sanitizers to have full stack traces.
|
||||
</small></td>
|
||||
<td><small>
|
||||
This functionality is only available with Loaders built with version
|
||||
1.3.259 of the Vulkan headers and later.<br/>
|
||||
</small></td>
|
||||
<td><small>
|
||||
export<br/>
|
||||
VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING=1<br/>
|
||||
<br/>
|
||||
set<br/>
|
||||
VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING=1<br/><br/>
|
||||
</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -750,6 +981,34 @@ may be removed in a future loader release.
|
||||
<folder_a>\nvidia.json;<folder_b>\mesa.json
|
||||
</small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small>
|
||||
<i>VK_INSTANCE_LAYERS</i>
|
||||
</small></td>
|
||||
<td><small>
|
||||
Force the loader to add the given layers to the list of Enabled layers
|
||||
normally passed into <b>vkCreateInstance</b>.
|
||||
These layers are added first, and the loader will remove any duplicate
|
||||
layers that appear in both this list as well as that passed into
|
||||
<i>ppEnabledLayerNames</i>.
|
||||
</small></td>
|
||||
<td><small>
|
||||
This has been deprecated by <i>VK_LOADER_LAYERS_ENABLE</i>.
|
||||
It also overrides any layers disabled with
|
||||
<i>VK_LOADER_LAYERS_DISABLE</i>.
|
||||
</small></td>
|
||||
<td><small>
|
||||
None
|
||||
</small></td>
|
||||
<td><small>
|
||||
export<br/>
|
||||
VK_INSTANCE_LAYERS=<br/>
|
||||
<layer_a>;<layer_b><br/><br/>
|
||||
set<br/>
|
||||
VK_INSTANCE_LAYERS=<br/>
|
||||
<layer_a>;<layer_b>
|
||||
</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
<br/>
|
||||
@ -814,8 +1073,8 @@ may be removed in a future loader release.
|
||||
<td>Discovery</td>
|
||||
<td>The process of the loader searching for driver and layer files to set up
|
||||
the internal list of Vulkan objects available.<br/>
|
||||
On <i>Windows/Linux/macOS</i>, the discovery process typically focuses on
|
||||
searching for Manifest files.<br/>
|
||||
On <i>Windows/Linux/macOS</i>, the discovery process typically focuses
|
||||
on searching for Manifest files.<br/>
|
||||
On <i>Android</i>, the process focuses on searching for library files.
|
||||
</td>
|
||||
</tr>
|
||||
@ -982,4 +1241,31 @@ may be removed in a future loader release.
|
||||
for more information.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Exported Function</td>
|
||||
<td>A function which is intended to be obtained through the platform specific
|
||||
dynamic linker, specifically from a Driver or a Layer library.
|
||||
Functions that are required to be exported are primarily the very first
|
||||
functions the Loader calls on a Layer or Driver library. <br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Exposed Function</td>
|
||||
<td>A function which is intended to be obtained through a Querying Function, such as
|
||||
`vkGetInstanceProcAddr`.
|
||||
The exact Querying Function required for a specific exposed function varies
|
||||
between Layers and Drivers, as well as between interface versions. <br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Querying Functions</td>
|
||||
<td>These are functions which allow the Loader to query other functions from
|
||||
drivers and layers. These functions may be in the Vulkan API but also may be
|
||||
from the private Loader and Driver Interface or the Loader and Layer Interface. <br/>
|
||||
These functions are:
|
||||
`vkGetInstanceProcAddr`, `vkGetDeviceProcAddr`,
|
||||
`vk_icdGetInstanceProcAddr`, `vk_icdGetPhysicalDeviceProcAddr`, and
|
||||
`vk_layerGetPhysicalDeviceProcAddr`.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -4,16 +4,16 @@
|
||||
[1]: https://vulkan.lunarg.com/img/Vulkan_100px_Dec16.png "https://www.khronos.org/vulkan/"
|
||||
[2]: https://www.khronos.org/vulkan/
|
||||
|
||||
# Layer Interface to the Loader
|
||||
# Layer Interface to the Loader <!-- omit from toc -->
|
||||
[![Creative Commons][3]][4]
|
||||
|
||||
<!-- Copyright © 2015-2021 LunarG, Inc. -->
|
||||
<!-- Copyright © 2015-2023 LunarG, Inc. -->
|
||||
|
||||
[3]: https://i.creativecommons.org/l/by-nd/4.0/88x31.png "Creative Commons License"
|
||||
[4]: https://creativecommons.org/licenses/by-nd/4.0/
|
||||
|
||||
|
||||
## Table of Contents
|
||||
## Table of Contents <!-- omit from toc -->
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Layer Discovery](#layer-discovery)
|
||||
@ -25,6 +25,13 @@
|
||||
- [Fuchsia Layer Discovery](#fuchsia-layer-discovery)
|
||||
- [macOS Layer Discovery](#macos-layer-discovery)
|
||||
- [Example macOS Implicit Layer Search Path](#example-macos-implicit-layer-search-path)
|
||||
- [Layer Filtering](#layer-filtering)
|
||||
- [Layer Enable Filtering](#layer-enable-filtering)
|
||||
- [Layer Disable Filtering](#layer-disable-filtering)
|
||||
- [Layer Special Case Disable](#layer-special-case-disable)
|
||||
- [Layer Disable Warning](#layer-disable-warning)
|
||||
- [Allow certain Layers to ignore Layer Disabling](#allow-certain-layers-to-ignore-layer-disabling)
|
||||
- [`VK_INSTANCE_LAYERS`](#vk_instance_layers)
|
||||
- [Exception for Elevated Privileges](#exception-for-elevated-privileges)
|
||||
- [Layer Version Negotiation](#layer-version-negotiation)
|
||||
- [Layer Call Chains and Distributed Dispatch](#layer-call-chains-and-distributed-dispatch)
|
||||
@ -48,6 +55,7 @@
|
||||
- [Versioning and Activation Interactions](#versioning-and-activation-interactions)
|
||||
- [Layer Manifest File Format](#layer-manifest-file-format)
|
||||
- [Layer Manifest File Version History](#layer-manifest-file-version-history)
|
||||
- [Layer Manifest File Version 1.2.1](#layer-manifest-file-version-121)
|
||||
- [Layer Manifest File Version 1.2.0](#layer-manifest-file-version-120)
|
||||
- [Layer Manifest File Version 1.1.2](#layer-manifest-file-version-112)
|
||||
- [Layer Manifest File Version 1.1.1](#layer-manifest-file-version-111)
|
||||
@ -335,6 +343,9 @@ provided by the standard explicit layer paths mentioned above.
|
||||
The paths provided by `VK_ADD_LAYER_PATH` are added before the standard list
|
||||
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.
|
||||
See [Exception for Elevated Privileges](#exception-for-elevated-privileges)
|
||||
@ -412,14 +423,130 @@ following:
|
||||
/usr/share/vulkan/implicit_layer.d
|
||||
```
|
||||
|
||||
### Layer Filtering
|
||||
|
||||
**NOTE:** This functionality is only available with Loaders built with version
|
||||
1.3.234 of the Vulkan headers and later.
|
||||
|
||||
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`).
|
||||
|
||||
The filter variables will be compared against the layer name provided in the
|
||||
layer's manifest file.
|
||||
|
||||
The filters must also follow the behaviors define in the
|
||||
[Filter Environment Variable Behaviors](LoaderInterfaceArchitecture.md#filter-environment-variable-behaviors)
|
||||
section of the [LoaderLayerInterface](LoaderLayerInterface.md) document.
|
||||
|
||||
#### Layer Enable Filtering
|
||||
|
||||
The layer enable environment variable `VK_LOADER_LAYERS_ENABLE` is a
|
||||
comma-delimited list of globs to search for in known layers.
|
||||
The layer names are compared against the globs listed in the environment
|
||||
variable, and if they match, they will automatically be added to the enabled
|
||||
layer list in the loader for each application.
|
||||
These layers are enabled after implicit layers but before other explicit layers.
|
||||
|
||||
When a layer is enabled using the `VK_LOADER_LAYERS_ENABLE` filter, and
|
||||
loader logging is set to emit either warnings or layer messages, then a message
|
||||
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'
|
||||
```
|
||||
|
||||
#### Layer Disable Filtering
|
||||
|
||||
The layer disable environment variable `VK_LOADER_LAYERS_DISABLE` is a
|
||||
comma-delimited list of globs to search for in known layers.
|
||||
The layer names are compared against the globs listed in the environment
|
||||
variable, and if they match, they will automatically be disabled (whether or not
|
||||
the layer is Implicit or Explicit).
|
||||
This means that they will not be added to the enabled layer list in the loader
|
||||
for each application.
|
||||
This could mean that layers requested by an application are also not enabled
|
||||
such as `VK_KHRONOS_LAYER_synchronization2` which could cause some applications
|
||||
to misbehave.
|
||||
|
||||
When a layer is disabled using the `VK_LOADER_LAYERS_DISABLE` filter, and
|
||||
loader logging is set to emit either warnings or layer messages, then a message
|
||||
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'
|
||||
```
|
||||
|
||||
#### Layer Special Case Disable
|
||||
|
||||
Because there are different types of layers, there are 3 additional special
|
||||
disable options available when using the `VK_LOADER_LAYERS_DISABLE` environment
|
||||
variable.
|
||||
|
||||
These are:
|
||||
|
||||
* `~all~`
|
||||
* `~implicit~`
|
||||
* `~explicit~`
|
||||
|
||||
`~all~` will effectively disable every layer.
|
||||
This enables a developer to disable all layers on the system.
|
||||
`~implicit~` will effectively disable every implicit layer (leaving explicit
|
||||
layers still present in the application call chain).
|
||||
`~explicit~` will effectively disable every explicit layer (leaving implicit
|
||||
layers still present in the application call chain).
|
||||
|
||||
#### Layer Disable Warning
|
||||
|
||||
Disabling layers, whether just through normal usage of
|
||||
`VK_LOADER_LAYERS_DISABLE` or by evoking one of the special disable options like
|
||||
`~all~` or `~explicit~` could cause application breakage if the application is
|
||||
relying on features provided by one or more explicit layers.
|
||||
|
||||
#### Allow certain Layers to ignore Layer Disabling
|
||||
|
||||
**NOTE:** VK_LOADER_LAYERS_DISABLE is only available with Loaders built with version
|
||||
1.3.262 of the Vulkan headers and later.
|
||||
|
||||
The layer allow environment variable `VK_LOADER_LAYERS_ALLOW` is a
|
||||
comma-delimited list of globs to search for in known layers.
|
||||
The layer names are compared against the globs listed in the environment
|
||||
variable, and if they match, they will not be able to be disabled by
|
||||
`VK_LOADER_LAYERS_DISABLE`.
|
||||
|
||||
Implicit layers have the ability to only be enabled when a layer specified
|
||||
environment variable is set, allow for context dependent enablement.
|
||||
`VK_LOADER_LAYERS_ENABLE` ignores that context.
|
||||
`VK_LOADER_LAYERS_ALLOW` behaves similar to `VK_LOADER_LAYERS_ENABLE` while
|
||||
also respecting the context which is normally used to determine whether an
|
||||
implicit layer should be enabled.
|
||||
|
||||
`VK_LOADER_LAYERS_ALLOW` effectively negates the behavior of
|
||||
`VK_LOADER_LAYERS_DISABLE`.
|
||||
Explicit layers listed by `VK_LOADER_LAYERS_ALLOW` will not be enabled.
|
||||
Implicit layers listed by ``VK_LOADER_LAYERS_ALLOW` which are always active,
|
||||
i.e. they do not require any external context to be enabled, will be enabled.
|
||||
|
||||
##### `VK_INSTANCE_LAYERS`
|
||||
|
||||
The original `VK_INSTANCE_LAYERS` can be viewed as a special case of the new
|
||||
`VK_LOADER_LAYERS_ENABLE`.
|
||||
Because of this, any layers enabled via `VK_INSTANCE_LAYERS` will be treated the
|
||||
same as layers enabled with `VK_LOADER_LAYERS_ENABLE` and will therefore
|
||||
override any disables supplied in `VK_LOADER_LAYERS_DISABLE`.
|
||||
|
||||
### Exception for Elevated Privileges
|
||||
|
||||
There is an exception to when either `VK_LAYER_PATH` or `VK_ADD_LAYER_PATH` are
|
||||
available for use.
|
||||
For security reasons, both `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored
|
||||
if running the Vulkan application with elevated privileges.
|
||||
Because of this, both `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` can only be used
|
||||
for applications that do not use elevated privileges.
|
||||
For security reasons, `VK_LAYER_PATH` and `VK_ADD_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
|
||||
that do not use elevated privileges.
|
||||
|
||||
For more information see
|
||||
[Elevated Privilege Caveats](LoaderInterfaceArchitecture.md#elevated-privilege-caveats)
|
||||
@ -630,7 +757,8 @@ chain_info->u.pLayerInfo->pfnNextGetPhysicalDeviceProcAddr
|
||||
`vk_layerGetPhysicalDeviceProcAddr`.
|
||||
|
||||
If a layer intends to support functions that take VkPhysicalDevice as the
|
||||
dispatchable parameter, then layer should support `vk_layerGetPhysicalDeviceProcAddr`.
|
||||
dispatchable parameter, then layer should support
|
||||
`vk_layerGetPhysicalDeviceProcAddr`.
|
||||
This is because if these functions aren't known to the loader, such as those
|
||||
from unreleased extensions or because the loader is an older build thus doesn't
|
||||
know about them _yet_, the loader won't be able to distinguish whether this is
|
||||
@ -658,8 +786,8 @@ function, and set up a generic terminator which will pass it to the proper
|
||||
driver.
|
||||
4. Call down using `GetInstanceProcAddr`
|
||||
- If it returns non-NULL, treat it as an unknown logical device command.
|
||||
This means setting up a generic trampoline function that takes in a `VkDevice` as
|
||||
the first parameter and adjusting the dispatch table to call the
|
||||
This means setting up a generic trampoline function that takes in a `VkDevice`
|
||||
as the first parameter and adjusting the dispatch table to call the
|
||||
driver/layer's function after getting the dispatch table from the `VkDevice`.
|
||||
Then, return the pointer to corresponding trampoline function.
|
||||
5. Return NULL
|
||||
@ -714,7 +842,8 @@ function.
|
||||
corresponding Vulkan function in the next entity.
|
||||
* The common behavior for a layer is to intercept a call, perform some
|
||||
behavior, then pass it down to the next entity.
|
||||
* If a layer doesn't pass the information down, undefined behavior may occur.
|
||||
* If a layer doesn't pass the information down, undefined behavior may
|
||||
occur.
|
||||
* This is because the function will not be received by layers further
|
||||
down the chain, or any drivers.
|
||||
* One function that **must never call down the chain** is:
|
||||
@ -1074,7 +1203,7 @@ If any component layer is not present in the provided override paths, the meta
|
||||
layer is disabled.
|
||||
|
||||
The override meta-layer is primarily enabled when using the
|
||||
[VkConfig](https://github.com/LunarG/VulkanTools/blob/master/vkconfig/README.md)
|
||||
[VkConfig](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md)
|
||||
tool included in the Vulkan SDK.
|
||||
It is typically only available while the VkConfig tool is actually executing.
|
||||
Please refer to that documentation for more information.
|
||||
@ -1083,8 +1212,8 @@ Please refer to that documentation for more information.
|
||||
|
||||
Vulkan includes a small number of functions which are called without any
|
||||
dispatchable object.
|
||||
<b>Most layers do not intercept these functions</b>, as layers are enabled when an
|
||||
instance is created.
|
||||
<b>Most layers do not intercept these functions</b>, as layers are enabled when
|
||||
an instance is created.
|
||||
However, under certain conditions it is possible for a layer to intercept
|
||||
these functions.
|
||||
|
||||
@ -1411,7 +1540,8 @@ are in the blacklist will not be enabled.
|
||||
|
||||
* The `app_keys` member of the override meta layer will make a meta layer apply
|
||||
to only applications found in this list.
|
||||
If there are any items in the app keys list, the meta layer isn't enabled for any application except those found in the list.
|
||||
If there are any items in the app keys list, the meta layer isn't enabled for
|
||||
any application except those found in the list.
|
||||
|
||||
* The `override_paths` member of the override meta layer, if present, will
|
||||
replace the search paths the loader uses to find component layers.
|
||||
@ -1539,7 +1669,7 @@ Here's an example of a meta-layer manifest file:
|
||||
supports.
|
||||
It does not require the application to make use of that API version.
|
||||
It simply is an indication that the layer can support Vulkan API
|
||||
instance and device functions up to and including that API version. </br>
|
||||
instance and device functions up to and including that API version.</br>
|
||||
For example: 1.0.33.
|
||||
</td>
|
||||
<td>None</td>
|
||||
@ -1792,7 +1922,7 @@ application.
|
||||
#### Layer Manifest File Version 1.2.0
|
||||
|
||||
The ability to define the layer settings as defined by the
|
||||
[layer manifest schema](https://github.com/LunarG/VulkanTools/blob/master/vkconfig_core/layers/layers_schema.json).
|
||||
[layer manifest schema](https://github.com/LunarG/VulkanTools/blob/main/vkconfig_core/layers/layers_schema.json).
|
||||
|
||||
The ability to briefly document the layer thanks to the fields:
|
||||
* "introduction": Presentation of the purpose of the layer in a paragraph.
|
||||
@ -1802,7 +1932,7 @@ The ability to briefly document the layer thanks to the fields:
|
||||
|
||||
These changes were made to enable third-party layers to expose their features
|
||||
within
|
||||
[Vulkan Configurator](https://github.com/LunarG/VulkanTools/blob/master/vkconfig/README.md)
|
||||
[Vulkan Configurator](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md)
|
||||
or other tools.
|
||||
|
||||
#### Layer Manifest File Version 1.1.2
|
||||
@ -1837,8 +1967,8 @@ loader needs to query using OS-specific calls.
|
||||
- NOTE: This is an optional field and, as the two previous fields, only
|
||||
needed if the layer requires changing the name of the function for some reason.
|
||||
|
||||
The layer manifest file does not need to to be updated if the names of any listed
|
||||
functions has not changed.
|
||||
The layer manifest file does not need to to be updated if the names of any
|
||||
listed functions has not changed.
|
||||
|
||||
#### Layer Manifest File Version 1.0.1
|
||||
|
||||
@ -1878,7 +2008,7 @@ The following sections detail the differences between the various versions.
|
||||
### Layer Interface Version 2
|
||||
|
||||
Introduced the concept of
|
||||
[loader and layer interface](#layer-version-negotiation) using the new
|
||||
[loader and layer interface](#layer-version-negotiation) using the
|
||||
`vkNegotiateLoaderLayerInterfaceVersion` function.
|
||||
Additionally, it introduced the concept of
|
||||
[Layer Unknown Physical Device Extensions](#layer-unknown-physical-device-extensions)
|
||||
@ -1891,7 +2021,7 @@ Note: If a layer wraps the VkInstance handle, support for
|
||||
### Layer Interface Version 1
|
||||
|
||||
A layer supporting interface version 1 had the following behavior:
|
||||
1. `GetInstanceProcAddr` and `GetDeviceProcAddr` were directly exported
|
||||
1. `vkGetInstanceProcAddr` and `vkGetDeviceProcAddr` were directly exported
|
||||
2. The layer manifest file was able to override the names of the
|
||||
`GetInstanceProcAddr` and `GetDeviceProcAddr`functions.
|
||||
|
||||
@ -2090,7 +2220,7 @@ Android Vulkan documentation</a>.
|
||||
<td>A layer <b>must</b> have a valid JSON manifest file for the
|
||||
loader to process that ends with the ".json" suffix.
|
||||
It is recommended validating the layer manifest file against
|
||||
<a href="https://github.com/LunarG/VulkanTools/blob/master/vkconfig_core/layers/layers_schema.json">
|
||||
<a href="https://github.com/LunarG/VulkanTools/blob/main/vkconfig_core/layers/layers_schema.json">
|
||||
the layer schema</a> prior to publication.</br>
|
||||
The <b>only</b> exception is on Android which determines layer
|
||||
functionality through the introspection functions defined in
|
||||
@ -2168,7 +2298,7 @@ Android Vulkan documentation</a>.
|
||||
<td>Yes</td>
|
||||
<td>No</td>
|
||||
<td><small>
|
||||
<a href="https://github.com/KhronosGroup/VK-GL-CTS/blob/master/external/openglcts/README.md">
|
||||
<a href="https://github.com/KhronosGroup/VK-GL-CTS/blob/main/external/openglcts/README.md">
|
||||
Vulkan CTS Documentation</a>
|
||||
</small>
|
||||
</td>
|
||||
@ -2370,6 +2500,22 @@ Android Vulkan documentation</a>.
|
||||
<td>Yes</td>
|
||||
<td><small>N/A</small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small><b>LLP_LAYER_22</b></small></td>
|
||||
<td>During <i>vkCreateDevice</i>, a layer <b>must not</b> modify the
|
||||
<i>pDevice</i> pointer during prior to calling down to the lower
|
||||
layers.<br/>
|
||||
This is because the loader passes information in this pointer that is
|
||||
necessary for the initialization code in the loader's terminator
|
||||
function.<br/>
|
||||
Instead, if the layer is overriding the <i>pDevice</i> pointer, it
|
||||
<b>must</b> do so only after the call to the lower layers returns.
|
||||
</td>
|
||||
<td>The loader will likely crash.</td>
|
||||
<td>No</td>
|
||||
<td>Yes</td>
|
||||
<td><small>N/A</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
# ~~~
|
||||
# Copyright (c) 2014-2021 The Khronos Group Inc.
|
||||
# Copyright (c) 2014-2021 Valve Corporation
|
||||
# Copyright (c) 2014-2021 LunarG, Inc.
|
||||
# Copyright (c) 2014-2023 The Khronos Group Inc.
|
||||
# Copyright (c) 2014-2023 Valve Corporation
|
||||
# Copyright (c) 2014-2023 LunarG, Inc.
|
||||
# Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# Copyright (c) 2023-2023 RasterGrid Kft.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -16,45 +17,20 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# ~~~
|
||||
|
||||
# Get version of the API the generated code used and put it into a cmake variable LOADER_GENERATED_HEADER_VERSION
|
||||
include(generated/loader_generated_header_version.cmake)
|
||||
include(CheckIncludeFile)
|
||||
|
||||
add_library(loader_specific_options INTERFACE)
|
||||
target_link_libraries(loader_specific_options INTERFACE loader_common_options Vulkan::Headers)
|
||||
target_include_directories(loader_specific_options INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/generated ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
if(WIN32)
|
||||
if(MSVC)
|
||||
# Use static MSVCRT libraries
|
||||
foreach(configuration
|
||||
in
|
||||
CMAKE_C_FLAGS_DEBUG
|
||||
CMAKE_C_FLAGS_MINSIZEREL
|
||||
CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_CXX_FLAGS_DEBUG
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL
|
||||
CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
if(${configuration} MATCHES "/MD")
|
||||
string(REGEX
|
||||
REPLACE "/MD"
|
||||
"/MT"
|
||||
${configuration}
|
||||
"${${configuration}}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(ENABLE_WIN10_ONECORE)
|
||||
# Note: When linking your app or driver to OneCore.lib, be sure to remove any links to non-umbrella libs (such as
|
||||
# kernel32.lib).
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES " ") # space is intentional
|
||||
set(CMAKE_C_STANDARD_LIBRARIES ${CMAKE_CXX_STANDARD_LIBRARIES})
|
||||
set(CMAKE_C_STANDARD_LIBRARIES " ") # space is intentional
|
||||
endif()
|
||||
|
||||
target_compile_options(loader_specific_options INTERFACE -D_CRT_SECURE_NO_WARNINGS)
|
||||
# ~~~
|
||||
# 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.
|
||||
@ -68,27 +44,24 @@ if(WIN32)
|
||||
separate_arguments(MODIFIED_C_FLAGS_DEBUG WINDOWS_COMMAND ${MODIFIED_C_FLAGS_DEBUG})
|
||||
|
||||
# ~~~
|
||||
# Setup the loader.rc flie to contain the correct info
|
||||
# Optionally uses the BUILD_DLL_VERSIONINFO build option to allow setting the exact build version
|
||||
# Adds "Dev Build" to any build without the BUILD_DLL_VERSIONINFO option set
|
||||
# Only generate the loader.rc file with CMake if BUILD_DLL_VERSIONINFO was set.
|
||||
# This feature is for the Vulkan Runtime build
|
||||
# Otherwise rely on the checked in loader.rc from the python script
|
||||
# ~~~
|
||||
if ("$CACHE{BUILD_DLL_VERSIONINFO}" STREQUAL "")
|
||||
# default case - use 0 as the BUILDNO
|
||||
set(LOADER_RC_VERSION "1.0.1111.2222")
|
||||
set(LOADER_VER_FILE_VERSION_STR "\"${LOADER_RC_VERSION}.Dev Build\"")
|
||||
set(LOADER_VER_FILE_DESCRIPTION_STR "\"Vulkan Loader - Dev Build\"")
|
||||
else()
|
||||
if (NOT "$CACHE{BUILD_DLL_VERSIONINFO}" STREQUAL "")
|
||||
string(TIMESTAMP CURRENT_YEAR "%Y")
|
||||
set(LOADER_CUR_COPYRIGHT_YEAR "${CURRENT_YEAR}")
|
||||
set(LOADER_RC_VERSION "$CACHE{BUILD_DLL_VERSIONINFO}")
|
||||
set(LOADER_VER_FILE_VERSION_STR "\"${LOADER_RC_VERSION}\"")
|
||||
set(LOADER_VER_FILE_DESCRIPTION_STR "\"Vulkan Loader\"")
|
||||
|
||||
# RC file wants the value of FILEVERSION to separated by commas
|
||||
string(REPLACE "." ", " LOADER_VER_FILE_VERSION "${LOADER_RC_VERSION}")
|
||||
|
||||
# Configure the file to include the versioning info
|
||||
# Place it in the build directory - the GN build will use the checked in file
|
||||
configure_file(loader.rc.in ${CMAKE_CURRENT_BINARY_DIR}/loader.rc)
|
||||
endif()
|
||||
|
||||
# RC file wants the value of FILEVERSION to separated by commas
|
||||
string(REPLACE "." ", " LOADER_VER_FILE_VERSION "${LOADER_RC_VERSION}")
|
||||
|
||||
# Configure the file to include the versioning info
|
||||
# Place it in the current directory for check-in - so the GN build has up to date info
|
||||
configure_file(loader.rc.in ${CMAKE_CURRENT_LIST_DIR}/loader.rc)
|
||||
else()
|
||||
# Used to make alloca() and secure_getenv() available
|
||||
target_compile_definitions(loader_specific_options INTERFACE _GNU_SOURCE)
|
||||
@ -103,26 +76,46 @@ endif()
|
||||
|
||||
set(NORMAL_LOADER_SRCS
|
||||
allocation.c
|
||||
allocation.h
|
||||
cJSON.c
|
||||
cJSON.h
|
||||
debug_utils.c
|
||||
debug_utils.h
|
||||
extension_manual.c
|
||||
get_environment.c
|
||||
extension_manual.h
|
||||
loader_environment.c
|
||||
loader_environment.h
|
||||
gpa_helper.c
|
||||
gpa_helper.h
|
||||
loader.c
|
||||
loader.h
|
||||
log.c
|
||||
log.h
|
||||
settings.c
|
||||
settings.h
|
||||
terminator.c
|
||||
trampoline.c
|
||||
unknown_function_handling.c
|
||||
unknown_function_handling.h
|
||||
wsi.c
|
||||
wsi.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND NORMAL_LOADER_SRCS loader_windows.c dirent_on_windows.c)
|
||||
elseif(UNIX AND NOT APPLE) # i.e.: Linux
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|DragonFly|GNU")
|
||||
list(APPEND NORMAL_LOADER_SRCS loader_linux.c)
|
||||
target_compile_definitions(loader_specific_options INTERFACE LOADER_ENABLE_LINUX_SORT)
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_OSX_ARCHITECTURES}" MATCHES ";")
|
||||
set(APPLE_UNIVERSAL_BINARY ON)
|
||||
|
||||
# When building a universal binary we cannot enable USE_GAS
|
||||
# Since USE_GAS assumes only 1 architecture (arm64, x64, etc).
|
||||
set(USE_GAS OFF)
|
||||
endif()
|
||||
|
||||
set(OPT_LOADER_SRCS dev_ext_trampoline.c phys_dev_ext.c)
|
||||
|
||||
# Check for assembler support
|
||||
@ -130,9 +123,13 @@ 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.")
|
||||
if(WIN32)
|
||||
if(MINGW)
|
||||
find_program(JWASM_FOUND jwasm)
|
||||
|
||||
if (APPLE_UNIVERSAL_BINARY)
|
||||
set(USE_ASSEMBLY_FALLBACK ON)
|
||||
elseif(WIN32)
|
||||
option(USE_MASM "Use MASM" ON)
|
||||
if(USE_MASM AND MINGW)
|
||||
find_program(JWASM_FOUND NAMES jwasm uasm)
|
||||
if (JWASM_FOUND)
|
||||
set(CMAKE_ASM_MASM_COMPILER ${JWASM_FOUND})
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpmachine OUTPUT_VARIABLE COMPILER_VERSION_OUTPUT)
|
||||
@ -140,57 +137,101 @@ if(WIN32)
|
||||
if (COMPILER_VERSION_OUTPUT MATCHES "x86_64")
|
||||
set(JWASM_FLAGS -win64)
|
||||
else()
|
||||
set(JWASM_FLAGS -coff)
|
||||
# jwasm requires setting the cpu to at least 386 for setting a flat model
|
||||
set(JWASM_FLAGS -3 -coff)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
option(USE_MASM "Use MASM" ON)
|
||||
if (USE_MASM)
|
||||
enable_language(ASM_MASM)
|
||||
enable_language(ASM_MASM)
|
||||
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 [=[
|
||||
.model flat
|
||||
.code
|
||||
extrn _start:near
|
||||
xor eax, eax
|
||||
ret
|
||||
end
|
||||
]=])
|
||||
else()
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm [=[
|
||||
.code
|
||||
extrn start:near
|
||||
xor rax, rax
|
||||
ret
|
||||
end
|
||||
]=])
|
||||
endif ()
|
||||
if(CMAKE_ASM_MASM_COMPILER_WORKS OR JWASM_FOUND)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
else()
|
||||
set(CMAKE_ASM_MASM_COMPILER_WORKS false)
|
||||
endif()
|
||||
if(CMAKE_ASM_MASM_COMPILER_WORKS)
|
||||
add_executable(asm_offset asm_offset.c)
|
||||
target_link_libraries(asm_offset loader_specific_options)
|
||||
add_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset MASM)
|
||||
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)
|
||||
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)
|
||||
# Force off optimization so that the output assembly includes all the necessary info - optimizer would get rid of it otherwise.
|
||||
target_compile_options(asm_offset PRIVATE /Od)
|
||||
|
||||
find_package(Python3 REQUIRED QUIET)
|
||||
# Run parse_asm_values.py on asm_offset's assembly file to generate the gen_defines.asm, which the asm code depends on
|
||||
add_custom_command(TARGET asm_offset POST_BUILD
|
||||
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}"
|
||||
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 $<TARGET_PROPERTY:loader_asm_gen_files,BINARY_DIR>)
|
||||
target_include_directories(loader-unknown-chain PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_dependencies(loader-unknown-chain loader_asm_gen_files)
|
||||
else()
|
||||
set(USE_ASSEMBLY_FALLBACK ON)
|
||||
message(WARNING "Could not find working MASM assembler\n${ASM_FAILURE_MSG}")
|
||||
add_custom_target(loader_asm_gen_files)
|
||||
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}")
|
||||
endif()
|
||||
elseif(APPLE)
|
||||
# For MacOS, use the C code and force the compiler's tail-call optimization instead of using assembly code.
|
||||
set(OPT_LOADER_SRCS ${OPT_LOADER_SRCS} unknown_ext_chain.c)
|
||||
set_source_files_properties(${OPT_LOADER_SRCS} PROPERTIES COMPILE_FLAGS -O)
|
||||
add_custom_target(loader_asm_gen_files) # This causes no assembly files to be generated.
|
||||
else() # i.e.: Linux
|
||||
elseif(UNIX) # i.e.: Linux & Apple
|
||||
|
||||
option(USE_GAS "Use GAS" ON)
|
||||
if(USE_GAS)
|
||||
if (APPLE_UNIVERSAL_BINARY)
|
||||
message(FATAL_ERROR "USE_GAS cannot be used when compiling a universal binary!")
|
||||
endif()
|
||||
|
||||
enable_language(ASM)
|
||||
|
||||
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
|
||||
if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
|
||||
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64|arm64")
|
||||
try_compile(ASSEMBLER_WORKS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/asm_test_aarch64.S)
|
||||
if(ASSEMBLER_WORKS)
|
||||
set(OPT_LOADER_SRCS ${OPT_LOADER_SRCS} unknown_ext_chain_gas_aarch64.S)
|
||||
endif()
|
||||
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "amd64" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "^i.86$")
|
||||
# Covers x86_64, amd64, x86, i386, i686, I386, I686
|
||||
elseif(${CMAKE_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)
|
||||
@ -203,19 +244,70 @@ else() # i.e.: Linux
|
||||
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.
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(ASM_OFFSET_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}) # x86_64 or aarch64/arm64
|
||||
else()
|
||||
set(ASM_OFFSET_SYSTEM_PROCESSOR "x86")
|
||||
endif()
|
||||
|
||||
if(ASSEMBLER_WORKS)
|
||||
add_executable(asm_offset asm_offset.c)
|
||||
target_link_libraries(asm_offset loader_specific_options)
|
||||
add_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset GAS)
|
||||
# If not cross compiling, run asm_offset to generage gen_defines.asm
|
||||
if (NOT CMAKE_CROSSCOMPILING)
|
||||
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(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
set(ASM_OFFSET_EXECUTABLE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/gen_defines.asm")
|
||||
set(ASM_OFFSET_INTERMEDIATE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/CMakeFiles/asm_offset.dir/asm_offset.c.s")
|
||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set(ASM_OFFSET_EXECUTABLE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/gen_defines.asm")
|
||||
set(ASM_OFFSET_INTERMEDIATE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/CMakeFiles/asm_offset.dir/asm_offset.s")
|
||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
|
||||
# Need to use the current binary dir since the asm_offset.s file is in that folder rather than the bundle
|
||||
set(ASM_OFFSET_EXECUTABLE_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/gen_defines.asm")
|
||||
set(ASM_OFFSET_INTERMEDIATE_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/asm_offset.dir/asm_offset.s")
|
||||
else()
|
||||
message(FATAL_ERROR "C_COMPILER_ID not supported!")
|
||||
endif()
|
||||
|
||||
find_package(Python3 REQUIRED QUIET)
|
||||
# Run parse_asm_values.py on asm_offset's assembly file to generate the gen_defines.asm, which the asm code depends on
|
||||
add_custom_command(TARGET asm_offset POST_BUILD
|
||||
COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/scripts/parse_asm_values.py "${ASM_OFFSET_EXECUTABLE_LOCATION}"
|
||||
"${ASM_OFFSET_INTERMEDIATE_LOCATION}" "GAS" "${CMAKE_C_COMPILER_ID}" "${ASM_OFFSET_SYSTEM_PROCESSOR}"
|
||||
BYPRODUCTS gen_defines.asm
|
||||
)
|
||||
endif()
|
||||
add_custom_target(loader_asm_gen_files DEPENDS gen_defines.asm)
|
||||
|
||||
if (APPLE)
|
||||
set(MODIFY_UNKNOWN_FUNCTION_DECLS ON)
|
||||
endif()
|
||||
else()
|
||||
set(USE_ASSEMBLY_FALLBACK ON)
|
||||
if(USE_GAS)
|
||||
message(WARNING "Could not find working ${CMAKE_SYSTEM_PROCESSOR} GAS assembler\n${ASM_FAILURE_MSG}")
|
||||
message(WARNING "Could not find working ${ASM_OFFSET_SYSTEM_PROCESSOR} GAS assembler\n${ASM_FAILURE_MSG}")
|
||||
else()
|
||||
message(WARNING "Assembly sources have been disabled\n${ASM_FAILURE_MSG}")
|
||||
endif()
|
||||
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)
|
||||
add_custom_target(loader_asm_gen_files)
|
||||
set_source_files_properties(${OPT_LOADER_SRCS} PROPERTIES COMPILE_FLAGS -O)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -225,25 +317,29 @@ if(WIN32)
|
||||
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}
|
||||
$<TARGET_OBJECTS:loader-unknown-chain>
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vulkan-1.def
|
||||
${CMAKE_CURRENT_LIST_DIR}/loader.rc)
|
||||
${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)
|
||||
|
||||
if (UPDATE_DEPS)
|
||||
add_dependencies(vulkan vl_update_deps)
|
||||
endif()
|
||||
|
||||
# when adding the suffix the import and runtime library names must be consistent
|
||||
# mingw: libvulkan-1.dll.a / vulkan-1.dll
|
||||
# msvc: vulkan-1.lib / vulkan-1.dll
|
||||
set_target_properties(vulkan
|
||||
PROPERTIES
|
||||
OUTPUT_NAME vulkan-1)
|
||||
OUTPUT_NAME ${API_TYPE}-1)
|
||||
if(MINGW)
|
||||
# generate the same DLL with mingw
|
||||
set_target_properties(vulkan
|
||||
@ -261,20 +357,48 @@ if(WIN32)
|
||||
add_dependencies(vulkan loader_asm_gen_files)
|
||||
|
||||
else()
|
||||
if(APPLE AND BUILD_STATIC_LOADER)
|
||||
add_library(vulkan STATIC ${NORMAL_LOADER_SRCS} ${OPT_LOADER_SRCS})
|
||||
target_compile_definitions(vulkan PRIVATE BUILD_STATIC_LOADER)
|
||||
else()
|
||||
add_library(vulkan SHARED ${NORMAL_LOADER_SRCS} ${OPT_LOADER_SRCS})
|
||||
if(APPLE)
|
||||
option(APPLE_STATIC_LOADER "Build a loader that can be statically linked. Intended for Chromium usage/testing.")
|
||||
mark_as_advanced(APPLE_STATIC_LOADER)
|
||||
endif()
|
||||
|
||||
if(APPLE_STATIC_LOADER)
|
||||
add_library(vulkan STATIC)
|
||||
target_compile_definitions(vulkan PRIVATE APPLE_STATIC_LOADER)
|
||||
|
||||
message(WARNING "The APPLE_STATIC_LOADER option has been set. Note that this will only work on MacOS and is not supported "
|
||||
"or tested as part of the loader. Use it at your own risk.")
|
||||
else()
|
||||
add_library(vulkan SHARED)
|
||||
endif()
|
||||
|
||||
target_sources(vulkan PRIVATE ${NORMAL_LOADER_SRCS} ${OPT_LOADER_SRCS})
|
||||
|
||||
add_dependencies(vulkan loader_asm_gen_files)
|
||||
# set version based on LOADER_GENERATED_HEADER_VERSION used to generate the code
|
||||
set_target_properties(vulkan
|
||||
PROPERTIES SOVERSION "1"
|
||||
VERSION ${LOADER_GENERATED_HEADER_VERSION})
|
||||
target_link_libraries(vulkan PRIVATE ${CMAKE_DL_LIBS} m)
|
||||
if (NOT ANDROID)
|
||||
target_link_libraries(vulkan PRIVATE Threads::Threads)
|
||||
|
||||
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})
|
||||
|
||||
if (LOADER_ENABLE_ADDRESS_SANITIZER)
|
||||
target_compile_options(vulkan PUBLIC -fsanitize=address)
|
||||
target_link_options(vulkan PUBLIC -fsanitize=address)
|
||||
endif()
|
||||
if (LOADER_ENABLE_THREAD_SANITIZER)
|
||||
target_compile_options(vulkan PUBLIC -fsanitize=thread)
|
||||
target_link_options(vulkan PUBLIC -fsanitize=thread)
|
||||
endif()
|
||||
if (LOADER_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER)
|
||||
target_compile_options(vulkan PUBLIC -fsanitize=undefined)
|
||||
target_link_options(vulkan PUBLIC -fsanitize=undefined)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
@ -284,83 +408,106 @@ else()
|
||||
# Build vulkan.framework
|
||||
# Use GLOB_RECURSE to find all the header files and populate the vulkan.framework headers with them
|
||||
# Use CONFIGURE_DEPENDS to ensure that if the header files are updated, this list is also updated
|
||||
# Note: CONFIGURE_DEPENDS is a 3.12 feature - gate it for now and remove when CMake minimum version is higher
|
||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12.0")
|
||||
file(GLOB_RECURSE CONFIGURE_DEPENDS FRAMEWORK_HEADERS ${VulkanHeaders_INCLUDE_DIRS})
|
||||
else()
|
||||
file(GLOB_RECURSE FRAMEWORK_HEADERS ${VulkanHeaders_INCLUDE_DIRS})
|
||||
endif()
|
||||
if(BUILD_STATIC_LOADER)
|
||||
add_library(vulkan-framework STATIC ${NORMAL_LOADER_SRCS} ${OPT_LOADER_SRCS} ${FRAMEWORK_HEADERS})
|
||||
else()
|
||||
add_library(vulkan-framework SHARED ${NORMAL_LOADER_SRCS} ${OPT_LOADER_SRCS} ${FRAMEWORK_HEADERS})
|
||||
endif()
|
||||
get_target_property(VulkanHeaders_INCLUDE_DIRS Vulkan::Headers INTERFACE_INCLUDE_DIRECTORIES)
|
||||
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})
|
||||
|
||||
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)
|
||||
|
||||
if (MODIFY_UNKNOWN_FUNCTION_DECLS)
|
||||
# Modifies the names of functions as they appearin the assembly code so that the
|
||||
# unknown function handling will work
|
||||
target_compile_definitions(vulkan PRIVATE MODIFY_UNKNOWN_FUNCTION_DECLS)
|
||||
target_compile_definitions(vulkan-framework PRIVATE MODIFY_UNKNOWN_FUNCTION_DECLS)
|
||||
endif()
|
||||
|
||||
# The FRAMEWORK_VERSION needs to be "A" here so that Xcode code-signing works when a user adds their framework to an Xcode
|
||||
# project and does "Sign on Copy". It would have been nicer to use "1" to denote Vulkan 1. Although Apple docs say that a
|
||||
# framework version does not have to be "A", this part of the Apple toolchain expects it.
|
||||
# https://forums.developer.apple.com/thread/65963
|
||||
|
||||
# cmake-format: off
|
||||
set_target_properties(vulkan-framework PROPERTIES
|
||||
OUTPUT_NAME vulkan
|
||||
FRAMEWORK TRUE
|
||||
FRAMEWORK_VERSION A
|
||||
VERSION "${LOADER_GENERATED_HEADER_VERSION}" # "current version"
|
||||
SOVERSION "1.0.0" # "compatibility version"
|
||||
VERSION "${VULKAN_LOADER_VERSION}"
|
||||
SOVERSION "1.0.0"
|
||||
MACOSX_FRAMEWORK_IDENTIFIER com.lunarg.vulkanFramework
|
||||
PUBLIC_HEADER "${FRAMEWORK_HEADERS}"
|
||||
)
|
||||
|
||||
# Workaround linker warning: https://github.com/KhronosGroup/Vulkan-Loader/issues/1332
|
||||
#
|
||||
# MACHO_CURRENT_VERSION specifically applies to the -current_version linker option which is the
|
||||
# linker warning we are trying to address.
|
||||
set(APPLE_VULKAN_LOADER_VERSION "${VULKAN_LOADER_VERSION_MAJOR}.${VULKAN_LOADER_VERSION_MINOR}.0")
|
||||
set_target_properties(vulkan PROPERTIES MACHO_CURRENT_VERSION "${APPLE_VULKAN_LOADER_VERSION}")
|
||||
set_target_properties(vulkan-framework PROPERTIES MACHO_CURRENT_VERSION "${APPLE_VULKAN_LOADER_VERSION}")
|
||||
|
||||
install(TARGETS vulkan-framework
|
||||
PUBLIC_HEADER DESTINATION vulkan
|
||||
FRAMEWORK DESTINATION loader
|
||||
)
|
||||
# cmake-format: on
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(LOADER_USE_UNSAFE_FILE_SEARCH "Allows the loader to search in unsafe locations")
|
||||
if (LOADER_USE_UNSAFE_FILE_SEARCH)
|
||||
target_compile_definitions(vulkan PRIVATE LOADER_USE_UNSAFE_FILE_SEARCH)
|
||||
endif()
|
||||
|
||||
# common attributes of the vulkan library
|
||||
target_link_libraries(vulkan PRIVATE loader_specific_options)
|
||||
|
||||
set_target_properties(vulkan ${LOADER_STANDARD_C_PROPERTIES})
|
||||
if (TARGET asm_offset)
|
||||
set_target_properties(asm_offset ${LOADER_STANDARD_C_PROPERTIES})
|
||||
target_link_libraries(vulkan PRIVATE Vulkan::Headers)
|
||||
add_library(Vulkan::Loader ALIAS vulkan)
|
||||
|
||||
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!")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Generate pkg-config file.
|
||||
include(FindPkgConfig QUIET)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
set(VK_API_VERSION "${LOADER_GENERATED_HEADER_VERSION}")
|
||||
foreach(LIB ${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES} ${PLATFORM_LIBS})
|
||||
set(PRIVATE_LIBS "${PRIVATE_LIBS} -l${LIB}")
|
||||
endforeach()
|
||||
# Generate CMake Configuration File (IE: VulkanLoaderConfig.cmake)
|
||||
install(TARGETS vulkan EXPORT VulkanLoaderConfig)
|
||||
set_target_properties(vulkan PROPERTIES EXPORT_NAME "Loader")
|
||||
install(EXPORT VulkanLoaderConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VulkanLoader NAMESPACE Vulkan::)
|
||||
|
||||
# Generate CMake Version File (IE: VulkanLoaderConfigVersion.cmake)
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
set(version_config "${CMAKE_CURRENT_BINARY_DIR}/generated/VulkanLoaderConfigVersion.cmake")
|
||||
write_basic_package_version_file("${version_config}" COMPATIBILITY SameMajorVersion)
|
||||
install(FILES "${version_config}" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VulkanLoader)
|
||||
|
||||
# Generate PkgConfig File (IE: vulkan.pc)
|
||||
# NOTE: Hopefully in the future CMake can generate .pc files natively.
|
||||
# https://gitlab.kitware.com/cmake/cmake/-/issues/22621
|
||||
find_package(PkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
if(WIN32)
|
||||
if(MINGW)
|
||||
set(VULKAN_LIB_SUFFIX "-1.dll")
|
||||
else()
|
||||
set(VULKAN_LIB_SUFFIX "-1")
|
||||
endif()
|
||||
# Set libdir path as in cmake's FindVulkan.cmake
|
||||
# https://github.com/KhronosGroup/Vulkan-Loader/issues/668
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
string(REPLACE "lib" "Lib" CMAKE_INSTALL_FULL_LIBDIR_PC ${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
else()
|
||||
string(REPLACE "lib" "Lib32" CMAKE_INSTALL_FULL_LIBDIR_PC ${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# BUG: The following code will NOT work well with `cmake --install ... --prefix <dir>`
|
||||
# due to this code relying on CMAKE_INSTALL_PREFIX being defined at configure time.
|
||||
#
|
||||
# NOTE: vulkan.pc essentially cover both Vulkan-Loader and Vulkan-Headers for legacy reasons.
|
||||
if ("${CMAKE_INSTALL_PREFIX}" STREQUAL "")
|
||||
set(CMAKE_INSTALL_LIBDIR_PC ${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
set(CMAKE_INSTALL_INCLUDEDIR_PC ${CMAKE_INSTALL_FULL_INCLUDEDIR})
|
||||
else()
|
||||
set(CMAKE_INSTALL_FULL_LIBDIR_PC ${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
endif ()
|
||||
file(RELATIVE_PATH CMAKE_INSTALL_LIBDIR_PC ${CMAKE_INSTALL_PREFIX} ${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR_PC ${CMAKE_INSTALL_PREFIX} ${CMAKE_INSTALL_FULL_INCLUDEDIR})
|
||||
endif()
|
||||
configure_file("vulkan.pc.in" "vulkan.pc" @ONLY)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/vulkan.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/vulkan.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" RENAME "${API_TYPE}.pc")
|
||||
endif()
|
||||
|
||||
target_link_libraries(vulkan PRIVATE Vulkan::Headers)
|
||||
add_library(Vulkan::Vulkan ALIAS vulkan)
|
||||
|
||||
install(TARGETS vulkan
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
@ -28,7 +28,7 @@ typedef struct LoaderEnumAdapters2 {
|
||||
LUID luid;
|
||||
ULONG source_count;
|
||||
BOOL present_move_regions_preferred;
|
||||
} * adapters;
|
||||
} *adapters;
|
||||
} LoaderEnumAdapters2;
|
||||
|
||||
typedef _Check_return_ NTSTATUS(APIENTRY *PFN_LoaderEnumAdapters2)(const LoaderEnumAdapters2 *);
|
||||
|
@ -22,14 +22,54 @@
|
||||
|
||||
// This code generates an assembly file which provides offsets to get struct members from assembly code.
|
||||
|
||||
// __USE_MINGW_ANSI_STDIO is needed to use the %zu format specifier with mingw-w64.
|
||||
// Otherwise the compiler will complain about an unknown format specifier.
|
||||
#if defined(__MINGW32__) && !defined(__USE_MINGW_ANSI_STDIO)
|
||||
#define __USE_MINGW_ANSI_STDIO 1
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "loader_common.h"
|
||||
#include "log.h"
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
void produce_asm_define() {
|
||||
// GCC and clang make it easy to print easy to regex for values
|
||||
__asm__("# VULKAN_LOADER_ERROR_BIT = %c0" : : "i"(VULKAN_LOADER_ERROR_BIT));
|
||||
__asm__("# PTR_SIZE = %c0" : : "i"(sizeof(void *)));
|
||||
__asm__("# CHAR_PTR_SIZE = %c0" : : "i"(sizeof(char *)));
|
||||
__asm__("# FUNCTION_OFFSET_INSTANCE = %c0" : : "i"(offsetof(struct loader_instance, phys_dev_ext_disp_functions)));
|
||||
__asm__("# PHYS_DEV_OFFSET_INST_DISPATCH = %c0" : : "i"(offsetof(struct loader_instance_dispatch_table, phys_dev_ext)));
|
||||
__asm__("# PHYS_DEV_OFFSET_PHYS_DEV_TRAMP = %c0" : : "i"(offsetof(struct loader_physical_device_tramp, phys_dev)));
|
||||
__asm__("# ICD_TERM_OFFSET_PHYS_DEV_TERM = %c0" : : "i"(offsetof(struct loader_physical_device_term, this_icd_term)));
|
||||
__asm__("# PHYS_DEV_OFFSET_PHYS_DEV_TERM = %c0" : : "i"(offsetof(struct loader_physical_device_term, phys_dev)));
|
||||
__asm__("# INSTANCE_OFFSET_ICD_TERM = %c0" : : "i"(offsetof(struct loader_icd_term, this_instance)));
|
||||
__asm__("# DISPATCH_OFFSET_ICD_TERM = %c0" : : "i"(offsetof(struct loader_icd_term, phys_dev_ext)));
|
||||
__asm__("# EXT_OFFSET_DEVICE_DISPATCH = %c0" : : "i"(offsetof(struct loader_dev_dispatch_table, ext_dispatch)));
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
// MSVC will print the name of the value and the value in hex
|
||||
// Must disable optimization for this translation unit, otherwise the compiler strips out the variables
|
||||
static const uint32_t PTR_SIZE = sizeof(void *);
|
||||
static const uint32_t CHAR_PTR_SIZE = sizeof(char *);
|
||||
static const uint32_t FUNCTION_OFFSET_INSTANCE = offsetof(struct loader_instance, phys_dev_ext_disp_functions);
|
||||
static const uint32_t PHYS_DEV_OFFSET_INST_DISPATCH = offsetof(struct loader_instance_dispatch_table, phys_dev_ext);
|
||||
static const uint32_t PHYS_DEV_OFFSET_PHYS_DEV_TRAMP = offsetof(struct loader_physical_device_tramp, phys_dev);
|
||||
static const uint32_t ICD_TERM_OFFSET_PHYS_DEV_TERM = offsetof(struct loader_physical_device_term, this_icd_term);
|
||||
static const uint32_t PHYS_DEV_OFFSET_PHYS_DEV_TERM = offsetof(struct loader_physical_device_term, phys_dev);
|
||||
static const uint32_t INSTANCE_OFFSET_ICD_TERM = offsetof(struct loader_icd_term, this_instance);
|
||||
static const uint32_t DISPATCH_OFFSET_ICD_TERM = offsetof(struct loader_icd_term, phys_dev_ext);
|
||||
static const uint32_t EXT_OFFSET_DEVICE_DISPATCH = offsetof(struct loader_dev_dispatch_table, ext_dispatch);
|
||||
#else
|
||||
#warning asm_offset.c variable declarations need to be defined for this platform
|
||||
#endif
|
||||
|
||||
#if !defined(_MSC_VER) || (_MSC_VER >= 1900)
|
||||
#define SIZE_T_FMT "%-8zu"
|
||||
#else
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
#define SIZE_T_FMT "%-8lu"
|
||||
#else
|
||||
#warning asm_offset.c SIZE_T_FMT must be defined for this platform
|
||||
#endif
|
||||
|
||||
struct ValueInfo {
|
||||
@ -38,6 +78,8 @@ struct ValueInfo {
|
||||
const char *comment;
|
||||
};
|
||||
|
||||
// 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;
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
@ -78,7 +120,7 @@ int main(int argc, char **argv) {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
FILE *file = fopen("gen_defines.asm", "w");
|
||||
FILE *file = loader_fopen("gen_defines.asm", "w");
|
||||
fprintf(file, "\n");
|
||||
if (!strcmp(assembler, "MASM")) {
|
||||
for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) {
|
||||
|
701
loader/cJSON.c
701
loader/cJSON.c
File diff suppressed because it is too large
Load Diff
114
loader/cJSON.h
114
loader/cJSON.h
@ -25,11 +25,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "loader_common.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_False 0
|
||||
@ -64,96 +62,50 @@ typedef struct cJSON {
|
||||
VkAllocationCallbacks *pAllocator;
|
||||
} cJSON;
|
||||
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate.
|
||||
* Call cJSON_Delete when finished. */
|
||||
cJSON *cJSON_Parse(const VkAllocationCallbacks *pAllocator, const char *value);
|
||||
/* Render a cJSON entity to text for transfer/storage. Free the char* when
|
||||
* finished. */
|
||||
char *cJSON_Print(cJSON *item);
|
||||
char *loader_cJSON_Print(cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting.
|
||||
* Free the char* when finished. */
|
||||
char *cJSON_PrintUnformatted(cJSON *item);
|
||||
/* 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 */
|
||||
char *cJSON_PrintBuffered(cJSON *item, int prebuffer, int fmt);
|
||||
char *loader_cJSON_PrintUnformatted(cJSON *item);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
void cJSON_Delete(cJSON *c);
|
||||
/* Delete an item allocated inside the JSON parser*/
|
||||
void cJSON_Free(const VkAllocationCallbacks *pAllocator, void *p);
|
||||
void loader_cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
int cJSON_GetArraySize(cJSON *array);
|
||||
int loader_cJSON_GetArraySize(cJSON *array);
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful.
|
||||
*/
|
||||
cJSON *cJSON_GetArrayItem(cJSON *array, int item);
|
||||
cJSON *loader_cJSON_GetArrayItem(cJSON *array, int item);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
cJSON *cJSON_GetObjectItem(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 cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
const char *cJSON_GetErrorPtr(void);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
cJSON *cJSON_CreateNull(const VkAllocationCallbacks *pAllocator);
|
||||
cJSON *cJSON_CreateTrue(const VkAllocationCallbacks *pAllocator);
|
||||
cJSON *cJSON_CreateFalse(const VkAllocationCallbacks *pAllocator);
|
||||
cJSON *cJSON_CreateBool(const VkAllocationCallbacks *pAllocator, int b);
|
||||
cJSON *cJSON_CreateNumber(const VkAllocationCallbacks *pAllocator, double num);
|
||||
cJSON *cJSON_CreateString(const VkAllocationCallbacks *pAllocator, const char *string);
|
||||
cJSON *cJSON_CreateArray(const VkAllocationCallbacks *pAllocator);
|
||||
cJSON *cJSON_CreateObject(const VkAllocationCallbacks *pAllocator);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
cJSON *cJSON_CreateIntArray(const VkAllocationCallbacks *pAllocator, const int *numbers, int count);
|
||||
cJSON *cJSON_CreateFloatArray(const VkAllocationCallbacks *pAllocator, const float *numbers, int count);
|
||||
cJSON *cJSON_CreateDoubleArray(const VkAllocationCallbacks *pAllocator, const double *numbers, int count);
|
||||
cJSON *cJSON_CreateStringArray(const VkAllocationCallbacks *pAllocator, const char **strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and
|
||||
* will definitely survive the cJSON object */
|
||||
void cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you
|
||||
* want to add an existing cJSON to a new cJSON, but don't want to corrupt your
|
||||
* existing cJSON. */
|
||||
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detach items from Arrays/Objects. */
|
||||
cJSON *cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
void cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
void cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
void cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
cJSON *cJSON_Duplicate(cJSON *item, int recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new
|
||||
memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected
|
||||
to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null
|
||||
* terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
cJSON *cJSON_ParseWithOpts(const VkAllocationCallbacks *pAllocator, const char *value, const char **return_parse_end,
|
||||
int require_null_terminated);
|
||||
|
||||
void cJSON_Minify(char *json);
|
||||
cJSON *loader_cJSON_GetObjectItem(cJSON *object, const char *string);
|
||||
|
||||
/* 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))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
// Helper functions to using JSON
|
||||
|
||||
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.
|
||||
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(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);
|
||||
|
@ -27,9 +27,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef WIN32
|
||||
#if !defined(WIN32)
|
||||
#include <signal.h>
|
||||
#else
|
||||
#endif
|
||||
|
||||
#include "vulkan/vk_layer.h"
|
||||
@ -45,30 +44,32 @@
|
||||
|
||||
VkResult util_CreateDebugUtilsMessenger(struct loader_instance *inst, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT messenger) {
|
||||
VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
|
||||
VkLayerDbgFunctionNode *new_dbg_function_node = NULL;
|
||||
|
||||
pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
|
||||
new_dbg_function_node = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
|
||||
pAllocator, inst, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
|
||||
if (!pNewDbgFuncNode) {
|
||||
if (!new_dbg_function_node) {
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
pNewDbgFuncNode->is_messenger = true;
|
||||
pNewDbgFuncNode->messenger.messenger = messenger;
|
||||
pNewDbgFuncNode->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
|
||||
pNewDbgFuncNode->messenger.messageSeverity = pCreateInfo->messageSeverity;
|
||||
pNewDbgFuncNode->messenger.messageType = pCreateInfo->messageType;
|
||||
pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
|
||||
pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
|
||||
inst->DbgFunctionHead = pNewDbgFuncNode;
|
||||
new_dbg_function_node->is_messenger = true;
|
||||
new_dbg_function_node->messenger.messenger = messenger;
|
||||
new_dbg_function_node->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
|
||||
new_dbg_function_node->messenger.messageSeverity = pCreateInfo->messageSeverity;
|
||||
new_dbg_function_node->messenger.messageType = pCreateInfo->messageType;
|
||||
new_dbg_function_node->pUserData = pCreateInfo->pUserData;
|
||||
new_dbg_function_node->pNext = inst->instance_only_dbg_function_head;
|
||||
inst->instance_only_dbg_function_head = new_dbg_function_node;
|
||||
inst->current_dbg_function_head = inst->instance_only_dbg_function_head;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VKAPI_ATTR VkResult VKAPI_CALL
|
||||
debug_utils_CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pMessenger) {
|
||||
VKAPI_ATTR VkResult VKAPI_CALL debug_utils_CreateDebugUtilsMessengerEXT(VkInstance instance,
|
||||
const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkDebugUtilsMessengerEXT *pMessenger) {
|
||||
struct loader_instance *inst = loader_get_instance(instance);
|
||||
loader_platform_thread_lock_mutex(&loader_lock);
|
||||
VkResult result = inst->disp->layer_inst_disp.CreateDebugUtilsMessengerEXT(inst->instance, pCreateInfo, pAllocator, pMessenger);
|
||||
@ -82,7 +83,7 @@ VkBool32 util_SubmitDebugUtilsMessageEXT(const struct loader_instance *inst, VkD
|
||||
VkBool32 bail = false;
|
||||
|
||||
if (NULL != pCallbackData) {
|
||||
VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
|
||||
VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
|
||||
VkDebugReportObjectTypeEXT object_type = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
|
||||
VkDebugReportFlagsEXT object_flags = 0;
|
||||
uint64_t object_handle = 0;
|
||||
@ -115,13 +116,14 @@ VkBool32 util_SubmitDebugUtilsMessageEXT(const struct loader_instance *inst, VkD
|
||||
|
||||
void util_DestroyDebugUtilsMessenger(struct loader_instance *inst, VkDebugUtilsMessengerEXT messenger,
|
||||
const VkAllocationCallbacks *pAllocator) {
|
||||
VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
|
||||
VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
|
||||
VkLayerDbgFunctionNode *pPrev = pTrav;
|
||||
|
||||
while (pTrav) {
|
||||
if (pTrav->is_messenger && pTrav->messenger.messenger == messenger) {
|
||||
pPrev->pNext = pTrav->pNext;
|
||||
if (inst->DbgFunctionHead == pTrav) inst->DbgFunctionHead = pTrav->pNext;
|
||||
if (inst->current_dbg_function_head == pTrav) inst->current_dbg_function_head = pTrav->pNext;
|
||||
if (inst->instance_only_dbg_function_head == pTrav) inst->instance_only_dbg_function_head = pTrav->pNext;
|
||||
loader_free_with_instance_fallback(pAllocator, inst, pTrav);
|
||||
break;
|
||||
}
|
||||
@ -149,16 +151,17 @@ VkResult util_CreateDebugUtilsMessengers(struct loader_instance *inst, const voi
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VKAPI_ATTR void VKAPI_CALL debug_utils_SubmitDebugUtilsMessageEXT(
|
||||
VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
|
||||
VKAPI_ATTR void VKAPI_CALL debug_utils_SubmitDebugUtilsMessageEXT(VkInstance instance,
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
|
||||
struct loader_instance *inst = loader_get_instance(instance);
|
||||
|
||||
inst->disp->layer_inst_disp.SubmitDebugUtilsMessageEXT(inst->instance, messageSeverity, messageTypes, pCallbackData);
|
||||
}
|
||||
|
||||
static VKAPI_ATTR void VKAPI_CALL debug_utils_DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
|
||||
const VkAllocationCallbacks *pAllocator) {
|
||||
VKAPI_ATTR void VKAPI_CALL debug_utils_DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
|
||||
const VkAllocationCallbacks *pAllocator) {
|
||||
struct loader_instance *inst = loader_get_instance(instance);
|
||||
loader_platform_thread_lock_mutex(&loader_lock);
|
||||
|
||||
@ -177,7 +180,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugUtilsMessengerEXT(VkInstanc
|
||||
struct loader_instance *inst = (struct loader_instance *)instance;
|
||||
VkResult res = VK_SUCCESS;
|
||||
uint32_t storage_idx;
|
||||
VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
|
||||
VkLayerDbgFunctionNode *new_dbg_func_node = NULL;
|
||||
|
||||
icd_info = (VkDebugUtilsMessengerEXT *)loader_calloc_with_instance_fallback(
|
||||
pAllocator, inst, inst->total_icd_count * sizeof(VkDebugUtilsMessengerEXT), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
@ -204,23 +207,23 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugUtilsMessengerEXT(VkInstanc
|
||||
// Setup the debug report callback in the terminator since a layer may want
|
||||
// to grab the information itself (RenderDoc) and then return back to the
|
||||
// user callback a sub-set of the messages.
|
||||
pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
|
||||
new_dbg_func_node = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
|
||||
pAllocator, inst, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!pNewDbgFuncNode) {
|
||||
if (!new_dbg_func_node) {
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pNewDbgFuncNode->is_messenger = true;
|
||||
pNewDbgFuncNode->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
|
||||
pNewDbgFuncNode->messenger.messageSeverity = pCreateInfo->messageSeverity;
|
||||
pNewDbgFuncNode->messenger.messageType = pCreateInfo->messageType;
|
||||
pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
|
||||
pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
|
||||
inst->DbgFunctionHead = pNewDbgFuncNode;
|
||||
new_dbg_func_node->is_messenger = true;
|
||||
new_dbg_func_node->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
|
||||
new_dbg_func_node->messenger.messageSeverity = pCreateInfo->messageSeverity;
|
||||
new_dbg_func_node->messenger.messageType = pCreateInfo->messageType;
|
||||
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;
|
||||
|
||||
*(VkDebugUtilsMessengerEXT **)pMessenger = icd_info;
|
||||
pNewDbgFuncNode->messenger.messenger = *pMessenger;
|
||||
*pMessenger = (VkDebugUtilsMessengerEXT)(uintptr_t)icd_info;
|
||||
new_dbg_func_node->messenger.messenger = *pMessenger;
|
||||
|
||||
out:
|
||||
|
||||
@ -237,8 +240,8 @@ out:
|
||||
}
|
||||
storage_idx++;
|
||||
}
|
||||
loader_free(pAllocator, pNewDbgFuncNode);
|
||||
loader_free(pAllocator, icd_info);
|
||||
loader_free_with_instance_fallback(pAllocator, inst, new_dbg_func_node);
|
||||
loader_free_with_instance_fallback(pAllocator, inst, icd_info);
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -252,7 +255,7 @@ VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugUtilsMessengerEXT(VkInstance i
|
||||
const struct loader_icd_term *icd_term;
|
||||
|
||||
struct loader_instance *inst = (struct loader_instance *)instance;
|
||||
icd_info = *(VkDebugUtilsMessengerEXT **)&messenger;
|
||||
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) {
|
||||
@ -267,7 +270,7 @@ VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugUtilsMessengerEXT(VkInstance i
|
||||
|
||||
util_DestroyDebugUtilsMessenger(inst, messenger, pAllocator);
|
||||
|
||||
loader_free(pAllocator, icd_info);
|
||||
loader_free_with_instance_fallback(pAllocator, inst, icd_info);
|
||||
}
|
||||
|
||||
// This is the instance chain terminator function for SubmitDebugUtilsMessageEXT
|
||||
@ -289,28 +292,30 @@ VKAPI_ATTR void VKAPI_CALL terminator_SubmitDebugUtilsMessageEXT(VkInstance inst
|
||||
|
||||
VkResult util_CreateDebugReportCallback(struct loader_instance *inst, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT callback) {
|
||||
VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
|
||||
VkLayerDbgFunctionNode *new_dbg_func_node = NULL;
|
||||
|
||||
pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
|
||||
new_dbg_func_node = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
|
||||
pAllocator, inst, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!pNewDbgFuncNode) {
|
||||
if (!new_dbg_func_node) {
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
pNewDbgFuncNode->is_messenger = false;
|
||||
pNewDbgFuncNode->report.msgCallback = callback;
|
||||
pNewDbgFuncNode->report.pfnMsgCallback = pCreateInfo->pfnCallback;
|
||||
pNewDbgFuncNode->report.msgFlags = pCreateInfo->flags;
|
||||
pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
|
||||
pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
|
||||
inst->DbgFunctionHead = pNewDbgFuncNode;
|
||||
new_dbg_func_node->is_messenger = false;
|
||||
new_dbg_func_node->report.msgCallback = callback;
|
||||
new_dbg_func_node->report.pfnMsgCallback = pCreateInfo->pfnCallback;
|
||||
new_dbg_func_node->report.msgFlags = pCreateInfo->flags;
|
||||
new_dbg_func_node->pUserData = pCreateInfo->pUserData;
|
||||
new_dbg_func_node->pNext = inst->instance_only_dbg_function_head;
|
||||
inst->instance_only_dbg_function_head = new_dbg_func_node;
|
||||
inst->current_dbg_function_head = inst->instance_only_dbg_function_head;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VKAPI_ATTR VkResult VKAPI_CALL
|
||||
debug_utils_CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback) {
|
||||
VKAPI_ATTR VkResult VKAPI_CALL debug_utils_CreateDebugReportCallbackEXT(VkInstance instance,
|
||||
const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkDebugReportCallbackEXT *pCallback) {
|
||||
struct loader_instance *inst = loader_get_instance(instance);
|
||||
loader_platform_thread_lock_mutex(&loader_lock);
|
||||
VkResult result = inst->disp->layer_inst_disp.CreateDebugReportCallbackEXT(inst->instance, pCreateInfo, pAllocator, pCallback);
|
||||
@ -322,7 +327,7 @@ debug_utils_CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugRepor
|
||||
VkBool32 util_DebugReportMessage(const struct loader_instance *inst, VkFlags msgFlags, VkDebugReportObjectTypeEXT objectType,
|
||||
uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
|
||||
VkBool32 bail = false;
|
||||
VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
|
||||
VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT severity;
|
||||
VkDebugUtilsMessageTypeFlagsEXT types;
|
||||
VkDebugUtilsMessengerCallbackDataEXT callback_data;
|
||||
@ -365,13 +370,15 @@ VkBool32 util_DebugReportMessage(const struct loader_instance *inst, VkFlags msg
|
||||
|
||||
void util_DestroyDebugReportCallback(struct loader_instance *inst, VkDebugReportCallbackEXT callback,
|
||||
const VkAllocationCallbacks *pAllocator) {
|
||||
VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
|
||||
VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
|
||||
VkLayerDbgFunctionNode *pPrev = pTrav;
|
||||
|
||||
while (pTrav) {
|
||||
if (!pTrav->is_messenger && pTrav->report.msgCallback == callback) {
|
||||
pPrev->pNext = pTrav->pNext;
|
||||
if (inst->DbgFunctionHead == pTrav) inst->DbgFunctionHead = pTrav->pNext;
|
||||
if (inst->current_dbg_function_head == pTrav) inst->current_dbg_function_head = pTrav->pNext;
|
||||
if (inst->instance_only_dbg_function_head == pTrav) inst->instance_only_dbg_function_head = pTrav->pNext;
|
||||
if (inst->current_dbg_function_head == pTrav) inst->current_dbg_function_head = pTrav->pNext;
|
||||
loader_free_with_instance_fallback(pAllocator, inst, pTrav);
|
||||
break;
|
||||
}
|
||||
@ -399,8 +406,8 @@ VkResult util_CreateDebugReportCallbacks(struct loader_instance *inst, const voi
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VKAPI_ATTR void VKAPI_CALL debug_utils_DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
|
||||
const VkAllocationCallbacks *pAllocator) {
|
||||
VKAPI_ATTR void VKAPI_CALL debug_utils_DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
|
||||
const VkAllocationCallbacks *pAllocator) {
|
||||
struct loader_instance *inst = loader_get_instance(instance);
|
||||
loader_platform_thread_lock_mutex(&loader_lock);
|
||||
|
||||
@ -409,10 +416,9 @@ static VKAPI_ATTR void VKAPI_CALL debug_utils_DestroyDebugReportCallbackEXT(VkIn
|
||||
loader_platform_thread_unlock_mutex(&loader_lock);
|
||||
}
|
||||
|
||||
static VKAPI_ATTR void VKAPI_CALL debug_utils_DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
|
||||
VkDebugReportObjectTypeEXT objType, uint64_t object,
|
||||
size_t location, int32_t msgCode, const char *pLayerPrefix,
|
||||
const char *pMsg) {
|
||||
VKAPI_ATTR void VKAPI_CALL debug_utils_DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
|
||||
VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
|
||||
int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
|
||||
struct loader_instance *inst = loader_get_instance(instance);
|
||||
|
||||
inst->disp->layer_inst_disp.DebugReportMessageEXT(inst->instance, flags, objType, object, location, msgCode, pLayerPrefix,
|
||||
@ -430,10 +436,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallbackEXT(VkInstanc
|
||||
struct loader_instance *inst = (struct loader_instance *)instance;
|
||||
VkResult res = VK_SUCCESS;
|
||||
uint32_t storage_idx;
|
||||
VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
|
||||
VkLayerDbgFunctionNode *new_dbg_func_node = NULL;
|
||||
|
||||
icd_info = ((VkDebugReportCallbackEXT *)loader_calloc(pAllocator, inst->total_icd_count * sizeof(VkDebugReportCallbackEXT),
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
|
||||
icd_info = ((VkDebugReportCallbackEXT *)loader_calloc_with_instance_fallback(
|
||||
pAllocator, inst, inst->total_icd_count * sizeof(VkDebugReportCallbackEXT), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
|
||||
if (!icd_info) {
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
@ -456,23 +462,23 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallbackEXT(VkInstanc
|
||||
// Setup the debug report callback in the terminator since a layer may want
|
||||
// to grab the information itself (RenderDoc) and then return back to the
|
||||
// user callback a sub-set of the messages.
|
||||
pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
|
||||
new_dbg_func_node = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
|
||||
pAllocator, inst, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
|
||||
if (!pNewDbgFuncNode) {
|
||||
if (!new_dbg_func_node) {
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pNewDbgFuncNode->is_messenger = false;
|
||||
pNewDbgFuncNode->report.pfnMsgCallback = pCreateInfo->pfnCallback;
|
||||
pNewDbgFuncNode->report.msgFlags = pCreateInfo->flags;
|
||||
pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
|
||||
pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
|
||||
inst->DbgFunctionHead = pNewDbgFuncNode;
|
||||
new_dbg_func_node->is_messenger = false;
|
||||
new_dbg_func_node->report.pfnMsgCallback = pCreateInfo->pfnCallback;
|
||||
new_dbg_func_node->report.msgFlags = pCreateInfo->flags;
|
||||
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;
|
||||
|
||||
*(VkDebugReportCallbackEXT **)pCallback = icd_info;
|
||||
pNewDbgFuncNode->report.msgCallback = *pCallback;
|
||||
*pCallback = (VkDebugReportCallbackEXT)(uintptr_t)icd_info;
|
||||
new_dbg_func_node->report.msgCallback = *pCallback;
|
||||
|
||||
out:
|
||||
|
||||
@ -489,8 +495,8 @@ out:
|
||||
}
|
||||
storage_idx++;
|
||||
}
|
||||
loader_free(pAllocator, pNewDbgFuncNode);
|
||||
loader_free(pAllocator, icd_info);
|
||||
loader_free_with_instance_fallback(pAllocator, inst, new_dbg_func_node);
|
||||
loader_free_with_instance_fallback(pAllocator, inst, icd_info);
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -504,7 +510,7 @@ VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugReportCallbackEXT(VkInstance i
|
||||
const struct loader_icd_term *icd_term;
|
||||
|
||||
struct loader_instance *inst = (struct loader_instance *)instance;
|
||||
icd_info = *(VkDebugReportCallbackEXT **)&callback;
|
||||
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) {
|
||||
@ -519,7 +525,7 @@ VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugReportCallbackEXT(VkInstance i
|
||||
|
||||
util_DestroyDebugReportCallback(inst, callback, pAllocator);
|
||||
|
||||
loader_free(pAllocator, icd_info);
|
||||
loader_free_with_instance_fallback(pAllocator, inst, icd_info);
|
||||
}
|
||||
|
||||
// This is the instance chain terminator function for DebugReportMessage
|
||||
@ -548,25 +554,25 @@ VKAPI_ATTR void VKAPI_CALL terminator_DebugReportMessageEXT(VkInstance instance,
|
||||
|
||||
// General utilities
|
||||
|
||||
static const VkExtensionProperties debug_utils_extension_info[] = {
|
||||
const VkExtensionProperties debug_utils_extension_info[] = {
|
||||
{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION},
|
||||
{VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_SPEC_VERSION},
|
||||
};
|
||||
|
||||
void destroy_debug_callbacks_chain(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator) {
|
||||
VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
|
||||
VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
|
||||
VkLayerDbgFunctionNode *pNext = NULL;
|
||||
while (pTrav) {
|
||||
pNext = pTrav->pNext;
|
||||
loader_free_with_instance_fallback(pAllocator, inst, pTrav);
|
||||
pTrav = pNext;
|
||||
}
|
||||
inst->DbgFunctionHead = NULL;
|
||||
inst->current_dbg_function_head = NULL;
|
||||
}
|
||||
|
||||
void add_debug_extensions_to_ext_list(const struct loader_instance *inst, struct loader_extension_list *ext_list) {
|
||||
loader_add_to_ext_list(inst, ext_list, sizeof(debug_utils_extension_info) / sizeof(VkExtensionProperties),
|
||||
debug_utils_extension_info);
|
||||
VkResult add_debug_extensions_to_ext_list(const struct loader_instance *inst, struct loader_extension_list *ext_list) {
|
||||
return loader_add_to_ext_list(inst, ext_list, sizeof(debug_utils_extension_info) / sizeof(VkExtensionProperties),
|
||||
debug_utils_extension_info);
|
||||
}
|
||||
|
||||
void check_for_enabled_debug_extensions(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) {
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
// General utilities
|
||||
|
||||
void add_debug_extensions_to_ext_list(const struct loader_instance *inst, struct loader_extension_list *ext_list);
|
||||
VkResult add_debug_extensions_to_ext_list(const struct loader_instance *inst, struct loader_extension_list *ext_list);
|
||||
void check_for_enabled_debug_extensions(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo);
|
||||
bool debug_extensions_InstanceGpa(struct loader_instance *ptr_instance, const char *name, void **addr);
|
||||
bool debug_utils_ReportFlagsToAnnotFlags(VkDebugReportFlagsEXT dr_flags, bool default_flag_is_spec,
|
||||
|
@ -24,259 +24,266 @@
|
||||
#pragma GCC optimize(3) // force gcc to use tail-calls
|
||||
#endif
|
||||
|
||||
// The asm declaration prevents name mangling which is necessary for macOS
|
||||
#if defined(MODIFY_UNKNOWN_FUNCTION_DECLS)
|
||||
#define ASM_NAME(name) __asm(name)
|
||||
#else
|
||||
#define ASM_NAME(name)
|
||||
#endif
|
||||
|
||||
// Clang-format does not understand macros.
|
||||
// clang-format off
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext0(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext1(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext2(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext3(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext4(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext5(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext6(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext7(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext8(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext9(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext10(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext11(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext12(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext13(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext14(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext15(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext16(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext17(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext18(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext19(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext20(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext21(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext22(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext23(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext24(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext25(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext26(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext27(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext28(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext29(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext30(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext31(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext32(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext33(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext34(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext35(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext36(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext37(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext38(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext39(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext40(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext41(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext42(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext43(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext44(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext45(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext46(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext47(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext48(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext49(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext50(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext51(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext52(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext53(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext54(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext55(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext56(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext57(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext58(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext59(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext60(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext61(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext62(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext63(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext64(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext65(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext66(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext67(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext68(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext69(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext70(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext71(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext72(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext73(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext74(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext75(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext76(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext77(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext78(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext79(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext80(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext81(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext82(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext83(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext84(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext85(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext86(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext87(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext88(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext89(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext90(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext91(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext92(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext93(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext94(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext95(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext96(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext97(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext98(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext99(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext100(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext101(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext102(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext103(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext104(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext105(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext106(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext107(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext108(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext109(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext110(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext111(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext112(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext113(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext114(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext115(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext116(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext117(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext118(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext119(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext120(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext121(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext122(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext123(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext124(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext125(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext126(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext127(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext128(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext129(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext130(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext131(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext132(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext133(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext134(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext135(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext136(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext137(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext138(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext139(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext140(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext141(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext142(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext143(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext144(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext145(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext146(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext147(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext148(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext149(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext150(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext151(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext152(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext153(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext154(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext155(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext156(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext157(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext158(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext159(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext160(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext161(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext162(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext163(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext164(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext165(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext166(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext167(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext168(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext169(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext170(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext171(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext172(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext173(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext174(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext175(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext176(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext177(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext178(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext179(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext180(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext181(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext182(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext183(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext184(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext185(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext186(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext187(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext188(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext189(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext190(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext191(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext192(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext193(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext194(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext195(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext196(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext197(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext198(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext199(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext200(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext201(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext202(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext203(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext204(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext205(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext206(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext207(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext208(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext209(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext210(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext211(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext212(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext213(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext214(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext215(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext216(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext217(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext218(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext219(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext220(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext221(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext222(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext223(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext224(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext225(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext226(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext227(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext228(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext229(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext230(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext231(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext232(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext233(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext234(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext235(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext236(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext237(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext238(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext239(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext240(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext241(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext242(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext243(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext244(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext245(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext246(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext247(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext248(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext249(VkDevice device);
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext0(VkDevice device) ASM_NAME("vkdev_ext0");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext1(VkDevice device) ASM_NAME("vkdev_ext1");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext2(VkDevice device) ASM_NAME("vkdev_ext2");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext3(VkDevice device) ASM_NAME("vkdev_ext3");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext4(VkDevice device) ASM_NAME("vkdev_ext4");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext5(VkDevice device) ASM_NAME("vkdev_ext5");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext6(VkDevice device) ASM_NAME("vkdev_ext6");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext7(VkDevice device) ASM_NAME("vkdev_ext7");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext8(VkDevice device) ASM_NAME("vkdev_ext8");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext9(VkDevice device) ASM_NAME("vkdev_ext9");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext10(VkDevice device) ASM_NAME("vkdev_ext10");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext11(VkDevice device) ASM_NAME("vkdev_ext11");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext12(VkDevice device) ASM_NAME("vkdev_ext12");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext13(VkDevice device) ASM_NAME("vkdev_ext13");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext14(VkDevice device) ASM_NAME("vkdev_ext14");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext15(VkDevice device) ASM_NAME("vkdev_ext15");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext16(VkDevice device) ASM_NAME("vkdev_ext16");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext17(VkDevice device) ASM_NAME("vkdev_ext17");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext18(VkDevice device) ASM_NAME("vkdev_ext18");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext19(VkDevice device) ASM_NAME("vkdev_ext19");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext20(VkDevice device) ASM_NAME("vkdev_ext20");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext21(VkDevice device) ASM_NAME("vkdev_ext21");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext22(VkDevice device) ASM_NAME("vkdev_ext22");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext23(VkDevice device) ASM_NAME("vkdev_ext23");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext24(VkDevice device) ASM_NAME("vkdev_ext24");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext25(VkDevice device) ASM_NAME("vkdev_ext25");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext26(VkDevice device) ASM_NAME("vkdev_ext26");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext27(VkDevice device) ASM_NAME("vkdev_ext27");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext28(VkDevice device) ASM_NAME("vkdev_ext28");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext29(VkDevice device) ASM_NAME("vkdev_ext29");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext30(VkDevice device) ASM_NAME("vkdev_ext30");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext31(VkDevice device) ASM_NAME("vkdev_ext31");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext32(VkDevice device) ASM_NAME("vkdev_ext32");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext33(VkDevice device) ASM_NAME("vkdev_ext33");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext34(VkDevice device) ASM_NAME("vkdev_ext34");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext35(VkDevice device) ASM_NAME("vkdev_ext35");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext36(VkDevice device) ASM_NAME("vkdev_ext36");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext37(VkDevice device) ASM_NAME("vkdev_ext37");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext38(VkDevice device) ASM_NAME("vkdev_ext38");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext39(VkDevice device) ASM_NAME("vkdev_ext39");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext40(VkDevice device) ASM_NAME("vkdev_ext40");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext41(VkDevice device) ASM_NAME("vkdev_ext41");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext42(VkDevice device) ASM_NAME("vkdev_ext42");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext43(VkDevice device) ASM_NAME("vkdev_ext43");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext44(VkDevice device) ASM_NAME("vkdev_ext44");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext45(VkDevice device) ASM_NAME("vkdev_ext45");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext46(VkDevice device) ASM_NAME("vkdev_ext46");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext47(VkDevice device) ASM_NAME("vkdev_ext47");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext48(VkDevice device) ASM_NAME("vkdev_ext48");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext49(VkDevice device) ASM_NAME("vkdev_ext49");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext50(VkDevice device) ASM_NAME("vkdev_ext50");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext51(VkDevice device) ASM_NAME("vkdev_ext51");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext52(VkDevice device) ASM_NAME("vkdev_ext52");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext53(VkDevice device) ASM_NAME("vkdev_ext53");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext54(VkDevice device) ASM_NAME("vkdev_ext54");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext55(VkDevice device) ASM_NAME("vkdev_ext55");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext56(VkDevice device) ASM_NAME("vkdev_ext56");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext57(VkDevice device) ASM_NAME("vkdev_ext57");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext58(VkDevice device) ASM_NAME("vkdev_ext58");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext59(VkDevice device) ASM_NAME("vkdev_ext59");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext60(VkDevice device) ASM_NAME("vkdev_ext60");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext61(VkDevice device) ASM_NAME("vkdev_ext61");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext62(VkDevice device) ASM_NAME("vkdev_ext62");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext63(VkDevice device) ASM_NAME("vkdev_ext63");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext64(VkDevice device) ASM_NAME("vkdev_ext64");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext65(VkDevice device) ASM_NAME("vkdev_ext65");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext66(VkDevice device) ASM_NAME("vkdev_ext66");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext67(VkDevice device) ASM_NAME("vkdev_ext67");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext68(VkDevice device) ASM_NAME("vkdev_ext68");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext69(VkDevice device) ASM_NAME("vkdev_ext69");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext70(VkDevice device) ASM_NAME("vkdev_ext70");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext71(VkDevice device) ASM_NAME("vkdev_ext71");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext72(VkDevice device) ASM_NAME("vkdev_ext72");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext73(VkDevice device) ASM_NAME("vkdev_ext73");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext74(VkDevice device) ASM_NAME("vkdev_ext74");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext75(VkDevice device) ASM_NAME("vkdev_ext75");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext76(VkDevice device) ASM_NAME("vkdev_ext76");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext77(VkDevice device) ASM_NAME("vkdev_ext77");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext78(VkDevice device) ASM_NAME("vkdev_ext78");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext79(VkDevice device) ASM_NAME("vkdev_ext79");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext80(VkDevice device) ASM_NAME("vkdev_ext80");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext81(VkDevice device) ASM_NAME("vkdev_ext81");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext82(VkDevice device) ASM_NAME("vkdev_ext82");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext83(VkDevice device) ASM_NAME("vkdev_ext83");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext84(VkDevice device) ASM_NAME("vkdev_ext84");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext85(VkDevice device) ASM_NAME("vkdev_ext85");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext86(VkDevice device) ASM_NAME("vkdev_ext86");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext87(VkDevice device) ASM_NAME("vkdev_ext87");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext88(VkDevice device) ASM_NAME("vkdev_ext88");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext89(VkDevice device) ASM_NAME("vkdev_ext89");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext90(VkDevice device) ASM_NAME("vkdev_ext90");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext91(VkDevice device) ASM_NAME("vkdev_ext91");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext92(VkDevice device) ASM_NAME("vkdev_ext92");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext93(VkDevice device) ASM_NAME("vkdev_ext93");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext94(VkDevice device) ASM_NAME("vkdev_ext94");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext95(VkDevice device) ASM_NAME("vkdev_ext95");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext96(VkDevice device) ASM_NAME("vkdev_ext96");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext97(VkDevice device) ASM_NAME("vkdev_ext97");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext98(VkDevice device) ASM_NAME("vkdev_ext98");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext99(VkDevice device) ASM_NAME("vkdev_ext99");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext100(VkDevice device) ASM_NAME("vkdev_ext100");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext101(VkDevice device) ASM_NAME("vkdev_ext101");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext102(VkDevice device) ASM_NAME("vkdev_ext102");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext103(VkDevice device) ASM_NAME("vkdev_ext103");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext104(VkDevice device) ASM_NAME("vkdev_ext104");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext105(VkDevice device) ASM_NAME("vkdev_ext105");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext106(VkDevice device) ASM_NAME("vkdev_ext106");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext107(VkDevice device) ASM_NAME("vkdev_ext107");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext108(VkDevice device) ASM_NAME("vkdev_ext108");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext109(VkDevice device) ASM_NAME("vkdev_ext109");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext110(VkDevice device) ASM_NAME("vkdev_ext110");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext111(VkDevice device) ASM_NAME("vkdev_ext111");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext112(VkDevice device) ASM_NAME("vkdev_ext112");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext113(VkDevice device) ASM_NAME("vkdev_ext113");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext114(VkDevice device) ASM_NAME("vkdev_ext114");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext115(VkDevice device) ASM_NAME("vkdev_ext115");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext116(VkDevice device) ASM_NAME("vkdev_ext116");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext117(VkDevice device) ASM_NAME("vkdev_ext117");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext118(VkDevice device) ASM_NAME("vkdev_ext118");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext119(VkDevice device) ASM_NAME("vkdev_ext119");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext120(VkDevice device) ASM_NAME("vkdev_ext120");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext121(VkDevice device) ASM_NAME("vkdev_ext121");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext122(VkDevice device) ASM_NAME("vkdev_ext122");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext123(VkDevice device) ASM_NAME("vkdev_ext123");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext124(VkDevice device) ASM_NAME("vkdev_ext124");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext125(VkDevice device) ASM_NAME("vkdev_ext125");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext126(VkDevice device) ASM_NAME("vkdev_ext126");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext127(VkDevice device) ASM_NAME("vkdev_ext127");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext128(VkDevice device) ASM_NAME("vkdev_ext128");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext129(VkDevice device) ASM_NAME("vkdev_ext129");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext130(VkDevice device) ASM_NAME("vkdev_ext130");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext131(VkDevice device) ASM_NAME("vkdev_ext131");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext132(VkDevice device) ASM_NAME("vkdev_ext132");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext133(VkDevice device) ASM_NAME("vkdev_ext133");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext134(VkDevice device) ASM_NAME("vkdev_ext134");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext135(VkDevice device) ASM_NAME("vkdev_ext135");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext136(VkDevice device) ASM_NAME("vkdev_ext136");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext137(VkDevice device) ASM_NAME("vkdev_ext137");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext138(VkDevice device) ASM_NAME("vkdev_ext138");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext139(VkDevice device) ASM_NAME("vkdev_ext139");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext140(VkDevice device) ASM_NAME("vkdev_ext140");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext141(VkDevice device) ASM_NAME("vkdev_ext141");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext142(VkDevice device) ASM_NAME("vkdev_ext142");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext143(VkDevice device) ASM_NAME("vkdev_ext143");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext144(VkDevice device) ASM_NAME("vkdev_ext144");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext145(VkDevice device) ASM_NAME("vkdev_ext145");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext146(VkDevice device) ASM_NAME("vkdev_ext146");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext147(VkDevice device) ASM_NAME("vkdev_ext147");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext148(VkDevice device) ASM_NAME("vkdev_ext148");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext149(VkDevice device) ASM_NAME("vkdev_ext149");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext150(VkDevice device) ASM_NAME("vkdev_ext150");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext151(VkDevice device) ASM_NAME("vkdev_ext151");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext152(VkDevice device) ASM_NAME("vkdev_ext152");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext153(VkDevice device) ASM_NAME("vkdev_ext153");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext154(VkDevice device) ASM_NAME("vkdev_ext154");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext155(VkDevice device) ASM_NAME("vkdev_ext155");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext156(VkDevice device) ASM_NAME("vkdev_ext156");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext157(VkDevice device) ASM_NAME("vkdev_ext157");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext158(VkDevice device) ASM_NAME("vkdev_ext158");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext159(VkDevice device) ASM_NAME("vkdev_ext159");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext160(VkDevice device) ASM_NAME("vkdev_ext160");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext161(VkDevice device) ASM_NAME("vkdev_ext161");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext162(VkDevice device) ASM_NAME("vkdev_ext162");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext163(VkDevice device) ASM_NAME("vkdev_ext163");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext164(VkDevice device) ASM_NAME("vkdev_ext164");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext165(VkDevice device) ASM_NAME("vkdev_ext165");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext166(VkDevice device) ASM_NAME("vkdev_ext166");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext167(VkDevice device) ASM_NAME("vkdev_ext167");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext168(VkDevice device) ASM_NAME("vkdev_ext168");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext169(VkDevice device) ASM_NAME("vkdev_ext169");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext170(VkDevice device) ASM_NAME("vkdev_ext170");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext171(VkDevice device) ASM_NAME("vkdev_ext171");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext172(VkDevice device) ASM_NAME("vkdev_ext172");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext173(VkDevice device) ASM_NAME("vkdev_ext173");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext174(VkDevice device) ASM_NAME("vkdev_ext174");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext175(VkDevice device) ASM_NAME("vkdev_ext175");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext176(VkDevice device) ASM_NAME("vkdev_ext176");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext177(VkDevice device) ASM_NAME("vkdev_ext177");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext178(VkDevice device) ASM_NAME("vkdev_ext178");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext179(VkDevice device) ASM_NAME("vkdev_ext179");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext180(VkDevice device) ASM_NAME("vkdev_ext180");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext181(VkDevice device) ASM_NAME("vkdev_ext181");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext182(VkDevice device) ASM_NAME("vkdev_ext182");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext183(VkDevice device) ASM_NAME("vkdev_ext183");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext184(VkDevice device) ASM_NAME("vkdev_ext184");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext185(VkDevice device) ASM_NAME("vkdev_ext185");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext186(VkDevice device) ASM_NAME("vkdev_ext186");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext187(VkDevice device) ASM_NAME("vkdev_ext187");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext188(VkDevice device) ASM_NAME("vkdev_ext188");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext189(VkDevice device) ASM_NAME("vkdev_ext189");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext190(VkDevice device) ASM_NAME("vkdev_ext190");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext191(VkDevice device) ASM_NAME("vkdev_ext191");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext192(VkDevice device) ASM_NAME("vkdev_ext192");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext193(VkDevice device) ASM_NAME("vkdev_ext193");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext194(VkDevice device) ASM_NAME("vkdev_ext194");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext195(VkDevice device) ASM_NAME("vkdev_ext195");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext196(VkDevice device) ASM_NAME("vkdev_ext196");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext197(VkDevice device) ASM_NAME("vkdev_ext197");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext198(VkDevice device) ASM_NAME("vkdev_ext198");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext199(VkDevice device) ASM_NAME("vkdev_ext199");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext200(VkDevice device) ASM_NAME("vkdev_ext200");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext201(VkDevice device) ASM_NAME("vkdev_ext201");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext202(VkDevice device) ASM_NAME("vkdev_ext202");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext203(VkDevice device) ASM_NAME("vkdev_ext203");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext204(VkDevice device) ASM_NAME("vkdev_ext204");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext205(VkDevice device) ASM_NAME("vkdev_ext205");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext206(VkDevice device) ASM_NAME("vkdev_ext206");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext207(VkDevice device) ASM_NAME("vkdev_ext207");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext208(VkDevice device) ASM_NAME("vkdev_ext208");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext209(VkDevice device) ASM_NAME("vkdev_ext209");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext210(VkDevice device) ASM_NAME("vkdev_ext210");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext211(VkDevice device) ASM_NAME("vkdev_ext211");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext212(VkDevice device) ASM_NAME("vkdev_ext212");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext213(VkDevice device) ASM_NAME("vkdev_ext213");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext214(VkDevice device) ASM_NAME("vkdev_ext214");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext215(VkDevice device) ASM_NAME("vkdev_ext215");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext216(VkDevice device) ASM_NAME("vkdev_ext216");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext217(VkDevice device) ASM_NAME("vkdev_ext217");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext218(VkDevice device) ASM_NAME("vkdev_ext218");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext219(VkDevice device) ASM_NAME("vkdev_ext219");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext220(VkDevice device) ASM_NAME("vkdev_ext220");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext221(VkDevice device) ASM_NAME("vkdev_ext221");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext222(VkDevice device) ASM_NAME("vkdev_ext222");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext223(VkDevice device) ASM_NAME("vkdev_ext223");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext224(VkDevice device) ASM_NAME("vkdev_ext224");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext225(VkDevice device) ASM_NAME("vkdev_ext225");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext226(VkDevice device) ASM_NAME("vkdev_ext226");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext227(VkDevice device) ASM_NAME("vkdev_ext227");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext228(VkDevice device) ASM_NAME("vkdev_ext228");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext229(VkDevice device) ASM_NAME("vkdev_ext229");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext230(VkDevice device) ASM_NAME("vkdev_ext230");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext231(VkDevice device) ASM_NAME("vkdev_ext231");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext232(VkDevice device) ASM_NAME("vkdev_ext232");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext233(VkDevice device) ASM_NAME("vkdev_ext233");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext234(VkDevice device) ASM_NAME("vkdev_ext234");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext235(VkDevice device) ASM_NAME("vkdev_ext235");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext236(VkDevice device) ASM_NAME("vkdev_ext236");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext237(VkDevice device) ASM_NAME("vkdev_ext237");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext238(VkDevice device) ASM_NAME("vkdev_ext238");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext239(VkDevice device) ASM_NAME("vkdev_ext239");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext240(VkDevice device) ASM_NAME("vkdev_ext240");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext241(VkDevice device) ASM_NAME("vkdev_ext241");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext242(VkDevice device) ASM_NAME("vkdev_ext242");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext243(VkDevice device) ASM_NAME("vkdev_ext243");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext244(VkDevice device) ASM_NAME("vkdev_ext244");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext245(VkDevice device) ASM_NAME("vkdev_ext245");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext246(VkDevice device) ASM_NAME("vkdev_ext246");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext247(VkDevice device) ASM_NAME("vkdev_ext247");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext248(VkDevice device) ASM_NAME("vkdev_ext248");
|
||||
VKAPI_ATTR void VKAPI_CALL vkdev_ext249(VkDevice device) ASM_NAME("vkdev_ext249");
|
||||
|
||||
void *loader_get_dev_ext_trampoline(uint32_t index) {
|
||||
switch (index) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include "allocation.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@ -36,11 +36,12 @@ DIR *opendir(const VkAllocationCallbacks *pAllocator, const char *name) {
|
||||
size_t base_length = strlen(name);
|
||||
const char *all = /* search pattern must end with suitable wildcard */
|
||||
strchr("/\\", name[base_length - 1]) ? "*" : "/*";
|
||||
size_t full_length = base_length + strlen(all) + 1;
|
||||
|
||||
if ((dir = (DIR *)loader_alloc(pAllocator, sizeof *dir, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)) != 0 &&
|
||||
(dir->name = (char *)loader_alloc(pAllocator, base_length + strlen(all) + 1, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)) !=
|
||||
0) {
|
||||
strcat(strcpy(dir->name, name), all);
|
||||
(dir->name = (char *)loader_calloc(pAllocator, full_length, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)) != 0) {
|
||||
loader_strncpy(dir->name, full_length, name, base_length);
|
||||
loader_strncat(dir->name, full_length, all, strlen(all));
|
||||
|
||||
if ((dir->handle = (handle_type)_findfirst(dir->name, &dir->info)) != -1) {
|
||||
dir->result.d_name = 0;
|
||||
@ -108,7 +109,7 @@ void rewinddir(DIR *dir) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@ -46,6 +46,6 @@ void rewinddir(DIR *);
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
@ -46,7 +46,7 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceExternalImageFormatPropertiesNV(
|
||||
const VkLayerInstanceDispatchTable *disp;
|
||||
VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
|
||||
if (VK_NULL_HANDLE == unwrapped_phys_dev) {
|
||||
loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
"vkGetPhysicalDeviceExternalImageFormatPropertiesNV: Invalid physicalDevice "
|
||||
"[VUID-vkGetPhysicalDeviceExternalImageFormatPropertiesNV-physicalDevice-parameter]");
|
||||
abort(); /* Intentionally fail so user can correct issue. */
|
||||
@ -92,7 +92,7 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysic
|
||||
const VkLayerInstanceDispatchTable *disp;
|
||||
VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
|
||||
if (VK_NULL_HANDLE == unwrapped_phys_dev) {
|
||||
loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
"vkGetPhysicalDeviceExternalImageFormatPropertiesNV: Invalid physicalDevice "
|
||||
"[VUID-vkGetPhysicalDeviceSurfaceCapabilities2EXT-physicalDevice-parameter]");
|
||||
abort(); /* Intentionally fail so user can correct issue. */
|
||||
@ -157,7 +157,7 @@ VKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice
|
||||
const VkLayerInstanceDispatchTable *disp;
|
||||
VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
|
||||
if (VK_NULL_HANDLE == unwrapped_phys_dev) {
|
||||
loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
"vkReleaseDisplayEXT: Invalid physicalDevice [VUID-vkReleaseDisplayEXT-physicalDevice-parameter]");
|
||||
abort(); /* Intentionally fail so user can correct issue. */
|
||||
}
|
||||
@ -170,7 +170,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_ReleaseDisplayEXT(VkPhysicalDevice phy
|
||||
struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
|
||||
|
||||
if (icd_term->dispatch.ReleaseDisplayEXT == NULL) {
|
||||
loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"ICD \"%s\" associated with VkPhysicalDevice does not support vkReleaseDisplayEXT - Consequently, the call is "
|
||||
"invalid because it should not be possible to acquire a display on this device",
|
||||
icd_term->scanned_icd->lib_name);
|
||||
@ -181,12 +181,12 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_ReleaseDisplayEXT(VkPhysicalDevice phy
|
||||
|
||||
// ---- VK_EXT_acquire_xlib_display extension trampoline/terminators
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, VkDisplayKHR display) {
|
||||
const VkLayerInstanceDispatchTable *disp;
|
||||
VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
|
||||
if (VK_NULL_HANDLE == unwrapped_phys_dev) {
|
||||
loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
"vkAcquireXlibDisplayEXT: Invalid physicalDevice [VUID-vkAcquireXlibDisplayEXT-physicalDevice-parameter]");
|
||||
abort(); /* Intentionally fail so user can correct issue. */
|
||||
}
|
||||
@ -217,7 +217,7 @@ VKAPI_ATTR VkResult VKAPI_CALL GetRandROutputDisplayEXT(VkPhysicalDevice physica
|
||||
const VkLayerInstanceDispatchTable *disp;
|
||||
VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
|
||||
if (VK_NULL_HANDLE == unwrapped_phys_dev) {
|
||||
loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
"vkGetRandROutputDisplayEXT: Invalid physicalDevice [VUID-vkGetRandROutputDisplayEXT-physicalDevice-parameter]");
|
||||
abort(); /* Intentionally fail so user can correct issue. */
|
||||
}
|
||||
@ -247,7 +247,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetRandROutputDisplayEXT(VkPhysicalDev
|
||||
|
||||
#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModes2EXT(VkPhysicalDevice physicalDevice,
|
||||
const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
|
||||
uint32_t *pPresentModeCount,
|
||||
@ -255,7 +255,7 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModes2EXT(VkPhysic
|
||||
const VkLayerInstanceDispatchTable *disp;
|
||||
VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
|
||||
if (VK_NULL_HANDLE == unwrapped_phys_dev) {
|
||||
loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
"vkGetPhysicalDeviceSurfacePresentModes2EXT: Invalid physicalDevice "
|
||||
"[VUID-vkGetPhysicalDeviceSurfacePresentModes2EXT-physicalDevice-parameter]");
|
||||
abort(); /* Intentionally fail so user can correct issue. */
|
||||
@ -270,7 +270,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModes2E
|
||||
struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
|
||||
struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
|
||||
if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT) {
|
||||
loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceSurfacePresentModes2EXT");
|
||||
abort();
|
||||
}
|
||||
@ -293,7 +293,7 @@ VKAPI_ATTR VkResult VKAPI_CALL GetDeviceGroupSurfacePresentModes2EXT(VkDevice de
|
||||
VkDeviceGroupPresentModeFlagsKHR *pModes) {
|
||||
const VkLayerDispatchTable *disp = loader_get_dispatch(device);
|
||||
if (NULL == disp) {
|
||||
loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
"vkGetDeviceGroupSurfacePresentModes2EXT: Invalid device "
|
||||
"[VUID-vkGetDeviceGroupSurfacePresentModes2EXT-device-parameter]");
|
||||
abort(); /* Intentionally fail so user can correct issue. */
|
||||
@ -307,18 +307,30 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModes2EXT(
|
||||
uint32_t icd_index = 0;
|
||||
struct loader_device *dev;
|
||||
struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
|
||||
if (NULL != icd_term && NULL != icd_term->dispatch.GetDeviceGroupSurfacePresentModes2EXT) {
|
||||
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface;
|
||||
if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != 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.GetDeviceGroupSurfacePresentModes2EXT(device, &surface_info_copy, pModes);
|
||||
}
|
||||
return icd_term->dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes);
|
||||
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,
|
||||
"vkGetDeviceGroupSurfacePresentModes2EXT Terminator: Invalid device handle. This is likely the result of a "
|
||||
"layer wrapping device handles and failing to unwrap them in all functions. "
|
||||
"[VUID-vkGetDeviceGroupSurfacePresentModes2EXT-device-parameter]");
|
||||
abort(); /* Intentionally fail so user can correct issue. */
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
if (NULL == pSurfaceInfo) {
|
||||
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
"vkGetDeviceGroupSurfacePresentModes2EXT: Invalid pSurfaceInfo pointer "
|
||||
"[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);
|
||||
}
|
||||
return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes);
|
||||
}
|
||||
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
@ -330,7 +342,7 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceToolPropertiesEXT(VkPhysicalDevi
|
||||
const VkLayerInstanceDispatchTable *disp;
|
||||
VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
|
||||
if (VK_NULL_HANDLE == unwrapped_phys_dev) {
|
||||
loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
|
||||
"vkGetPhysicalDeviceToolPropertiesEXT: Invalid physicalDevice "
|
||||
"[VUID-vkGetPhysicalDeviceToolPropertiesEXT-physicalDevice-parameter]");
|
||||
abort(); /* Intentionally fail so user can correct issue. */
|
||||
|
@ -49,7 +49,7 @@ VKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display);
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display* dpy,
|
||||
@ -62,7 +62,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetRandROutputDisplayEXT(VkPhysicalDev
|
||||
VkDisplayKHR* pDisplay);
|
||||
#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModes2EXT(VkPhysicalDevice physicalDevice,
|
||||
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
|
||||
uint32_t* pPresentModeCount,
|
||||
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
# Disable clang-format for generated code
|
||||
DisableFormat: true
|
||||
SortIncludes: false
|
||||
...
|
@ -1,28 +0,0 @@
|
||||
# *** THIS FILE IS GENERATED - DO NOT EDIT ***
|
||||
# See loader_versioning_generator.py for modifications
|
||||
|
||||
############################################################################
|
||||
#
|
||||
# Copyright (c) 2021 The Khronos Group Inc.
|
||||
# Copyright (c) 2021 Valve Corporation
|
||||
# Copyright (c) 2021 LunarG, Inc.
|
||||
# Copyright (c) 2021 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Author: Charles Giessen <charles@lunarg.com>
|
||||
#
|
||||
############################################################################
|
||||
|
||||
set(LOADER_GENERATED_HEADER_VERSION "1.3.231")
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,8 @@
|
||||
* Copyright (c) 2015-2022 The Khronos Group Inc.
|
||||
* Copyright (c) 2015-2022 Valve Corporation
|
||||
* Copyright (c) 2015-2022 LunarG, Inc.
|
||||
* Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (c) 2023-2023 RasterGrid Kft.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -22,16 +24,19 @@
|
||||
* Author: Mark Young <marky@lunarg.com>
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
#pragma once
|
||||
|
||||
#if !defined(PFN_GetPhysicalDeviceProcAddr)
|
||||
typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName);
|
||||
#endif
|
||||
|
||||
// Instance function pointer dispatch table
|
||||
typedef struct VkLayerInstanceDispatchTable_ {
|
||||
// Manually add in GetPhysicalDeviceProcAddr entry
|
||||
PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr;
|
||||
|
||||
// ---- Core 1_0 commands
|
||||
// ---- Core Vulkan 1.0 commands
|
||||
PFN_vkCreateInstance CreateInstance;
|
||||
PFN_vkDestroyInstance DestroyInstance;
|
||||
PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
|
||||
@ -49,7 +54,7 @@ typedef struct VkLayerInstanceDispatchTable_ {
|
||||
PFN_vkEnumerateDeviceLayerProperties EnumerateDeviceLayerProperties;
|
||||
PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties;
|
||||
|
||||
// ---- Core 1_1 commands
|
||||
// ---- Core Vulkan 1.1 commands
|
||||
PFN_vkEnumerateInstanceVersion EnumerateInstanceVersion;
|
||||
PFN_vkEnumeratePhysicalDeviceGroups EnumeratePhysicalDeviceGroups;
|
||||
PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2;
|
||||
@ -63,7 +68,7 @@ typedef struct VkLayerInstanceDispatchTable_ {
|
||||
PFN_vkGetPhysicalDeviceExternalFenceProperties GetPhysicalDeviceExternalFenceProperties;
|
||||
PFN_vkGetPhysicalDeviceExternalSemaphoreProperties GetPhysicalDeviceExternalSemaphoreProperties;
|
||||
|
||||
// ---- Core 1_3 commands
|
||||
// ---- Core Vulkan 1.3 commands
|
||||
PFN_vkGetPhysicalDeviceToolProperties GetPhysicalDeviceToolProperties;
|
||||
|
||||
// ---- VK_KHR_surface extension commands
|
||||
@ -86,49 +91,45 @@ typedef struct VkLayerInstanceDispatchTable_ {
|
||||
PFN_vkCreateDisplayPlaneSurfaceKHR CreateDisplayPlaneSurfaceKHR;
|
||||
|
||||
// ---- VK_KHR_xlib_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR;
|
||||
#endif // VK_USE_PLATFORM_XLIB_KHR
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR GetPhysicalDeviceXlibPresentationSupportKHR;
|
||||
#endif // VK_USE_PLATFORM_XLIB_KHR
|
||||
|
||||
// ---- VK_KHR_xcb_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
PFN_vkCreateXcbSurfaceKHR CreateXcbSurfaceKHR;
|
||||
#endif // VK_USE_PLATFORM_XCB_KHR
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR GetPhysicalDeviceXcbPresentationSupportKHR;
|
||||
#endif // VK_USE_PLATFORM_XCB_KHR
|
||||
|
||||
// ---- VK_KHR_wayland_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
PFN_vkCreateWaylandSurfaceKHR CreateWaylandSurfaceKHR;
|
||||
#endif // VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR GetPhysicalDeviceWaylandPresentationSupportKHR;
|
||||
#endif // VK_USE_PLATFORM_WAYLAND_KHR
|
||||
|
||||
// ---- VK_KHR_android_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
PFN_vkCreateAndroidSurfaceKHR CreateAndroidSurfaceKHR;
|
||||
#endif // VK_USE_PLATFORM_ANDROID_KHR
|
||||
|
||||
// ---- VK_KHR_win32_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkCreateWin32SurfaceKHR CreateWin32SurfaceKHR;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR GetPhysicalDeviceWin32PresentationSupportKHR;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
|
||||
// ---- VK_KHR_video_queue extension commands
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR GetPhysicalDeviceVideoCapabilitiesKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR GetPhysicalDeviceVideoFormatPropertiesKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
|
||||
// ---- VK_KHR_get_physical_device_properties2 extension commands
|
||||
PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysicalDeviceFeatures2KHR;
|
||||
@ -168,13 +169,22 @@ typedef struct VkLayerInstanceDispatchTable_ {
|
||||
// ---- VK_KHR_fragment_shading_rate extension commands
|
||||
PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR GetPhysicalDeviceFragmentShadingRatesKHR;
|
||||
|
||||
// ---- VK_KHR_video_encode_queue extension commands
|
||||
PFN_vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR;
|
||||
|
||||
// ---- VK_KHR_cooperative_matrix extension commands
|
||||
PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR GetPhysicalDeviceCooperativeMatrixPropertiesKHR;
|
||||
|
||||
// ---- VK_KHR_calibrated_timestamps extension commands
|
||||
PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsKHR GetPhysicalDeviceCalibrateableTimeDomainsKHR;
|
||||
|
||||
// ---- VK_EXT_debug_report extension commands
|
||||
PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
|
||||
PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT;
|
||||
PFN_vkDebugReportMessageEXT DebugReportMessageEXT;
|
||||
|
||||
// ---- VK_GGP_stream_descriptor_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_GGP
|
||||
#if defined(VK_USE_PLATFORM_GGP)
|
||||
PFN_vkCreateStreamDescriptorSurfaceGGP CreateStreamDescriptorSurfaceGGP;
|
||||
#endif // VK_USE_PLATFORM_GGP
|
||||
|
||||
@ -182,7 +192,7 @@ typedef struct VkLayerInstanceDispatchTable_ {
|
||||
PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV GetPhysicalDeviceExternalImageFormatPropertiesNV;
|
||||
|
||||
// ---- VK_NN_vi_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_VI_NN
|
||||
#if defined(VK_USE_PLATFORM_VI_NN)
|
||||
PFN_vkCreateViSurfaceNN CreateViSurfaceNN;
|
||||
#endif // VK_USE_PLATFORM_VI_NN
|
||||
|
||||
@ -190,10 +200,10 @@ typedef struct VkLayerInstanceDispatchTable_ {
|
||||
PFN_vkReleaseDisplayEXT ReleaseDisplayEXT;
|
||||
|
||||
// ---- VK_EXT_acquire_xlib_display extension commands
|
||||
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
|
||||
PFN_vkAcquireXlibDisplayEXT AcquireXlibDisplayEXT;
|
||||
#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
|
||||
PFN_vkGetRandROutputDisplayEXT GetRandROutputDisplayEXT;
|
||||
#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
|
||||
@ -201,12 +211,12 @@ typedef struct VkLayerInstanceDispatchTable_ {
|
||||
PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT GetPhysicalDeviceSurfaceCapabilities2EXT;
|
||||
|
||||
// ---- VK_MVK_ios_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_IOS_MVK
|
||||
#if defined(VK_USE_PLATFORM_IOS_MVK)
|
||||
PFN_vkCreateIOSSurfaceMVK CreateIOSSurfaceMVK;
|
||||
#endif // VK_USE_PLATFORM_IOS_MVK
|
||||
|
||||
// ---- VK_MVK_macos_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_MACOS_MVK
|
||||
#if defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
PFN_vkCreateMacOSSurfaceMVK CreateMacOSSurfaceMVK;
|
||||
#endif // VK_USE_PLATFORM_MACOS_MVK
|
||||
|
||||
@ -222,12 +232,12 @@ typedef struct VkLayerInstanceDispatchTable_ {
|
||||
PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT GetPhysicalDeviceCalibrateableTimeDomainsEXT;
|
||||
|
||||
// ---- VK_FUCHSIA_imagepipe_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
PFN_vkCreateImagePipeSurfaceFUCHSIA CreateImagePipeSurfaceFUCHSIA;
|
||||
#endif // VK_USE_PLATFORM_FUCHSIA
|
||||
|
||||
// ---- VK_EXT_metal_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
PFN_vkCreateMetalSurfaceEXT CreateMetalSurfaceEXT;
|
||||
#endif // VK_USE_PLATFORM_METAL_EXT
|
||||
|
||||
@ -241,7 +251,7 @@ typedef struct VkLayerInstanceDispatchTable_ {
|
||||
PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV;
|
||||
|
||||
// ---- VK_EXT_full_screen_exclusive extension commands
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT GetPhysicalDeviceSurfacePresentModes2EXT;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
|
||||
@ -253,26 +263,26 @@ typedef struct VkLayerInstanceDispatchTable_ {
|
||||
PFN_vkGetDrmDisplayEXT GetDrmDisplayEXT;
|
||||
|
||||
// ---- VK_NV_acquire_winrt_display extension commands
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkAcquireWinrtDisplayNV AcquireWinrtDisplayNV;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkGetWinrtDisplayNV GetWinrtDisplayNV;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
|
||||
// ---- VK_EXT_directfb_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
|
||||
PFN_vkCreateDirectFBSurfaceEXT CreateDirectFBSurfaceEXT;
|
||||
#endif // VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
|
||||
PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT GetPhysicalDeviceDirectFBPresentationSupportEXT;
|
||||
#endif // VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
|
||||
// ---- VK_QNX_screen_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_SCREEN_QNX
|
||||
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
|
||||
PFN_vkCreateScreenSurfaceQNX CreateScreenSurfaceQNX;
|
||||
#endif // VK_USE_PLATFORM_SCREEN_QNX
|
||||
#ifdef VK_USE_PLATFORM_SCREEN_QNX
|
||||
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
|
||||
PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX GetPhysicalDeviceScreenPresentationSupportQNX;
|
||||
#endif // VK_USE_PLATFORM_SCREEN_QNX
|
||||
|
||||
@ -290,7 +300,7 @@ typedef struct VkLayerInstanceDispatchTable_ {
|
||||
typedef struct VkLayerDispatchTable_ {
|
||||
uint64_t magic; // Should be DEVICE_DISP_TABLE_MAGIC_NUMBER
|
||||
|
||||
// ---- Core 1_0 commands
|
||||
// ---- Core Vulkan 1.0 commands
|
||||
PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
|
||||
PFN_vkDestroyDevice DestroyDevice;
|
||||
PFN_vkGetDeviceQueue GetDeviceQueue;
|
||||
@ -413,7 +423,7 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkCmdEndRenderPass CmdEndRenderPass;
|
||||
PFN_vkCmdExecuteCommands CmdExecuteCommands;
|
||||
|
||||
// ---- Core 1_1 commands
|
||||
// ---- Core Vulkan 1.1 commands
|
||||
PFN_vkBindBufferMemory2 BindBufferMemory2;
|
||||
PFN_vkBindImageMemory2 BindImageMemory2;
|
||||
PFN_vkGetDeviceGroupPeerMemoryFeatures GetDeviceGroupPeerMemoryFeatures;
|
||||
@ -431,7 +441,7 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkUpdateDescriptorSetWithTemplate UpdateDescriptorSetWithTemplate;
|
||||
PFN_vkGetDescriptorSetLayoutSupport GetDescriptorSetLayoutSupport;
|
||||
|
||||
// ---- Core 1_2 commands
|
||||
// ---- Core Vulkan 1.2 commands
|
||||
PFN_vkCmdDrawIndirectCount CmdDrawIndirectCount;
|
||||
PFN_vkCmdDrawIndexedIndirectCount CmdDrawIndexedIndirectCount;
|
||||
PFN_vkCreateRenderPass2 CreateRenderPass2;
|
||||
@ -446,7 +456,7 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkGetBufferOpaqueCaptureAddress GetBufferOpaqueCaptureAddress;
|
||||
PFN_vkGetDeviceMemoryOpaqueCaptureAddress GetDeviceMemoryOpaqueCaptureAddress;
|
||||
|
||||
// ---- Core 1_3 commands
|
||||
// ---- Core Vulkan 1.3 commands
|
||||
PFN_vkCreatePrivateDataSlot CreatePrivateDataSlot;
|
||||
PFN_vkDestroyPrivateDataSlot DestroyPrivateDataSlot;
|
||||
PFN_vkSetPrivateData SetPrivateData;
|
||||
@ -498,41 +508,19 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR;
|
||||
|
||||
// ---- VK_KHR_video_queue extension commands
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkCreateVideoSessionKHR CreateVideoSessionKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkDestroyVideoSessionKHR DestroyVideoSessionKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkGetVideoSessionMemoryRequirementsKHR GetVideoSessionMemoryRequirementsKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkBindVideoSessionMemoryKHR BindVideoSessionMemoryKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkCreateVideoSessionParametersKHR CreateVideoSessionParametersKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkUpdateVideoSessionParametersKHR UpdateVideoSessionParametersKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkDestroyVideoSessionParametersKHR DestroyVideoSessionParametersKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkCmdBeginVideoCodingKHR CmdBeginVideoCodingKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkCmdEndVideoCodingKHR CmdEndVideoCodingKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkCmdControlVideoCodingKHR CmdControlVideoCodingKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
|
||||
// ---- VK_KHR_video_decode_queue extension commands
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkCmdDecodeVideoKHR CmdDecodeVideoKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
|
||||
// ---- VK_KHR_dynamic_rendering extension commands
|
||||
PFN_vkCmdBeginRenderingKHR CmdBeginRenderingKHR;
|
||||
@ -547,10 +535,10 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkTrimCommandPoolKHR TrimCommandPoolKHR;
|
||||
|
||||
// ---- VK_KHR_external_memory_win32 extension commands
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkGetMemoryWin32HandleKHR GetMemoryWin32HandleKHR;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkGetMemoryWin32HandlePropertiesKHR GetMemoryWin32HandlePropertiesKHR;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
|
||||
@ -559,10 +547,10 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkGetMemoryFdPropertiesKHR GetMemoryFdPropertiesKHR;
|
||||
|
||||
// ---- VK_KHR_external_semaphore_win32 extension commands
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkImportSemaphoreWin32HandleKHR ImportSemaphoreWin32HandleKHR;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkGetSemaphoreWin32HandleKHR GetSemaphoreWin32HandleKHR;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
|
||||
@ -589,10 +577,10 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkGetSwapchainStatusKHR GetSwapchainStatusKHR;
|
||||
|
||||
// ---- VK_KHR_external_fence_win32 extension commands
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkImportFenceWin32HandleKHR ImportFenceWin32HandleKHR;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkGetFenceWin32HandleKHR GetFenceWin32HandleKHR;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
|
||||
@ -652,10 +640,13 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkGetPipelineExecutableStatisticsKHR GetPipelineExecutableStatisticsKHR;
|
||||
PFN_vkGetPipelineExecutableInternalRepresentationsKHR GetPipelineExecutableInternalRepresentationsKHR;
|
||||
|
||||
// ---- VK_KHR_map_memory2 extension commands
|
||||
PFN_vkMapMemory2KHR MapMemory2KHR;
|
||||
PFN_vkUnmapMemory2KHR UnmapMemory2KHR;
|
||||
|
||||
// ---- VK_KHR_video_encode_queue extension commands
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkGetEncodedVideoSessionParametersKHR GetEncodedVideoSessionParametersKHR;
|
||||
PFN_vkCmdEncodeVideoKHR CmdEncodeVideoKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
|
||||
// ---- VK_KHR_synchronization2 extension commands
|
||||
PFN_vkCmdSetEvent2KHR CmdSetEvent2KHR;
|
||||
@ -683,6 +674,23 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkGetDeviceImageMemoryRequirementsKHR GetDeviceImageMemoryRequirementsKHR;
|
||||
PFN_vkGetDeviceImageSparseMemoryRequirementsKHR GetDeviceImageSparseMemoryRequirementsKHR;
|
||||
|
||||
// ---- VK_KHR_maintenance5 extension commands
|
||||
PFN_vkCmdBindIndexBuffer2KHR CmdBindIndexBuffer2KHR;
|
||||
PFN_vkGetRenderingAreaGranularityKHR GetRenderingAreaGranularityKHR;
|
||||
PFN_vkGetDeviceImageSubresourceLayoutKHR GetDeviceImageSubresourceLayoutKHR;
|
||||
PFN_vkGetImageSubresourceLayout2KHR GetImageSubresourceLayout2KHR;
|
||||
|
||||
// ---- VK_KHR_calibrated_timestamps extension commands
|
||||
PFN_vkGetCalibratedTimestampsKHR GetCalibratedTimestampsKHR;
|
||||
|
||||
// ---- VK_KHR_maintenance6 extension commands
|
||||
PFN_vkCmdBindDescriptorSets2KHR CmdBindDescriptorSets2KHR;
|
||||
PFN_vkCmdPushConstants2KHR CmdPushConstants2KHR;
|
||||
PFN_vkCmdPushDescriptorSet2KHR CmdPushDescriptorSet2KHR;
|
||||
PFN_vkCmdPushDescriptorSetWithTemplate2KHR CmdPushDescriptorSetWithTemplate2KHR;
|
||||
PFN_vkCmdSetDescriptorBufferOffsets2EXT CmdSetDescriptorBufferOffsets2EXT;
|
||||
PFN_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT CmdBindDescriptorBufferEmbeddedSamplers2EXT;
|
||||
|
||||
// ---- VK_EXT_debug_marker extension commands
|
||||
PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT;
|
||||
PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT;
|
||||
@ -717,7 +725,7 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkGetShaderInfoAMD GetShaderInfoAMD;
|
||||
|
||||
// ---- VK_NV_external_memory_win32 extension commands
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkGetMemoryWin32HandleNV GetMemoryWin32HandleNV;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
|
||||
@ -740,6 +748,8 @@ typedef struct VkLayerDispatchTable_ {
|
||||
|
||||
// ---- VK_EXT_discard_rectangles extension commands
|
||||
PFN_vkCmdSetDiscardRectangleEXT CmdSetDiscardRectangleEXT;
|
||||
PFN_vkCmdSetDiscardRectangleEnableEXT CmdSetDiscardRectangleEnableEXT;
|
||||
PFN_vkCmdSetDiscardRectangleModeEXT CmdSetDiscardRectangleModeEXT;
|
||||
|
||||
// ---- VK_EXT_hdr_metadata extension commands
|
||||
PFN_vkSetHdrMetadataEXT SetHdrMetadataEXT;
|
||||
@ -755,13 +765,36 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT;
|
||||
|
||||
// ---- VK_ANDROID_external_memory_android_hardware_buffer extension commands
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
PFN_vkGetAndroidHardwareBufferPropertiesANDROID GetAndroidHardwareBufferPropertiesANDROID;
|
||||
#endif // VK_USE_PLATFORM_ANDROID_KHR
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
PFN_vkGetMemoryAndroidHardwareBufferANDROID GetMemoryAndroidHardwareBufferANDROID;
|
||||
#endif // VK_USE_PLATFORM_ANDROID_KHR
|
||||
|
||||
// ---- VK_AMDX_shader_enqueue extension commands
|
||||
#if defined(VK_ENABLE_BETA_EXTENSIONS)
|
||||
PFN_vkCreateExecutionGraphPipelinesAMDX CreateExecutionGraphPipelinesAMDX;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#if defined(VK_ENABLE_BETA_EXTENSIONS)
|
||||
PFN_vkGetExecutionGraphPipelineScratchSizeAMDX GetExecutionGraphPipelineScratchSizeAMDX;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#if defined(VK_ENABLE_BETA_EXTENSIONS)
|
||||
PFN_vkGetExecutionGraphPipelineNodeIndexAMDX GetExecutionGraphPipelineNodeIndexAMDX;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#if defined(VK_ENABLE_BETA_EXTENSIONS)
|
||||
PFN_vkCmdInitializeGraphScratchMemoryAMDX CmdInitializeGraphScratchMemoryAMDX;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#if defined(VK_ENABLE_BETA_EXTENSIONS)
|
||||
PFN_vkCmdDispatchGraphAMDX CmdDispatchGraphAMDX;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#if defined(VK_ENABLE_BETA_EXTENSIONS)
|
||||
PFN_vkCmdDispatchGraphIndirectAMDX CmdDispatchGraphIndirectAMDX;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#if defined(VK_ENABLE_BETA_EXTENSIONS)
|
||||
PFN_vkCmdDispatchGraphIndirectCountAMDX CmdDispatchGraphIndirectCountAMDX;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
|
||||
// ---- VK_EXT_sample_locations extension commands
|
||||
PFN_vkCmdSetSampleLocationsEXT CmdSetSampleLocationsEXT;
|
||||
|
||||
@ -809,6 +842,7 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkCmdDrawMeshTasksIndirectCountNV CmdDrawMeshTasksIndirectCountNV;
|
||||
|
||||
// ---- VK_NV_scissor_exclusive extension commands
|
||||
PFN_vkCmdSetExclusiveScissorEnableNV CmdSetExclusiveScissorEnableNV;
|
||||
PFN_vkCmdSetExclusiveScissorNV CmdSetExclusiveScissorNV;
|
||||
|
||||
// ---- VK_NV_device_diagnostic_checkpoints extension commands
|
||||
@ -833,13 +867,13 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkGetBufferDeviceAddressEXT GetBufferDeviceAddressEXT;
|
||||
|
||||
// ---- VK_EXT_full_screen_exclusive extension commands
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkAcquireFullScreenExclusiveModeEXT AcquireFullScreenExclusiveModeEXT;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkReleaseFullScreenExclusiveModeEXT ReleaseFullScreenExclusiveModeEXT;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkGetDeviceGroupSurfacePresentModes2EXT GetDeviceGroupSurfacePresentModes2EXT;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
|
||||
@ -863,6 +897,16 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkCmdSetStencilTestEnableEXT CmdSetStencilTestEnableEXT;
|
||||
PFN_vkCmdSetStencilOpEXT CmdSetStencilOpEXT;
|
||||
|
||||
// ---- VK_EXT_host_image_copy extension commands
|
||||
PFN_vkCopyMemoryToImageEXT CopyMemoryToImageEXT;
|
||||
PFN_vkCopyImageToMemoryEXT CopyImageToMemoryEXT;
|
||||
PFN_vkCopyImageToImageEXT CopyImageToImageEXT;
|
||||
PFN_vkTransitionImageLayoutEXT TransitionImageLayoutEXT;
|
||||
PFN_vkGetImageSubresourceLayout2EXT GetImageSubresourceLayout2EXT;
|
||||
|
||||
// ---- VK_EXT_swapchain_maintenance1 extension commands
|
||||
PFN_vkReleaseSwapchainImagesEXT ReleaseSwapchainImagesEXT;
|
||||
|
||||
// ---- VK_NV_device_generated_commands extension commands
|
||||
PFN_vkGetGeneratedCommandsMemoryRequirementsNV GetGeneratedCommandsMemoryRequirementsNV;
|
||||
PFN_vkCmdPreprocessGeneratedCommandsNV CmdPreprocessGeneratedCommandsNV;
|
||||
@ -871,23 +915,44 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkCreateIndirectCommandsLayoutNV CreateIndirectCommandsLayoutNV;
|
||||
PFN_vkDestroyIndirectCommandsLayoutNV DestroyIndirectCommandsLayoutNV;
|
||||
|
||||
// ---- VK_EXT_depth_bias_control extension commands
|
||||
PFN_vkCmdSetDepthBias2EXT CmdSetDepthBias2EXT;
|
||||
|
||||
// ---- VK_EXT_private_data extension commands
|
||||
PFN_vkCreatePrivateDataSlotEXT CreatePrivateDataSlotEXT;
|
||||
PFN_vkDestroyPrivateDataSlotEXT DestroyPrivateDataSlotEXT;
|
||||
PFN_vkSetPrivateDataEXT SetPrivateDataEXT;
|
||||
PFN_vkGetPrivateDataEXT GetPrivateDataEXT;
|
||||
|
||||
// ---- VK_NV_cuda_kernel_launch extension commands
|
||||
PFN_vkCreateCudaModuleNV CreateCudaModuleNV;
|
||||
PFN_vkGetCudaModuleCacheNV GetCudaModuleCacheNV;
|
||||
PFN_vkCreateCudaFunctionNV CreateCudaFunctionNV;
|
||||
PFN_vkDestroyCudaModuleNV DestroyCudaModuleNV;
|
||||
PFN_vkDestroyCudaFunctionNV DestroyCudaFunctionNV;
|
||||
PFN_vkCmdCudaLaunchKernelNV CmdCudaLaunchKernelNV;
|
||||
|
||||
// ---- VK_EXT_metal_objects extension commands
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
PFN_vkExportMetalObjectsEXT ExportMetalObjectsEXT;
|
||||
#endif // VK_USE_PLATFORM_METAL_EXT
|
||||
|
||||
// ---- VK_EXT_descriptor_buffer extension commands
|
||||
PFN_vkGetDescriptorSetLayoutSizeEXT GetDescriptorSetLayoutSizeEXT;
|
||||
PFN_vkGetDescriptorSetLayoutBindingOffsetEXT GetDescriptorSetLayoutBindingOffsetEXT;
|
||||
PFN_vkGetDescriptorEXT GetDescriptorEXT;
|
||||
PFN_vkCmdBindDescriptorBuffersEXT CmdBindDescriptorBuffersEXT;
|
||||
PFN_vkCmdSetDescriptorBufferOffsetsEXT CmdSetDescriptorBufferOffsetsEXT;
|
||||
PFN_vkCmdBindDescriptorBufferEmbeddedSamplersEXT CmdBindDescriptorBufferEmbeddedSamplersEXT;
|
||||
PFN_vkGetBufferOpaqueCaptureDescriptorDataEXT GetBufferOpaqueCaptureDescriptorDataEXT;
|
||||
PFN_vkGetImageOpaqueCaptureDescriptorDataEXT GetImageOpaqueCaptureDescriptorDataEXT;
|
||||
PFN_vkGetImageViewOpaqueCaptureDescriptorDataEXT GetImageViewOpaqueCaptureDescriptorDataEXT;
|
||||
PFN_vkGetSamplerOpaqueCaptureDescriptorDataEXT GetSamplerOpaqueCaptureDescriptorDataEXT;
|
||||
PFN_vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT GetAccelerationStructureOpaqueCaptureDescriptorDataEXT;
|
||||
|
||||
// ---- VK_NV_fragment_shading_rate_enums extension commands
|
||||
PFN_vkCmdSetFragmentShadingRateEnumNV CmdSetFragmentShadingRateEnumNV;
|
||||
|
||||
// ---- VK_EXT_image_compression_control extension commands
|
||||
PFN_vkGetImageSubresourceLayout2EXT GetImageSubresourceLayout2EXT;
|
||||
|
||||
// ---- VK_EXT_device_fault extension commands
|
||||
PFN_vkGetDeviceFaultInfoEXT GetDeviceFaultInfoEXT;
|
||||
|
||||
@ -895,35 +960,35 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkCmdSetVertexInputEXT CmdSetVertexInputEXT;
|
||||
|
||||
// ---- VK_FUCHSIA_external_memory extension commands
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
PFN_vkGetMemoryZirconHandleFUCHSIA GetMemoryZirconHandleFUCHSIA;
|
||||
#endif // VK_USE_PLATFORM_FUCHSIA
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA GetMemoryZirconHandlePropertiesFUCHSIA;
|
||||
#endif // VK_USE_PLATFORM_FUCHSIA
|
||||
|
||||
// ---- VK_FUCHSIA_external_semaphore extension commands
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
PFN_vkImportSemaphoreZirconHandleFUCHSIA ImportSemaphoreZirconHandleFUCHSIA;
|
||||
#endif // VK_USE_PLATFORM_FUCHSIA
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
PFN_vkGetSemaphoreZirconHandleFUCHSIA GetSemaphoreZirconHandleFUCHSIA;
|
||||
#endif // VK_USE_PLATFORM_FUCHSIA
|
||||
|
||||
// ---- VK_FUCHSIA_buffer_collection extension commands
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
PFN_vkCreateBufferCollectionFUCHSIA CreateBufferCollectionFUCHSIA;
|
||||
#endif // VK_USE_PLATFORM_FUCHSIA
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
PFN_vkSetBufferCollectionImageConstraintsFUCHSIA SetBufferCollectionImageConstraintsFUCHSIA;
|
||||
#endif // VK_USE_PLATFORM_FUCHSIA
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA SetBufferCollectionBufferConstraintsFUCHSIA;
|
||||
#endif // VK_USE_PLATFORM_FUCHSIA
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
PFN_vkDestroyBufferCollectionFUCHSIA DestroyBufferCollectionFUCHSIA;
|
||||
#endif // VK_USE_PLATFORM_FUCHSIA
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
PFN_vkGetBufferCollectionPropertiesFUCHSIA GetBufferCollectionPropertiesFUCHSIA;
|
||||
#endif // VK_USE_PLATFORM_FUCHSIA
|
||||
|
||||
@ -970,6 +1035,10 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkGetDeviceMicromapCompatibilityEXT GetDeviceMicromapCompatibilityEXT;
|
||||
PFN_vkGetMicromapBuildSizesEXT GetMicromapBuildSizesEXT;
|
||||
|
||||
// ---- VK_HUAWEI_cluster_culling_shader extension commands
|
||||
PFN_vkCmdDrawClusterHUAWEI CmdDrawClusterHUAWEI;
|
||||
PFN_vkCmdDrawClusterIndirectHUAWEI CmdDrawClusterIndirectHUAWEI;
|
||||
|
||||
// ---- VK_EXT_pageable_device_local_memory extension commands
|
||||
PFN_vkSetDeviceMemoryPriorityEXT SetDeviceMemoryPriorityEXT;
|
||||
|
||||
@ -977,6 +1046,19 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE GetDescriptorSetLayoutHostMappingInfoVALVE;
|
||||
PFN_vkGetDescriptorSetHostMappingVALVE GetDescriptorSetHostMappingVALVE;
|
||||
|
||||
// ---- VK_NV_copy_memory_indirect extension commands
|
||||
PFN_vkCmdCopyMemoryIndirectNV CmdCopyMemoryIndirectNV;
|
||||
PFN_vkCmdCopyMemoryToImageIndirectNV CmdCopyMemoryToImageIndirectNV;
|
||||
|
||||
// ---- VK_NV_memory_decompression extension commands
|
||||
PFN_vkCmdDecompressMemoryNV CmdDecompressMemoryNV;
|
||||
PFN_vkCmdDecompressMemoryIndirectCountNV CmdDecompressMemoryIndirectCountNV;
|
||||
|
||||
// ---- VK_NV_device_generated_commands_compute extension commands
|
||||
PFN_vkGetPipelineIndirectMemoryRequirementsNV GetPipelineIndirectMemoryRequirementsNV;
|
||||
PFN_vkCmdUpdatePipelineIndirectBufferNV CmdUpdatePipelineIndirectBufferNV;
|
||||
PFN_vkGetPipelineIndirectDeviceAddressNV GetPipelineIndirectDeviceAddressNV;
|
||||
|
||||
// ---- VK_EXT_extended_dynamic_state3 extension commands
|
||||
PFN_vkCmdSetTessellationDomainOriginEXT CmdSetTessellationDomainOriginEXT;
|
||||
PFN_vkCmdSetDepthClampEnableEXT CmdSetDepthClampEnableEXT;
|
||||
@ -1020,28 +1102,30 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkBindOpticalFlowSessionImageNV BindOpticalFlowSessionImageNV;
|
||||
PFN_vkCmdOpticalFlowExecuteNV CmdOpticalFlowExecuteNV;
|
||||
|
||||
// ---- VK_EXT_shader_object extension commands
|
||||
PFN_vkCreateShadersEXT CreateShadersEXT;
|
||||
PFN_vkDestroyShaderEXT DestroyShaderEXT;
|
||||
PFN_vkGetShaderBinaryDataEXT GetShaderBinaryDataEXT;
|
||||
PFN_vkCmdBindShadersEXT CmdBindShadersEXT;
|
||||
|
||||
// ---- VK_QCOM_tile_properties extension commands
|
||||
PFN_vkGetFramebufferTilePropertiesQCOM GetFramebufferTilePropertiesQCOM;
|
||||
PFN_vkGetDynamicRenderingTilePropertiesQCOM GetDynamicRenderingTilePropertiesQCOM;
|
||||
|
||||
// ---- VK_OHOS_native_buffer extension commands
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
PFN_vkGetSwapchainGrallocUsageOHOS GetSwapchainGrallocUsageOHOS;
|
||||
#endif // VK_USE_PLATFORM_OHOS
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
PFN_vkAcquireImageOHOS AcquireImageOHOS;
|
||||
#endif // VK_USE_PLATFORM_OHOS
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
PFN_vkQueueSignalReleaseImageOHOS QueueSignalReleaseImageOHOS;
|
||||
#endif // VK_USE_PLATFORM_OHOS
|
||||
// ---- VK_NV_low_latency2 extension commands
|
||||
PFN_vkSetLatencySleepModeNV SetLatencySleepModeNV;
|
||||
PFN_vkLatencySleepNV LatencySleepNV;
|
||||
PFN_vkSetLatencyMarkerNV SetLatencyMarkerNV;
|
||||
PFN_vkGetLatencyTimingsNV GetLatencyTimingsNV;
|
||||
PFN_vkQueueNotifyOutOfBandNV QueueNotifyOutOfBandNV;
|
||||
|
||||
// ---- VK_OHOS_external_memory extension commands
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
PFN_vkGetNativeBufferPropertiesOHOS GetNativeBufferPropertiesOHOS;
|
||||
#endif // VK_USE_PLATFORM_OHOS
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
PFN_vkGetMemoryNativeBufferOHOS GetMemoryNativeBufferOHOS;
|
||||
#endif // VK_USE_PLATFORM_OHOS
|
||||
// ---- VK_EXT_attachment_feedback_loop_dynamic_state extension commands
|
||||
PFN_vkCmdSetAttachmentFeedbackLoopEnableEXT CmdSetAttachmentFeedbackLoopEnableEXT;
|
||||
|
||||
// ---- VK_QNX_external_memory_screen_buffer extension commands
|
||||
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
|
||||
PFN_vkGetScreenBufferPropertiesQNX GetScreenBufferPropertiesQNX;
|
||||
#endif // VK_USE_PLATFORM_SCREEN_QNX
|
||||
|
||||
// ---- VK_KHR_acceleration_structure extension commands
|
||||
PFN_vkCreateAccelerationStructureKHR CreateAccelerationStructureKHR;
|
||||
@ -1073,6 +1157,25 @@ typedef struct VkLayerDispatchTable_ {
|
||||
PFN_vkCmdDrawMeshTasksEXT CmdDrawMeshTasksEXT;
|
||||
PFN_vkCmdDrawMeshTasksIndirectEXT CmdDrawMeshTasksIndirectEXT;
|
||||
PFN_vkCmdDrawMeshTasksIndirectCountEXT CmdDrawMeshTasksIndirectCountEXT;
|
||||
|
||||
// ---- VK_OHOS_native_buffer extension commands
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
PFN_vkGetSwapchainGrallocUsageOHOS GetSwapchainGrallocUsageOHOS;
|
||||
#endif // VK_USE_PLATFORM_OHOS
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
PFN_vkAcquireImageOHOS AcquireImageOHOS;
|
||||
#endif // VK_USE_PLATFORM_OHOS
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
PFN_vkQueueSignalReleaseImageOHOS QueueSignalReleaseImageOHOS;
|
||||
#endif // VK_USE_PLATFORM_OHOS
|
||||
|
||||
// ---- VK_OHOS_external_memory extension commands
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
PFN_vkGetNativeBufferPropertiesOHOS GetNativeBufferPropertiesOHOS;
|
||||
#endif // VK_USE_PLATFORM_OHOS
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
PFN_vkGetMemoryNativeBufferOHOS GetMemoryNativeBufferOHOS;
|
||||
#endif // VK_USE_PLATFORM_OHOS
|
||||
} VkLayerDispatchTable;
|
||||
|
||||
|
||||
// clang-format on
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,8 @@
|
||||
* Copyright (c) 2015-2022 The Khronos Group Inc.
|
||||
* Copyright (c) 2015-2022 Valve Corporation
|
||||
* Copyright (c) 2015-2022 LunarG, Inc.
|
||||
* Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (c) 2023-2023 RasterGrid Kft.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -22,6 +24,7 @@
|
||||
* Author: Mark Young <marky@lunarg.com>
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
#pragma once
|
||||
|
||||
// Structures defined externally, but used here
|
||||
@ -45,7 +48,7 @@ void extensions_create_instance(struct loader_instance *ptr_instance, const VkIn
|
||||
// Extension interception for vkGetDeviceProcAddr function, so we can return
|
||||
// an appropriate terminator if this is one of those few device commands requiring
|
||||
// a terminator.
|
||||
PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *pName);
|
||||
PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *name, bool* found_name);
|
||||
|
||||
// Dispatch table properly filled in with appropriate terminators for the
|
||||
// supported extensions.
|
||||
@ -54,8 +57,7 @@ extern const VkLayerInstanceDispatchTable instance_disp;
|
||||
// Array of extension strings for instance extensions we support.
|
||||
extern const char *const LOADER_INSTANCE_EXTENSIONS[];
|
||||
|
||||
VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_icd_term *icd_term, VkInstance inst,
|
||||
const PFN_vkGetInstanceProcAddr fp_gipa);
|
||||
VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_instance* inst, struct loader_icd_term *icd_term);
|
||||
|
||||
// Init Device function pointer dispatch table with core commands
|
||||
VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_dispatch_table *dev_table, PFN_vkGetDeviceProcAddr gpa,
|
||||
@ -77,7 +79,7 @@ VKAPI_ATTR void VKAPI_CALL loader_init_instance_extension_dispatch_table(VkLayer
|
||||
VkInstance inst);
|
||||
|
||||
// Device command lookup function
|
||||
VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDispatchTable *table, const char *name);
|
||||
VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDispatchTable *table, const char *name, bool* name_found);
|
||||
|
||||
// Instance command lookup function
|
||||
VKAPI_ATTR void* VKAPI_CALL loader_lookup_instance_dispatch_table(const VkLayerInstanceDispatchTable *table, const char *name,
|
||||
@ -208,7 +210,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceToolProperties(
|
||||
// ICD function pointer dispatch table
|
||||
struct loader_icd_term_dispatch {
|
||||
|
||||
// ---- Core 1_0 commands
|
||||
// ---- Core Vulkan 1.0 commands
|
||||
PFN_vkCreateInstance CreateInstance;
|
||||
PFN_vkDestroyInstance DestroyInstance;
|
||||
PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
|
||||
@ -225,7 +227,7 @@ struct loader_icd_term_dispatch {
|
||||
PFN_vkEnumerateInstanceLayerProperties EnumerateInstanceLayerProperties;
|
||||
PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties;
|
||||
|
||||
// ---- Core 1_1 commands
|
||||
// ---- Core Vulkan 1.1 commands
|
||||
PFN_vkEnumerateInstanceVersion EnumerateInstanceVersion;
|
||||
PFN_vkEnumeratePhysicalDeviceGroups EnumeratePhysicalDeviceGroups;
|
||||
PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2;
|
||||
@ -239,7 +241,7 @@ struct loader_icd_term_dispatch {
|
||||
PFN_vkGetPhysicalDeviceExternalFenceProperties GetPhysicalDeviceExternalFenceProperties;
|
||||
PFN_vkGetPhysicalDeviceExternalSemaphoreProperties GetPhysicalDeviceExternalSemaphoreProperties;
|
||||
|
||||
// ---- Core 1_3 commands
|
||||
// ---- Core Vulkan 1.3 commands
|
||||
PFN_vkGetPhysicalDeviceToolProperties GetPhysicalDeviceToolProperties;
|
||||
|
||||
// ---- VK_KHR_surface extension commands
|
||||
@ -250,8 +252,6 @@ struct loader_icd_term_dispatch {
|
||||
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR;
|
||||
|
||||
// ---- VK_KHR_swapchain extension commands
|
||||
PFN_vkCreateSwapchainKHR CreateSwapchainKHR;
|
||||
PFN_vkGetDeviceGroupSurfacePresentModesKHR GetDeviceGroupSurfacePresentModesKHR;
|
||||
PFN_vkGetPhysicalDevicePresentRectanglesKHR GetPhysicalDevicePresentRectanglesKHR;
|
||||
|
||||
// ---- VK_KHR_display extension commands
|
||||
@ -263,53 +263,46 @@ struct loader_icd_term_dispatch {
|
||||
PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR;
|
||||
PFN_vkCreateDisplayPlaneSurfaceKHR CreateDisplayPlaneSurfaceKHR;
|
||||
|
||||
// ---- VK_KHR_display_swapchain extension commands
|
||||
PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR;
|
||||
|
||||
// ---- VK_KHR_xlib_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR;
|
||||
#endif // VK_USE_PLATFORM_XLIB_KHR
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR GetPhysicalDeviceXlibPresentationSupportKHR;
|
||||
#endif // VK_USE_PLATFORM_XLIB_KHR
|
||||
|
||||
// ---- VK_KHR_xcb_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
PFN_vkCreateXcbSurfaceKHR CreateXcbSurfaceKHR;
|
||||
#endif // VK_USE_PLATFORM_XCB_KHR
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR GetPhysicalDeviceXcbPresentationSupportKHR;
|
||||
#endif // VK_USE_PLATFORM_XCB_KHR
|
||||
|
||||
// ---- VK_KHR_wayland_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
PFN_vkCreateWaylandSurfaceKHR CreateWaylandSurfaceKHR;
|
||||
#endif // VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR GetPhysicalDeviceWaylandPresentationSupportKHR;
|
||||
#endif // VK_USE_PLATFORM_WAYLAND_KHR
|
||||
|
||||
// ---- VK_KHR_android_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
PFN_vkCreateAndroidSurfaceKHR CreateAndroidSurfaceKHR;
|
||||
#endif // VK_USE_PLATFORM_ANDROID_KHR
|
||||
|
||||
// ---- VK_KHR_win32_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkCreateWin32SurfaceKHR CreateWin32SurfaceKHR;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR GetPhysicalDeviceWin32PresentationSupportKHR;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
|
||||
// ---- VK_KHR_video_queue extension commands
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR GetPhysicalDeviceVideoCapabilitiesKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR GetPhysicalDeviceVideoFormatPropertiesKHR;
|
||||
#endif // VK_ENABLE_BETA_EXTENSIONS
|
||||
|
||||
// ---- VK_KHR_get_physical_device_properties2 extension commands
|
||||
PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysicalDeviceFeatures2KHR;
|
||||
@ -349,17 +342,22 @@ struct loader_icd_term_dispatch {
|
||||
// ---- VK_KHR_fragment_shading_rate extension commands
|
||||
PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR GetPhysicalDeviceFragmentShadingRatesKHR;
|
||||
|
||||
// ---- VK_KHR_video_encode_queue extension commands
|
||||
PFN_vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR;
|
||||
|
||||
// ---- VK_KHR_cooperative_matrix extension commands
|
||||
PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR GetPhysicalDeviceCooperativeMatrixPropertiesKHR;
|
||||
|
||||
// ---- VK_KHR_calibrated_timestamps extension commands
|
||||
PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsKHR GetPhysicalDeviceCalibrateableTimeDomainsKHR;
|
||||
|
||||
// ---- VK_EXT_debug_report extension commands
|
||||
PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
|
||||
PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT;
|
||||
PFN_vkDebugReportMessageEXT DebugReportMessageEXT;
|
||||
|
||||
// ---- VK_EXT_debug_marker extension commands
|
||||
PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT;
|
||||
PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT;
|
||||
|
||||
// ---- VK_GGP_stream_descriptor_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_GGP
|
||||
#if defined(VK_USE_PLATFORM_GGP)
|
||||
PFN_vkCreateStreamDescriptorSurfaceGGP CreateStreamDescriptorSurfaceGGP;
|
||||
#endif // VK_USE_PLATFORM_GGP
|
||||
|
||||
@ -367,7 +365,7 @@ struct loader_icd_term_dispatch {
|
||||
PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV GetPhysicalDeviceExternalImageFormatPropertiesNV;
|
||||
|
||||
// ---- VK_NN_vi_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_VI_NN
|
||||
#if defined(VK_USE_PLATFORM_VI_NN)
|
||||
PFN_vkCreateViSurfaceNN CreateViSurfaceNN;
|
||||
#endif // VK_USE_PLATFORM_VI_NN
|
||||
|
||||
@ -375,10 +373,10 @@ struct loader_icd_term_dispatch {
|
||||
PFN_vkReleaseDisplayEXT ReleaseDisplayEXT;
|
||||
|
||||
// ---- VK_EXT_acquire_xlib_display extension commands
|
||||
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
|
||||
PFN_vkAcquireXlibDisplayEXT AcquireXlibDisplayEXT;
|
||||
#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
|
||||
PFN_vkGetRandROutputDisplayEXT GetRandROutputDisplayEXT;
|
||||
#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
|
||||
@ -386,24 +384,16 @@ struct loader_icd_term_dispatch {
|
||||
PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT GetPhysicalDeviceSurfaceCapabilities2EXT;
|
||||
|
||||
// ---- VK_MVK_ios_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_IOS_MVK
|
||||
#if defined(VK_USE_PLATFORM_IOS_MVK)
|
||||
PFN_vkCreateIOSSurfaceMVK CreateIOSSurfaceMVK;
|
||||
#endif // VK_USE_PLATFORM_IOS_MVK
|
||||
|
||||
// ---- VK_MVK_macos_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_MACOS_MVK
|
||||
#if defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
PFN_vkCreateMacOSSurfaceMVK CreateMacOSSurfaceMVK;
|
||||
#endif // VK_USE_PLATFORM_MACOS_MVK
|
||||
|
||||
// ---- VK_EXT_debug_utils extension commands
|
||||
PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT;
|
||||
PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT;
|
||||
PFN_vkQueueBeginDebugUtilsLabelEXT QueueBeginDebugUtilsLabelEXT;
|
||||
PFN_vkQueueEndDebugUtilsLabelEXT QueueEndDebugUtilsLabelEXT;
|
||||
PFN_vkQueueInsertDebugUtilsLabelEXT QueueInsertDebugUtilsLabelEXT;
|
||||
PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT;
|
||||
PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT;
|
||||
PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT;
|
||||
PFN_vkCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT;
|
||||
PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT;
|
||||
PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT;
|
||||
@ -415,12 +405,12 @@ struct loader_icd_term_dispatch {
|
||||
PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT GetPhysicalDeviceCalibrateableTimeDomainsEXT;
|
||||
|
||||
// ---- VK_FUCHSIA_imagepipe_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
PFN_vkCreateImagePipeSurfaceFUCHSIA CreateImagePipeSurfaceFUCHSIA;
|
||||
#endif // VK_USE_PLATFORM_FUCHSIA
|
||||
|
||||
// ---- VK_EXT_metal_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
PFN_vkCreateMetalSurfaceEXT CreateMetalSurfaceEXT;
|
||||
#endif // VK_USE_PLATFORM_METAL_EXT
|
||||
|
||||
@ -434,12 +424,9 @@ struct loader_icd_term_dispatch {
|
||||
PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV;
|
||||
|
||||
// ---- VK_EXT_full_screen_exclusive extension commands
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT GetPhysicalDeviceSurfacePresentModes2EXT;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
PFN_vkGetDeviceGroupSurfacePresentModes2EXT GetDeviceGroupSurfacePresentModes2EXT;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
|
||||
// ---- VK_EXT_headless_surface extension commands
|
||||
PFN_vkCreateHeadlessSurfaceEXT CreateHeadlessSurfaceEXT;
|
||||
@ -449,26 +436,26 @@ struct loader_icd_term_dispatch {
|
||||
PFN_vkGetDrmDisplayEXT GetDrmDisplayEXT;
|
||||
|
||||
// ---- VK_NV_acquire_winrt_display extension commands
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkAcquireWinrtDisplayNV AcquireWinrtDisplayNV;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
PFN_vkGetWinrtDisplayNV GetWinrtDisplayNV;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
|
||||
// ---- VK_EXT_directfb_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
|
||||
PFN_vkCreateDirectFBSurfaceEXT CreateDirectFBSurfaceEXT;
|
||||
#endif // VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
|
||||
PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT GetPhysicalDeviceDirectFBPresentationSupportEXT;
|
||||
#endif // VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
|
||||
// ---- VK_QNX_screen_surface extension commands
|
||||
#ifdef VK_USE_PLATFORM_SCREEN_QNX
|
||||
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
|
||||
PFN_vkCreateScreenSurfaceQNX CreateScreenSurfaceQNX;
|
||||
#endif // VK_USE_PLATFORM_SCREEN_QNX
|
||||
#ifdef VK_USE_PLATFORM_SCREEN_QNX
|
||||
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
|
||||
PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX GetPhysicalDeviceScreenPresentationSupportQNX;
|
||||
#endif // VK_USE_PLATFORM_SCREEN_QNX
|
||||
|
||||
@ -496,4 +483,30 @@ struct loader_instance_extension_enables {
|
||||
uint8_t ext_acquire_drm_display;
|
||||
};
|
||||
|
||||
// Functions that required a terminator need to have a separate dispatch table which contains their corresponding
|
||||
// device function. This is used in the terminators themselves.
|
||||
struct loader_device_terminator_dispatch {
|
||||
// ---- VK_KHR_swapchain extension commands
|
||||
PFN_vkCreateSwapchainKHR CreateSwapchainKHR;
|
||||
PFN_vkGetDeviceGroupSurfacePresentModesKHR GetDeviceGroupSurfacePresentModesKHR;
|
||||
// ---- VK_KHR_display_swapchain extension commands
|
||||
PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR;
|
||||
// ---- VK_EXT_debug_marker extension commands
|
||||
PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT;
|
||||
PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT;
|
||||
// ---- VK_EXT_debug_utils extension commands
|
||||
PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT;
|
||||
PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT;
|
||||
PFN_vkQueueBeginDebugUtilsLabelEXT QueueBeginDebugUtilsLabelEXT;
|
||||
PFN_vkQueueEndDebugUtilsLabelEXT QueueEndDebugUtilsLabelEXT;
|
||||
PFN_vkQueueInsertDebugUtilsLabelEXT QueueInsertDebugUtilsLabelEXT;
|
||||
PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT;
|
||||
PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT;
|
||||
PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT;
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
// ---- VK_EXT_full_screen_exclusive extension commands
|
||||
PFN_vkGetDeviceGroupSurfacePresentModes2EXT GetDeviceGroupSurfacePresentModes2EXT;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
};
|
||||
|
||||
// clang-format on
|
||||
|
@ -1,3 +1,4 @@
|
||||
// clang-format off
|
||||
// *** THIS FILE IS GENERATED - DO NOT EDIT ***
|
||||
// See helper_file_generator.py for modifications
|
||||
|
||||
@ -80,11 +81,14 @@ typedef enum VulkanObjectType {
|
||||
kVulkanObjectTypeAccelerationStructureNV = 41,
|
||||
kVulkanObjectTypePerformanceConfigurationINTEL = 42,
|
||||
kVulkanObjectTypeIndirectCommandsLayoutNV = 43,
|
||||
kVulkanObjectTypeBufferCollectionFUCHSIA = 44,
|
||||
kVulkanObjectTypeMicromapEXT = 45,
|
||||
kVulkanObjectTypeOpticalFlowSessionNV = 46,
|
||||
kVulkanObjectTypeAccelerationStructureKHR = 47,
|
||||
kVulkanObjectTypeMax = 48,
|
||||
kVulkanObjectTypeCudaModuleNV = 44,
|
||||
kVulkanObjectTypeCudaFunctionNV = 45,
|
||||
kVulkanObjectTypeAccelerationStructureKHR = 46,
|
||||
kVulkanObjectTypeBufferCollectionFUCHSIA = 47,
|
||||
kVulkanObjectTypeMicromapEXT = 48,
|
||||
kVulkanObjectTypeOpticalFlowSessionNV = 49,
|
||||
kVulkanObjectTypeShaderEXT = 50,
|
||||
kVulkanObjectTypeMax = 51,
|
||||
// Aliases for backwards compatibilty of "promoted" types
|
||||
kVulkanObjectTypeDescriptorUpdateTemplateKHR = kVulkanObjectTypeDescriptorUpdateTemplate,
|
||||
kVulkanObjectTypeSamplerYcbcrConversionKHR = kVulkanObjectTypeSamplerYcbcrConversion,
|
||||
@ -137,10 +141,13 @@ static const char * const object_string[kVulkanObjectTypeMax] = {
|
||||
"AccelerationStructureNV",
|
||||
"PerformanceConfigurationINTEL",
|
||||
"IndirectCommandsLayoutNV",
|
||||
"CudaModuleNV",
|
||||
"CudaFunctionNV",
|
||||
"AccelerationStructureKHR",
|
||||
"BufferCollectionFUCHSIA",
|
||||
"MicromapEXT",
|
||||
"OpticalFlowSessionNV",
|
||||
"AccelerationStructureKHR",
|
||||
"ShaderEXT",
|
||||
};
|
||||
|
||||
// Helper array to get Vulkan VK_EXT_debug_report object type enum from the internal layers version
|
||||
@ -189,10 +196,13 @@ const VkDebugReportObjectTypeEXT get_debug_report_enum[] = {
|
||||
VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT, // kVulkanObjectTypeAccelerationStructureNV
|
||||
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypePerformanceConfigurationINTEL
|
||||
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeIndirectCommandsLayoutNV
|
||||
VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_MODULE_NV_EXT, // kVulkanObjectTypeCudaModuleNV
|
||||
VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_FUNCTION_NV_EXT, // kVulkanObjectTypeCudaFunctionNV
|
||||
VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT, // kVulkanObjectTypeAccelerationStructureKHR
|
||||
VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT, // kVulkanObjectTypeBufferCollectionFUCHSIA
|
||||
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeMicromapEXT
|
||||
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeOpticalFlowSessionNV
|
||||
VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT, // kVulkanObjectTypeAccelerationStructureKHR
|
||||
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeShaderEXT
|
||||
};
|
||||
|
||||
// Helper array to get Official Vulkan VkObjectType enum from the internal layers version
|
||||
@ -241,10 +251,13 @@ const VkObjectType get_object_type_enum[] = {
|
||||
VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV, // kVulkanObjectTypeAccelerationStructureNV
|
||||
VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL, // kVulkanObjectTypePerformanceConfigurationINTEL
|
||||
VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV, // kVulkanObjectTypeIndirectCommandsLayoutNV
|
||||
VK_OBJECT_TYPE_CUDA_MODULE_NV, // kVulkanObjectTypeCudaModuleNV
|
||||
VK_OBJECT_TYPE_CUDA_FUNCTION_NV, // kVulkanObjectTypeCudaFunctionNV
|
||||
VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR, // kVulkanObjectTypeAccelerationStructureKHR
|
||||
VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA, // kVulkanObjectTypeBufferCollectionFUCHSIA
|
||||
VK_OBJECT_TYPE_MICROMAP_EXT, // kVulkanObjectTypeMicromapEXT
|
||||
VK_OBJECT_TYPE_OPTICAL_FLOW_SESSION_NV, // kVulkanObjectTypeOpticalFlowSessionNV
|
||||
VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR, // kVulkanObjectTypeAccelerationStructureKHR
|
||||
VK_OBJECT_TYPE_SHADER_EXT, // kVulkanObjectTypeShaderEXT
|
||||
};
|
||||
|
||||
// Helper function to convert from VkDebugReportObjectTypeEXT to VkObjectType
|
||||
@ -331,6 +344,10 @@ static inline VkObjectType convertDebugReportObjectToCoreObject(VkDebugReportObj
|
||||
return VK_OBJECT_TYPE_VALIDATION_CACHE_EXT;
|
||||
} else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT) {
|
||||
return VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV;
|
||||
} else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_MODULE_NV_EXT) {
|
||||
return VK_OBJECT_TYPE_CUDA_MODULE_NV;
|
||||
} else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_FUNCTION_NV_EXT) {
|
||||
return VK_OBJECT_TYPE_CUDA_FUNCTION_NV;
|
||||
} else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT) {
|
||||
return VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA;
|
||||
}
|
||||
@ -421,8 +438,13 @@ static inline VkDebugReportObjectTypeEXT convertCoreObjectToDebugReportObject(Vk
|
||||
return VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT;
|
||||
} else if (core_report_obj == VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV) {
|
||||
return VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT;
|
||||
} else if (core_report_obj == VK_OBJECT_TYPE_CUDA_MODULE_NV) {
|
||||
return VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_MODULE_NV_EXT;
|
||||
} else if (core_report_obj == VK_OBJECT_TYPE_CUDA_FUNCTION_NV) {
|
||||
return VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_FUNCTION_NV_EXT;
|
||||
} else if (core_report_obj == VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA) {
|
||||
return VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT;
|
||||
}
|
||||
return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
|
||||
}
|
||||
// clang-format on
|
||||
|
@ -1,185 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2014-2021 The Khronos Group Inc.
|
||||
* Copyright (c) 2014-2021 Valve Corporation
|
||||
* Copyright (c) 2014-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: Courtney Goeltzenleuchter <courtney@LunarG.com>
|
||||
* Author: Chia-I Wu <olvaffe@gmail.com>
|
||||
* Author: Chia-I Wu <olv@lunarg.com>
|
||||
* Author: Mark Lobodzinski <mark@LunarG.com>
|
||||
* Author: Lenny Komow <lenny@lunarg.com>
|
||||
* Author: Charles Giessen <charles@lunarg.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "get_environment.h"
|
||||
|
||||
#include "allocation.h"
|
||||
#include "log.h"
|
||||
#include "param/sys_param.h"
|
||||
|
||||
// Environment variables
|
||||
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNXNTO__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
|
||||
bool is_high_integrity() { return geteuid() != getuid() || getegid() != getgid(); }
|
||||
|
||||
char *loader_getenv(const char *name, const struct loader_instance *inst) {
|
||||
#ifdef __OHOS__
|
||||
CachedHandle g_Handle = CachedParameterCreate(name, "");
|
||||
int changed = 0;
|
||||
const char *res = CachedParameterGetChanged(g_Handle, &changed);
|
||||
loader_log(inst, VULKAN_LOADER_DEBUG_BIT | VULKAN_LOADER_INFO_BIT, 0, "loader_getenv name:%s, res:%s", name, res);
|
||||
if (res == NULL || res[0] == '\0') {
|
||||
return NULL;
|
||||
}
|
||||
return (char *)res;
|
||||
#else
|
||||
// No allocation of memory necessary for Linux, but we should at least touch
|
||||
// the inst pointer to get rid of compiler warnings.
|
||||
(void)inst;
|
||||
return getenv(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *loader_secure_getenv(const char *name, const struct loader_instance *inst) {
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
// Apple does not appear to have a secure getenv implementation.
|
||||
// The main difference between secure getenv and getenv is that secure getenv
|
||||
// returns NULL if the process is being run with elevated privileges by a normal user.
|
||||
// The idea is to prevent the reading of malicious environment variables by a process
|
||||
// that can do damage.
|
||||
// This algorithm is derived from glibc code that sets an internal
|
||||
// variable (__libc_enable_secure) if the process is running under setuid or setgid.
|
||||
return is_high_integrity() ? NULL : loader_getenv(name, inst);
|
||||
#elif defined(__Fuchsia__)
|
||||
return loader_getenv(name, inst);
|
||||
#else
|
||||
// Linux
|
||||
char *out;
|
||||
#if defined(HAVE_SECURE_GETENV) && !defined(USE_UNSAFE_FILE_SEARCH)
|
||||
(void)inst;
|
||||
out = secure_getenv(name);
|
||||
#elif defined(HAVE___SECURE_GETENV) && !defined(USE_UNSAFE_FILE_SEARCH)
|
||||
(void)inst;
|
||||
out = __secure_getenv(name);
|
||||
#else
|
||||
out = loader_getenv(name, inst);
|
||||
#if !defined(USE_UNSAFE_FILE_SEARCH)
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "Loader is using non-secure environment variable lookup for %s", name);
|
||||
#endif
|
||||
#endif
|
||||
return out;
|
||||
#endif
|
||||
}
|
||||
|
||||
void loader_free_getenv(char *val, const struct loader_instance *inst) {
|
||||
// No freeing of memory necessary for Linux, but we should at least touch
|
||||
// the val and inst pointers to get rid of compiler warnings.
|
||||
(void)val;
|
||||
(void)inst;
|
||||
}
|
||||
|
||||
#elif defined(WIN32)
|
||||
|
||||
bool is_high_integrity() {
|
||||
HANDLE process_token;
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, &process_token)) {
|
||||
// Maximum possible size of SID_AND_ATTRIBUTES is maximum size of a SID + size of attributes DWORD.
|
||||
uint8_t mandatory_label_buffer[SECURITY_MAX_SID_SIZE + sizeof(DWORD)];
|
||||
DWORD buffer_size;
|
||||
if (GetTokenInformation(process_token, TokenIntegrityLevel, mandatory_label_buffer, sizeof(mandatory_label_buffer),
|
||||
&buffer_size) != 0) {
|
||||
const TOKEN_MANDATORY_LABEL *mandatory_label = (const TOKEN_MANDATORY_LABEL *)mandatory_label_buffer;
|
||||
const DWORD sub_authority_count = *GetSidSubAuthorityCount(mandatory_label->Label.Sid);
|
||||
const DWORD integrity_level = *GetSidSubAuthority(mandatory_label->Label.Sid, sub_authority_count - 1);
|
||||
|
||||
CloseHandle(process_token);
|
||||
return integrity_level > SECURITY_MANDATORY_MEDIUM_RID;
|
||||
}
|
||||
|
||||
CloseHandle(process_token);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
char *loader_getenv(const char *name, const struct loader_instance *inst) {
|
||||
int name_utf16_size = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
|
||||
if (name_utf16_size <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
wchar_t *name_utf16 = (wchar_t *)loader_stack_alloc(name_utf16_size * sizeof(wchar_t));
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, name, -1, name_utf16, name_utf16_size) != name_utf16_size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD val_size = GetEnvironmentVariableW(name_utf16, NULL, 0);
|
||||
// val_size DOES include the null terminator, so for any set variable
|
||||
// will always be at least 1. If it's 0, the variable wasn't set.
|
||||
if (val_size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wchar_t *val = (wchar_t *)loader_stack_alloc(val_size * sizeof(wchar_t));
|
||||
if (GetEnvironmentVariableW(name_utf16, val, val_size) != val_size - 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int val_utf8_size = WideCharToMultiByte(CP_UTF8, 0, val, -1, NULL, 0, NULL, NULL);
|
||||
if (val_utf8_size <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
char *val_utf8 = (char *)loader_instance_heap_alloc(inst, val_utf8_size * sizeof(char), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (val_utf8 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, val, -1, val_utf8, val_utf8_size, NULL, NULL) != val_utf8_size) {
|
||||
loader_instance_heap_free(inst, val_utf8);
|
||||
return NULL;
|
||||
}
|
||||
return val_utf8;
|
||||
}
|
||||
|
||||
char *loader_secure_getenv(const char *name, const struct loader_instance *inst) {
|
||||
#if !defined(USE_UNSAFE_FILE_SEARCH)
|
||||
if (is_high_integrity()) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
|
||||
"Loader is running with elevated permissions. Environment variable %s will be ignored", name);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return loader_getenv(name, inst);
|
||||
}
|
||||
|
||||
void loader_free_getenv(char *val, const struct loader_instance *inst) { loader_instance_heap_free(inst, (void *)val); }
|
||||
|
||||
#else
|
||||
|
||||
char *loader_getenv(const char *name, const struct loader_instance *inst) {
|
||||
// stub func
|
||||
(void)inst;
|
||||
(void)name;
|
||||
return NULL;
|
||||
}
|
||||
void loader_free_getenv(char *val, const struct loader_instance *inst) {
|
||||
// stub func
|
||||
(void)val;
|
||||
(void)inst;
|
||||
}
|
||||
|
||||
#endif
|
@ -278,17 +278,3 @@ void *globalGetProcAddr(const char *name) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *loader_non_passthrough_gdpa(const char *name) {
|
||||
if (!name || name[0] != 'v' || name[1] != 'k') return NULL;
|
||||
|
||||
name += 2;
|
||||
|
||||
if (!strcmp(name, "GetDeviceProcAddr")) return vkGetDeviceProcAddr;
|
||||
if (!strcmp(name, "DestroyDevice")) return vkDestroyDevice;
|
||||
if (!strcmp(name, "GetDeviceQueue")) return vkGetDeviceQueue;
|
||||
if (!strcmp(name, "GetDeviceQueue2")) return vkGetDeviceQueue2;
|
||||
if (!strcmp(name, "AllocateCommandBuffers")) return vkAllocateCommandBuffers;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -27,5 +27,3 @@
|
||||
void *trampoline_get_proc_addr(struct loader_instance *inst, const char *funcName);
|
||||
|
||||
void *globalGetProcAddr(const char *name);
|
||||
|
||||
void *loader_non_passthrough_gdpa(const char *name);
|
Binary file not shown.
4115
loader/loader.c
4115
loader/loader.c
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,8 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2014-2022 The Khronos Group Inc.
|
||||
* Copyright (c) 2014-2022 Valve Corporation
|
||||
* Copyright (c) 2014-2022 LunarG, Inc.
|
||||
* Copyright (c) 2014-2023 The Khronos Group Inc.
|
||||
* Copyright (c) 2014-2023 Valve Corporation
|
||||
* Copyright (c) 2014-2023 LunarG, Inc.
|
||||
* Copyright (C) 2015 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -30,6 +30,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "loader_common.h"
|
||||
#include "cJSON.h"
|
||||
|
||||
// Declare the once_init variable
|
||||
LOADER_PLATFORM_THREAD_ONCE_EXTERN_DEFINITION(once_init)
|
||||
@ -68,7 +69,7 @@ static inline struct loader_instance_dispatch_table *loader_get_instance_dispatc
|
||||
}
|
||||
|
||||
static inline void loader_init_dispatch(void *obj, const void *data) {
|
||||
#ifdef DEBUG
|
||||
#if defined(DEBUG)
|
||||
assert(valid_loader_magic_value(obj) &&
|
||||
"Incompatible ICD, first dword must be initialized to "
|
||||
"ICD_LOADER_MAGIC. See loader/README.md for details.");
|
||||
@ -80,7 +81,6 @@ static inline void loader_init_dispatch(void *obj, const void *data) {
|
||||
// Global variables used across files
|
||||
extern struct loader_struct loader;
|
||||
extern loader_platform_thread_mutex loader_lock;
|
||||
extern loader_platform_thread_mutex loader_json_lock;
|
||||
extern loader_platform_thread_mutex loader_preload_icd_lock;
|
||||
extern loader_platform_thread_mutex loader_global_instance_list_lock;
|
||||
|
||||
@ -91,58 +91,89 @@ VkResult loader_validate_layers(const struct loader_instance *inst, const uint32
|
||||
|
||||
VkResult loader_validate_instance_extensions(struct loader_instance *inst, const struct loader_extension_list *icd_exts,
|
||||
const struct loader_layer_list *instance_layer,
|
||||
const struct loader_envvar_all_filters *layer_filters,
|
||||
const VkInstanceCreateInfo *pCreateInfo);
|
||||
|
||||
void loader_initialize(void);
|
||||
void loader_release(void);
|
||||
void loader_preload_icds(void);
|
||||
void loader_unload_preloaded_icds(void);
|
||||
VkResult loader_init_library_list(struct loader_layer_list *instance_layers, loader_platform_dl_handle **libs);
|
||||
|
||||
// Allocate a new string able to hold source_str and place it in dest_str
|
||||
VkResult loader_copy_to_new_str(const struct loader_instance *inst, const char *source_str, char **dest_str);
|
||||
|
||||
// Allocate a loader_string_list with enough space for allocated_count strings inside of it
|
||||
VkResult create_string_list(const struct loader_instance *inst, uint32_t allocated_count, struct loader_string_list *string_list);
|
||||
// Resize if there isn't enough space, then add the string str to the end of the loader_string_list
|
||||
// This function takes ownership of the str passed in - but only when it succeeds
|
||||
VkResult append_str_to_string_list(const struct loader_instance *inst, struct loader_string_list *string_list, char *str);
|
||||
// Resize if there isn't enough space, then copy the string str to a new string the end of the loader_string_list
|
||||
// This function does not take ownership of the string, it merely copies it.
|
||||
// This function appends a null terminator to the string automatically
|
||||
// The str_len parameter does not include the null terminator
|
||||
VkResult copy_str_to_string_list(const struct loader_instance *inst, struct loader_string_list *string_list, const char *str,
|
||||
size_t str_len);
|
||||
|
||||
// Free any string inside of loader_string_list and then free the list itself
|
||||
void free_string_list(const struct loader_instance *inst, struct loader_string_list *string_list);
|
||||
|
||||
VkResult loader_init_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info, size_t element_size);
|
||||
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);
|
||||
|
||||
// This function takes ownership of layer_property in the case that allocation fails
|
||||
VkResult loader_append_layer_property(const struct loader_instance *inst, struct loader_layer_list *layer_list,
|
||||
struct loader_layer_properties *layer_property);
|
||||
VkResult loader_add_layer_properties(const struct loader_instance *inst, struct loader_layer_list *layer_instance_list, cJSON *json,
|
||||
bool is_implicit, char *filename);
|
||||
bool loader_find_layer_name_in_list(const char *name, const struct loader_pointer_layer_list *layer_list);
|
||||
VkResult loader_add_layer_properties_to_list(const struct loader_instance *inst, struct loader_pointer_layer_list *list,
|
||||
struct loader_layer_properties *props);
|
||||
void loader_free_layer_properties(const struct loader_instance *inst, struct loader_layer_properties *layer_properties);
|
||||
bool loader_implicit_layer_is_enabled(const struct loader_instance *inst, const struct loader_envvar_all_filters *filters,
|
||||
const struct loader_layer_properties *prop);
|
||||
VkResult loader_add_meta_layer(const struct loader_instance *inst, const struct loader_envvar_all_filters *filters,
|
||||
struct loader_layer_properties *prop, struct loader_pointer_layer_list *target_list,
|
||||
struct loader_pointer_layer_list *expanded_target_list, const struct loader_layer_list *source_list,
|
||||
bool *out_found_all_component_layers);
|
||||
VkResult loader_add_to_ext_list(const struct loader_instance *inst, struct loader_extension_list *ext_list,
|
||||
uint32_t prop_list_count, const VkExtensionProperties *props);
|
||||
VkResult loader_add_to_dev_ext_list(const struct loader_instance *inst, struct loader_device_extension_list *ext_list,
|
||||
const VkExtensionProperties *props, uint32_t entry_count, char **entrys);
|
||||
VkResult loader_add_device_extensions(const struct loader_instance *inst,
|
||||
PFN_vkEnumerateDeviceExtensionProperties fpEnumerateDeviceExtensionProperties,
|
||||
VkPhysicalDevice physical_device, const char *lib_name,
|
||||
struct loader_extension_list *ext_list);
|
||||
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_layer_list(const struct loader_instance *inst, struct loader_device *device,
|
||||
struct loader_layer_list *layer_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);
|
||||
VkResult loader_add_layer_name_to_list(const struct loader_instance *inst, const char *name, const enum layer_type_flags type_flags,
|
||||
const struct loader_layer_list *source_list, struct loader_layer_list *target_list,
|
||||
struct loader_layer_list *expanded_target_list);
|
||||
void loader_icd_destroy(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term,
|
||||
const VkAllocationCallbacks *pAllocator);
|
||||
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_icd_scan(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
|
||||
bool *skipped_portability_drivers);
|
||||
void loader_scan_for_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers);
|
||||
void loader_scan_for_implicit_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers);
|
||||
bool loader_implicit_layer_is_enabled(const struct loader_instance *inst, const struct loader_layer_properties *prop);
|
||||
const VkInstanceCreateInfo *pCreateInfo, bool *skipped_portability_drivers);
|
||||
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,
|
||||
const struct loader_envvar_all_filters *layer_filters);
|
||||
VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers,
|
||||
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_instance *loader_get_instance(const VkInstance instance);
|
||||
void loader_deactivate_layers(const struct loader_instance *instance, struct loader_device *device, struct loader_layer_list *list);
|
||||
struct loader_device *loader_create_logical_device(const struct loader_instance *inst, const VkAllocationCallbacks *pAllocator);
|
||||
void loader_add_logical_device(const struct loader_instance *inst, struct loader_icd_term *icd_term,
|
||||
struct loader_device *found_dev);
|
||||
void loader_remove_logical_device(const struct loader_instance *inst, struct loader_icd_term *icd_term,
|
||||
struct loader_device *found_dev, 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,
|
||||
const VkAllocationCallbacks *pAllocator);
|
||||
// NOTE: Outside of loader, this entry-point is only provided for error
|
||||
// cleanup.
|
||||
void loader_destroy_logical_device(const struct loader_instance *inst, struct loader_device *dev,
|
||||
const VkAllocationCallbacks *pAllocator);
|
||||
void loader_destroy_logical_device(struct loader_device *dev, const VkAllocationCallbacks *pAllocator);
|
||||
|
||||
VkResult loader_enable_instance_layers(struct loader_instance *inst, const VkInstanceCreateInfo *pCreateInfo,
|
||||
const struct loader_layer_list *instance_layers);
|
||||
const struct loader_layer_list *instance_layers,
|
||||
const struct loader_envvar_all_filters *layer_filters);
|
||||
|
||||
VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
|
||||
struct loader_instance *inst, VkInstance *created_instance);
|
||||
@ -162,7 +193,7 @@ VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCre
|
||||
PFN_vkGetDeviceProcAddr *layerNextGDPA);
|
||||
|
||||
VkResult loader_validate_device_extensions(struct loader_instance *this_instance,
|
||||
const struct loader_layer_list *activated_device_layers,
|
||||
const struct loader_pointer_layer_list *activated_device_layers,
|
||||
const struct loader_extension_list *icd_exts, const VkDeviceCreateInfo *pCreateInfo);
|
||||
|
||||
VkResult setup_loader_tramp_phys_devs(struct loader_instance *inst, uint32_t phys_dev_count, VkPhysicalDevice *phys_devs);
|
||||
@ -171,7 +202,7 @@ VkResult setup_loader_tramp_phys_dev_groups(struct loader_instance *inst, uint32
|
||||
|
||||
VkStringErrorFlags vk_string_validate(const int max_length, const char *char_array);
|
||||
char *loader_get_next_path(char *path);
|
||||
VkResult add_data_files(const struct loader_instance *inst, char *search_path, struct loader_data_files *out_files,
|
||||
VkResult add_data_files(const struct loader_instance *inst, char *search_path, struct loader_string_list *out_files,
|
||||
bool use_first_found_manifest);
|
||||
|
||||
loader_api_version loader_make_version(uint32_t version);
|
||||
@ -181,10 +212,10 @@ loader_api_version loader_combine_version(uint32_t major, uint32_t minor, uint32
|
||||
bool loader_check_version_meets_required(loader_api_version required, loader_api_version version);
|
||||
|
||||
// Convenience macros for common versions
|
||||
#ifndef LOADER_VERSION_1_0_0
|
||||
#if !defined(LOADER_VERSION_1_0_0)
|
||||
#define LOADER_VERSION_1_0_0 loader_combine_version(1, 0, 0)
|
||||
#endif
|
||||
|
||||
#ifndef LOADER_VERSION_1_1_0
|
||||
#if !defined(LOADER_VERSION_1_1_0)
|
||||
#define LOADER_VERSION_1_1_0 loader_combine_version(1, 1, 0)
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// Copyright (c) 2014-2022 The Khronos Group Inc.
|
||||
// Copyright (c) 2014-2022 Valve Corporation
|
||||
// Copyright (c) 2014-2022 LunarG, Inc.
|
||||
// Copyright (c) 2014-2024 The Khronos Group Inc.
|
||||
// Copyright (c) 2014-2024 Valve Corporation
|
||||
// Copyright (c) 2014-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.
|
||||
@ -22,9 +22,10 @@
|
||||
#include "winres.h"
|
||||
|
||||
// All set through CMake
|
||||
#define VER_FILE_VERSION 1, 0, 1111, 2222
|
||||
#define VER_FILE_DESCRIPTION_STR "Vulkan Loader - Dev Build"
|
||||
#define VER_FILE_VERSION_STR "1.0.1111.2222.Dev Build"
|
||||
#define VER_FILE_VERSION 1, 3, 275, 0
|
||||
#define VER_FILE_DESCRIPTION_STR "1.3.275.Dev Build"
|
||||
#define VER_FILE_VERSION_STR "Vulkan Loader - Dev Build"
|
||||
#define VER_COPYRIGHT_STR "Copyright (C) 2015-2024"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VER_FILE_VERSION
|
||||
@ -46,7 +47,7 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "FileDescription", VER_FILE_DESCRIPTION_STR
|
||||
VALUE "FileVersion", VER_FILE_VERSION_STR
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015-2022"
|
||||
VALUE "LegalCopyright", VER_COPYRIGHT_STR
|
||||
VALUE "ProductName", "Vulkan Runtime"
|
||||
VALUE "ProductVersion", VER_FILE_VERSION_STR
|
||||
END
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// Copyright (c) 2014-2022 The Khronos Group Inc.
|
||||
// Copyright (c) 2014-2022 Valve Corporation
|
||||
// Copyright (c) 2014-2022 LunarG, Inc.
|
||||
// Copyright (c) 2014-${LOADER_CUR_COPYRIGHT_YEAR} The Khronos Group Inc.
|
||||
// Copyright (c) 2014-${LOADER_CUR_COPYRIGHT_YEAR} Valve Corporation
|
||||
// Copyright (c) 2014-${LOADER_CUR_COPYRIGHT_YEAR} LunarG, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -25,6 +25,7 @@
|
||||
#define VER_FILE_VERSION ${LOADER_VER_FILE_VERSION}
|
||||
#define VER_FILE_DESCRIPTION_STR ${LOADER_VER_FILE_DESCRIPTION_STR}
|
||||
#define VER_FILE_VERSION_STR ${LOADER_VER_FILE_VERSION_STR}
|
||||
#define VER_COPYRIGHT_STR "Copyright (C) 2015-${LOADER_CUR_COPYRIGHT_YEAR}"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VER_FILE_VERSION
|
||||
@ -46,7 +47,7 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "FileDescription", VER_FILE_DESCRIPTION_STR
|
||||
VALUE "FileVersion", VER_FILE_VERSION_STR
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015-2022"
|
||||
VALUE "LegalCopyright", VER_COPYRIGHT_STR
|
||||
VALUE "ProductName", "Vulkan Runtime"
|
||||
VALUE "ProductVersion", VER_FILE_VERSION_STR
|
||||
END
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include "vk_layer_dispatch_table.h"
|
||||
#include "vk_loader_extensions.h"
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
typedef enum VkStringErrorFlagBits {
|
||||
VK_STRING_ERROR_NONE = 0x00000000,
|
||||
VK_STRING_ERROR_LENGTH = 0x00000001,
|
||||
@ -65,6 +67,12 @@ struct loader_generic_list {
|
||||
void *list;
|
||||
};
|
||||
|
||||
struct loader_string_list {
|
||||
uint32_t allocated_count;
|
||||
uint32_t count;
|
||||
char **list;
|
||||
};
|
||||
|
||||
struct loader_extension_list {
|
||||
size_t capacity;
|
||||
uint32_t count;
|
||||
@ -73,8 +81,7 @@ struct loader_extension_list {
|
||||
|
||||
struct loader_dev_ext_props {
|
||||
VkExtensionProperties props;
|
||||
uint32_t entrypoint_count;
|
||||
char **entrypoints;
|
||||
struct loader_string_list entrypoints;
|
||||
};
|
||||
|
||||
struct loader_device_extension_list {
|
||||
@ -84,28 +91,20 @@ struct loader_device_extension_list {
|
||||
};
|
||||
|
||||
struct loader_name_value {
|
||||
char name[MAX_STRING_SIZE];
|
||||
char value[MAX_STRING_SIZE];
|
||||
char *name;
|
||||
char *value;
|
||||
};
|
||||
|
||||
struct loader_layer_functions {
|
||||
char str_gipa[MAX_STRING_SIZE];
|
||||
char str_gdpa[MAX_STRING_SIZE];
|
||||
char str_negotiate_interface[MAX_STRING_SIZE];
|
||||
char *str_gipa;
|
||||
char *str_gdpa;
|
||||
char *str_negotiate_interface;
|
||||
PFN_vkNegotiateLoaderLayerInterfaceVersion negotiate_layer_interface;
|
||||
PFN_vkGetInstanceProcAddr get_instance_proc_addr;
|
||||
PFN_vkGetDeviceProcAddr get_device_proc_addr;
|
||||
PFN_GetPhysicalDeviceProcAddr get_physical_device_proc_addr;
|
||||
};
|
||||
|
||||
struct loader_override_expiration {
|
||||
uint16_t year;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
uint8_t hour;
|
||||
uint8_t minute;
|
||||
};
|
||||
|
||||
// This structure is used to store the json file version in a more manageable way.
|
||||
typedef struct {
|
||||
uint16_t major;
|
||||
@ -121,6 +120,7 @@ enum loader_layer_library_status {
|
||||
|
||||
LOADER_LAYER_LIB_ERROR_WRONG_BIT_TYPE = 20,
|
||||
LOADER_LAYER_LIB_ERROR_FAILED_TO_LOAD = 21,
|
||||
LOADER_LAYER_LIB_ERROR_OUT_OF_MEMORY = 22,
|
||||
};
|
||||
|
||||
enum layer_type_flags {
|
||||
@ -132,9 +132,11 @@ enum layer_type_flags {
|
||||
struct loader_layer_properties {
|
||||
VkLayerProperties info;
|
||||
enum layer_type_flags type_flags;
|
||||
enum loader_settings_layer_control settings_control_value;
|
||||
|
||||
uint32_t interface_version; // PFN_vkNegotiateLoaderLayerInterfaceVersion
|
||||
char manifest_file_name[MAX_STRING_SIZE];
|
||||
char lib_name[MAX_STRING_SIZE];
|
||||
char *manifest_file_name;
|
||||
char *lib_name;
|
||||
enum loader_layer_library_status lib_status;
|
||||
loader_platform_dl_handle lib_handle;
|
||||
struct loader_layer_functions functions;
|
||||
@ -142,36 +144,40 @@ struct loader_layer_properties {
|
||||
struct loader_device_extension_list device_extension_list;
|
||||
struct loader_name_value disable_env_var;
|
||||
struct loader_name_value enable_env_var;
|
||||
uint32_t num_component_layers;
|
||||
char (*component_layer_names)[MAX_STRING_SIZE];
|
||||
struct loader_string_list component_layer_names;
|
||||
struct {
|
||||
char enumerate_instance_extension_properties[MAX_STRING_SIZE];
|
||||
char enumerate_instance_layer_properties[MAX_STRING_SIZE];
|
||||
char enumerate_instance_version[MAX_STRING_SIZE];
|
||||
char *enumerate_instance_extension_properties;
|
||||
char *enumerate_instance_layer_properties;
|
||||
char *enumerate_instance_version;
|
||||
} pre_instance_functions;
|
||||
uint32_t num_override_paths;
|
||||
char (*override_paths)[MAX_STRING_SIZE];
|
||||
struct loader_string_list override_paths;
|
||||
bool is_override;
|
||||
bool has_expiration;
|
||||
struct loader_override_expiration expiration;
|
||||
bool keep;
|
||||
uint32_t num_blacklist_layers;
|
||||
char (*blacklist_layer_names)[MAX_STRING_SIZE];
|
||||
uint32_t num_app_key_paths;
|
||||
char (*app_key_paths)[MAX_STRING_SIZE];
|
||||
struct loader_string_list blacklist_layer_names;
|
||||
struct loader_string_list app_key_paths;
|
||||
};
|
||||
|
||||
// Stores a list of loader_layer_properties
|
||||
struct loader_layer_list {
|
||||
size_t capacity;
|
||||
uint32_t count;
|
||||
struct loader_layer_properties *list;
|
||||
};
|
||||
|
||||
// Stores a list of pointers to loader_layer_properties
|
||||
// Used for app_activated_layer_list and expanded_activated_layer_list
|
||||
struct loader_pointer_layer_list {
|
||||
size_t capacity;
|
||||
uint32_t count;
|
||||
struct loader_layer_properties **list;
|
||||
};
|
||||
|
||||
typedef VkResult(VKAPI_PTR *PFN_vkDevExt)(VkDevice device);
|
||||
|
||||
struct loader_dev_dispatch_table {
|
||||
VkLayerDispatchTable core_dispatch;
|
||||
PFN_vkDevExt ext_dispatch[MAX_NUM_UNKNOWN_EXTS];
|
||||
struct loader_device_terminator_dispatch extension_terminator_dispatch;
|
||||
};
|
||||
|
||||
// per CreateDevice structure
|
||||
@ -181,16 +187,16 @@ struct loader_device {
|
||||
VkDevice icd_device; // device object from the icd
|
||||
struct loader_physical_device_term *phys_dev_term;
|
||||
|
||||
// List of activated layers.
|
||||
// app_ is the version based on exactly what the application asked for.
|
||||
// This is what must be returned to the application on Enumerate calls.
|
||||
// expanded_ is the version based on expanding meta-layers into their
|
||||
// individual component layers. This is what is used internally.
|
||||
struct loader_layer_list app_activated_layer_list;
|
||||
struct loader_layer_list expanded_activated_layer_list;
|
||||
|
||||
VkAllocationCallbacks alloc_callbacks;
|
||||
|
||||
// List of activated device extensions that layers support (but not necessarily the driver which have functions that require
|
||||
// trampolines to work correctly. EX - vkDebugMarkerSetObjectNameEXT can name wrapped handles like instance, physical device,
|
||||
// or surface
|
||||
struct {
|
||||
bool ext_debug_marker_enabled;
|
||||
bool ext_debug_utils_enabled;
|
||||
} layer_extensions;
|
||||
|
||||
// List of activated device extensions that have terminators implemented in the loader
|
||||
struct {
|
||||
bool khr_swapchain_enabled;
|
||||
@ -199,9 +205,13 @@ struct loader_device {
|
||||
bool ext_debug_marker_enabled;
|
||||
bool ext_debug_utils_enabled;
|
||||
bool ext_full_screen_exclusive_enabled;
|
||||
} extensions;
|
||||
} driver_extensions;
|
||||
|
||||
struct loader_device *next;
|
||||
|
||||
// Makes vkGetDeviceProcAddr check if core functions are supported by the current app_api_version.
|
||||
// Only set to true if VK_KHR_maintenance5 is enabled.
|
||||
bool should_ignore_device_commands_from_newer_version;
|
||||
};
|
||||
|
||||
// Per ICD information
|
||||
@ -243,6 +253,9 @@ struct loader_instance {
|
||||
struct loader_instance_dispatch_table *disp; // must be first entry in structure
|
||||
uint64_t magic; // Should be LOADER_MAGIC_NUMBER
|
||||
|
||||
// Store all the terminators for instance functions in case a layer queries one *after* vkCreateInstance
|
||||
VkLayerInstanceDispatchTable terminator_dispatch;
|
||||
|
||||
// Vulkan API version the app is intending to use.
|
||||
loader_api_version app_api_version;
|
||||
|
||||
@ -267,6 +280,8 @@ struct loader_instance {
|
||||
struct loader_icd_term *icd_terms;
|
||||
struct loader_icd_tramp_list icd_tramp_list;
|
||||
|
||||
// Must store the strings inside loader_instance directly - since the asm code will offset into
|
||||
// loader_instance to get the function name
|
||||
uint32_t dev_ext_disp_function_count;
|
||||
char *dev_ext_disp_functions[MAX_NUM_UNKNOWN_EXTS];
|
||||
uint32_t phys_dev_ext_disp_function_count;
|
||||
@ -274,6 +289,8 @@ struct loader_instance {
|
||||
|
||||
struct loader_msg_callback_map_entry *icd_msg_callback_map;
|
||||
|
||||
struct loader_string_list enabled_layer_names;
|
||||
|
||||
struct loader_layer_list instance_layer_list;
|
||||
bool override_layer_present;
|
||||
|
||||
@ -282,68 +299,71 @@ struct loader_instance {
|
||||
// This is what must be returned to the application on Enumerate calls.
|
||||
// expanded_ is the version based on expanding meta-layers into their
|
||||
// individual component layers. This is what is used internally.
|
||||
struct loader_layer_list app_activated_layer_list;
|
||||
struct loader_layer_list expanded_activated_layer_list;
|
||||
struct loader_pointer_layer_list app_activated_layer_list;
|
||||
struct loader_pointer_layer_list expanded_activated_layer_list;
|
||||
|
||||
VkInstance instance; // layers/ICD instance returned to trampoline
|
||||
|
||||
struct loader_extension_list ext_list; // icds and loaders extensions
|
||||
struct loader_instance_extension_enables enabled_known_extensions;
|
||||
|
||||
// Stores debug callbacks - used in the log
|
||||
VkLayerDbgFunctionNode *DbgFunctionHead;
|
||||
|
||||
// Stores the debug callbacks set during instance creation
|
||||
// These are kept separate because they aren't to be used outside of instance creation and destruction
|
||||
// So they are swapped out at the end of instance creation and swapped in at instance destruction
|
||||
VkLayerDbgFunctionNode *InstanceCreationDeletionDebugFunctionHead;
|
||||
// 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
|
||||
|
||||
VkAllocationCallbacks alloc_callbacks;
|
||||
|
||||
// Set to true after vkCreateInstance has returned - necessary for loader_gpa_instance_terminator()
|
||||
bool instance_finished_creation;
|
||||
|
||||
loader_settings settings;
|
||||
|
||||
bool portability_enumeration_enabled;
|
||||
bool portability_enumeration_flag_bit_set;
|
||||
bool portability_enumeration_extension_enabled;
|
||||
|
||||
bool wsi_surface_enabled;
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
bool wsi_win32_surface_enabled;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
bool wsi_wayland_surface_enabled;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
bool wsi_xcb_surface_enabled;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
bool wsi_xlib_surface_enabled;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
|
||||
bool wsi_directfb_surface_enabled;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
bool wsi_android_surface_enabled;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
#if defined(VK_USE_PLATFORM_OHOS)
|
||||
bool wsi_ohos_surface_enabled;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_MACOS_MVK
|
||||
#if defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
bool wsi_macos_surface_enabled;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_IOS_MVK
|
||||
#if defined(VK_USE_PLATFORM_IOS_MVK)
|
||||
bool wsi_ios_surface_enabled;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_GGP
|
||||
#if defined(VK_USE_PLATFORM_GGP)
|
||||
bool wsi_ggp_surface_enabled;
|
||||
#endif
|
||||
bool wsi_headless_surface_enabled;
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
bool wsi_metal_surface_enabled;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
bool wsi_imagepipe_surface_enabled;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_SCREEN_QNX
|
||||
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
|
||||
bool wsi_screen_surface_enabled;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_VI_NN
|
||||
#if defined(VK_USE_PLATFORM_VI_NN)
|
||||
bool wsi_vi_surface_enabled;
|
||||
#endif
|
||||
bool wsi_display_enabled;
|
||||
@ -384,9 +404,9 @@ struct loader_physical_device_term {
|
||||
VkPhysicalDevice phys_dev; // object from ICD
|
||||
};
|
||||
|
||||
#ifdef LOADER_ENABLE_LINUX_SORT
|
||||
// Structure for storing the relevent device information for selecting a device.
|
||||
// NOTE: Needs to be defined here so we can store this content in the term structrue
|
||||
#if defined(LOADER_ENABLE_LINUX_SORT)
|
||||
// Structure for storing the relevant device information for selecting a device.
|
||||
// NOTE: Needs to be defined here so we can store this content in the term structure
|
||||
// for quicker sorting.
|
||||
struct LinuxSortedDeviceInfo {
|
||||
// Associated Vulkan Physical Device
|
||||
@ -417,7 +437,7 @@ struct loader_physical_device_group_term {
|
||||
struct loader_icd_term *this_icd_term;
|
||||
uint8_t icd_index;
|
||||
VkPhysicalDeviceGroupProperties group_props;
|
||||
#ifdef LOADER_ENABLE_LINUX_SORT
|
||||
#if defined(LOADER_ENABLE_LINUX_SORT)
|
||||
struct LinuxSortedDeviceInfo internal_device_info[VK_MAX_DEVICE_GROUP_SIZE];
|
||||
#endif // LOADER_ENABLE_LINUX_SORT
|
||||
};
|
||||
@ -447,20 +467,49 @@ enum loader_data_files_type {
|
||||
LOADER_DATA_FILE_NUM_TYPES // Not a real field, used for possible loop terminator
|
||||
};
|
||||
|
||||
struct loader_data_files {
|
||||
uint32_t count;
|
||||
uint32_t alloc_count;
|
||||
char **filename_list;
|
||||
};
|
||||
|
||||
struct loader_phys_dev_per_icd {
|
||||
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;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct loader_msg_callback_map_entry {
|
||||
VkDebugReportCallbackEXT icd_obj;
|
||||
VkDebugReportCallbackEXT loader_obj;
|
||||
};
|
||||
|
||||
typedef enum loader_filter_string_type {
|
||||
FILTER_STRING_FULLNAME = 0,
|
||||
FILTER_STRING_SUBSTRING,
|
||||
FILTER_STRING_PREFIX,
|
||||
FILTER_STRING_SUFFIX,
|
||||
FILTER_STRING_SPECIAL,
|
||||
} loader_filter_string_type;
|
||||
|
||||
struct loader_envvar_filter_value {
|
||||
char value[VK_MAX_EXTENSION_NAME_SIZE];
|
||||
size_t length;
|
||||
loader_filter_string_type type;
|
||||
};
|
||||
|
||||
#define MAX_ADDITIONAL_FILTERS 16
|
||||
struct loader_envvar_filter {
|
||||
uint32_t count;
|
||||
struct loader_envvar_filter_value filters[MAX_ADDITIONAL_FILTERS];
|
||||
};
|
||||
struct loader_envvar_disable_layers_filter {
|
||||
struct loader_envvar_filter additional_filters;
|
||||
bool disable_all;
|
||||
bool disable_all_implicit;
|
||||
bool disable_all_explicit;
|
||||
};
|
||||
|
||||
struct loader_envvar_all_filters {
|
||||
struct loader_envvar_filter enable_filter;
|
||||
struct loader_envvar_disable_layers_filter disable_filter;
|
||||
struct loader_envvar_filter allow_filter;
|
||||
};
|
||||
|
577
loader/loader_environment.c
Normal file
577
loader/loader_environment.c
Normal file
@ -0,0 +1,577 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2014-2023 The Khronos Group Inc.
|
||||
* Copyright (c) 2014-2023 Valve Corporation
|
||||
* Copyright (c) 2014-2023 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: Courtney Goeltzenleuchter <courtney@LunarG.com>
|
||||
* Author: Chia-I Wu <olvaffe@gmail.com>
|
||||
* Author: Chia-I Wu <olv@lunarg.com>
|
||||
* Author: Mark Lobodzinski <mark@LunarG.com>
|
||||
* Author: Lenny Komow <lenny@lunarg.com>
|
||||
* Author: Charles Giessen <charles@lunarg.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "loader_environment.h"
|
||||
|
||||
#include "allocation.h"
|
||||
#include "loader.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include "param/sys_param.h"
|
||||
|
||||
// Environment variables
|
||||
#if COMMON_UNIX_PLATFORMS
|
||||
|
||||
bool is_high_integrity() { return geteuid() != getuid() || getegid() != getgid(); }
|
||||
|
||||
char *loader_getenv(const char *name, const struct loader_instance *inst) {
|
||||
if (NULL == name) return NULL;
|
||||
#if defined(__OHOS__)
|
||||
CachedHandle g_Handle = CachedParameterCreate(name, "");
|
||||
int changed = 0;
|
||||
const char *res = CachedParameterGetChanged(g_Handle, &changed);
|
||||
loader_log(inst, VULKAN_LOADER_DEBUG_BIT | VULKAN_LOADER_INFO_BIT, 0, "loader_getenv name:%s, res:%s", name, res);
|
||||
if (res == NULL || res[0] == '\0') {
|
||||
return NULL;
|
||||
}
|
||||
return (char *)res;
|
||||
#else
|
||||
// No allocation of memory necessary for Linux, but we should at least touch
|
||||
// the inst pointer to get rid of compiler warnings.
|
||||
(void)inst;
|
||||
return getenv(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *loader_secure_getenv(const char *name, const struct loader_instance *inst) {
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
// Apple does not appear to have a secure getenv implementation.
|
||||
// The main difference between secure getenv and getenv is that secure getenv
|
||||
// returns NULL if the process is being run with elevated privileges by a normal user.
|
||||
// The idea is to prevent the reading of malicious environment variables by a process
|
||||
// that can do damage.
|
||||
// This algorithm is derived from glibc code that sets an internal
|
||||
// variable (__libc_enable_secure) if the process is running under setuid or setgid.
|
||||
return is_high_integrity() ? NULL : loader_getenv(name, inst);
|
||||
#elif defined(__Fuchsia__)
|
||||
return loader_getenv(name, inst);
|
||||
#else
|
||||
// Linux
|
||||
char *out;
|
||||
#if defined(HAVE_SECURE_GETENV) && !defined(LOADER_USE_UNSAFE_FILE_SEARCH)
|
||||
(void)inst;
|
||||
out = secure_getenv(name);
|
||||
#elif defined(HAVE___SECURE_GETENV) && !defined(LOADER_USE_UNSAFE_FILE_SEARCH)
|
||||
(void)inst;
|
||||
out = __secure_getenv(name);
|
||||
#else
|
||||
out = loader_getenv(name, inst);
|
||||
#if !defined(LOADER_USE_UNSAFE_FILE_SEARCH)
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "Loader is using non-secure environment variable lookup for %s", name);
|
||||
#endif
|
||||
#endif
|
||||
return out;
|
||||
#endif
|
||||
}
|
||||
|
||||
void loader_free_getenv(char *val, const struct loader_instance *inst) {
|
||||
// No freeing of memory necessary for Linux, but we should at least touch
|
||||
// the val and inst pointers to get rid of compiler warnings.
|
||||
(void)val;
|
||||
(void)inst;
|
||||
}
|
||||
|
||||
#elif defined(WIN32)
|
||||
|
||||
bool is_high_integrity() {
|
||||
HANDLE process_token;
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, &process_token)) {
|
||||
// Maximum possible size of SID_AND_ATTRIBUTES is maximum size of a SID + size of attributes DWORD.
|
||||
uint8_t mandatory_label_buffer[SECURITY_MAX_SID_SIZE + sizeof(DWORD)];
|
||||
DWORD buffer_size;
|
||||
if (GetTokenInformation(process_token, TokenIntegrityLevel, mandatory_label_buffer, sizeof(mandatory_label_buffer),
|
||||
&buffer_size) != 0) {
|
||||
const TOKEN_MANDATORY_LABEL *mandatory_label = (const TOKEN_MANDATORY_LABEL *)mandatory_label_buffer;
|
||||
const DWORD sub_authority_count = *GetSidSubAuthorityCount(mandatory_label->Label.Sid);
|
||||
const DWORD integrity_level = *GetSidSubAuthority(mandatory_label->Label.Sid, sub_authority_count - 1);
|
||||
|
||||
CloseHandle(process_token);
|
||||
return integrity_level >= SECURITY_MANDATORY_HIGH_RID;
|
||||
}
|
||||
|
||||
CloseHandle(process_token);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
char *loader_getenv(const char *name, const struct loader_instance *inst) {
|
||||
int name_utf16_size = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
|
||||
if (name_utf16_size <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
wchar_t *name_utf16 = (wchar_t *)loader_stack_alloc(name_utf16_size * sizeof(wchar_t));
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, name, -1, name_utf16, name_utf16_size) != name_utf16_size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD val_size = GetEnvironmentVariableW(name_utf16, NULL, 0);
|
||||
// val_size DOES include the null terminator, so for any set variable
|
||||
// will always be at least 1. If it's 0, the variable wasn't set.
|
||||
if (val_size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wchar_t *val = (wchar_t *)loader_stack_alloc(val_size * sizeof(wchar_t));
|
||||
if (GetEnvironmentVariableW(name_utf16, val, val_size) != val_size - 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int val_utf8_size = WideCharToMultiByte(CP_UTF8, 0, val, -1, NULL, 0, NULL, NULL);
|
||||
if (val_utf8_size <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
char *val_utf8 = (char *)loader_instance_heap_alloc(inst, val_utf8_size * sizeof(char), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (val_utf8 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, val, -1, val_utf8, val_utf8_size, NULL, NULL) != val_utf8_size) {
|
||||
loader_instance_heap_free(inst, val_utf8);
|
||||
return NULL;
|
||||
}
|
||||
return val_utf8;
|
||||
}
|
||||
|
||||
char *loader_secure_getenv(const char *name, const struct loader_instance *inst) {
|
||||
if (NULL == name) return NULL;
|
||||
#if !defined(LOADER_USE_UNSAFE_FILE_SEARCH)
|
||||
if (is_high_integrity()) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
|
||||
"Loader is running with elevated permissions. Environment variable %s will be ignored", name);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return loader_getenv(name, inst);
|
||||
}
|
||||
|
||||
void loader_free_getenv(char *val, const struct loader_instance *inst) { loader_instance_heap_free(inst, (void *)val); }
|
||||
|
||||
#else
|
||||
|
||||
#warning \
|
||||
"This platform does not support environment variables! If this is not intended, please implement the stubs functions loader_getenv and loader_free_getenv"
|
||||
|
||||
char *loader_getenv(const char *name, const struct loader_instance *inst) {
|
||||
// stub func
|
||||
(void)inst;
|
||||
(void)name;
|
||||
return NULL;
|
||||
}
|
||||
void loader_free_getenv(char *val, const struct loader_instance *inst) {
|
||||
// stub func
|
||||
(void)val;
|
||||
(void)inst;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Determine the type of filter string based on the contents of it.
|
||||
// This will properly check against:
|
||||
// - substrings "*string*"
|
||||
// - prefixes "string*"
|
||||
// - suffixes "*string"
|
||||
// - full string names "string"
|
||||
// It will also return the correct start and finish to remove any star '*' characters for the actual string compare
|
||||
void determine_filter_type(const char *filter_string, enum loader_filter_string_type *filter_type, const char **new_start,
|
||||
size_t *new_length) {
|
||||
size_t filter_length = strlen(filter_string);
|
||||
bool star_begin = false;
|
||||
bool star_end = false;
|
||||
if ('~' == filter_string[0]) {
|
||||
// One of the special identifiers like: ~all~, ~implicit~, or ~explicit~
|
||||
*filter_type = FILTER_STRING_SPECIAL;
|
||||
*new_start = filter_string;
|
||||
*new_length = filter_length;
|
||||
} else {
|
||||
if ('*' == filter_string[0]) {
|
||||
// Only the * means everything
|
||||
if (filter_length == 1) {
|
||||
*filter_type = FILTER_STRING_SPECIAL;
|
||||
*new_start = filter_string;
|
||||
*new_length = filter_length;
|
||||
} else {
|
||||
star_begin = true;
|
||||
}
|
||||
}
|
||||
if ('*' == filter_string[filter_length - 1]) {
|
||||
// Not really valid, but just catch this case so if someone accidentally types "**" it will also mean everything
|
||||
if (filter_length == 2) {
|
||||
*filter_type = FILTER_STRING_SPECIAL;
|
||||
*new_start = filter_string;
|
||||
*new_length = filter_length;
|
||||
} else {
|
||||
star_end = true;
|
||||
}
|
||||
}
|
||||
if (star_begin && star_end) {
|
||||
*filter_type = FILTER_STRING_SUBSTRING;
|
||||
*new_start = &filter_string[1];
|
||||
*new_length = filter_length - 2;
|
||||
} else if (star_begin) {
|
||||
*new_start = &filter_string[1];
|
||||
*new_length = filter_length - 1;
|
||||
*filter_type = FILTER_STRING_SUFFIX;
|
||||
} else if (star_end) {
|
||||
*filter_type = FILTER_STRING_PREFIX;
|
||||
*new_start = filter_string;
|
||||
*new_length = filter_length - 1;
|
||||
} else {
|
||||
*filter_type = FILTER_STRING_FULLNAME;
|
||||
*new_start = filter_string;
|
||||
*new_length = filter_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the provided filter string provided by the envrionment variable into the appropriate filter
|
||||
// struct variable.
|
||||
VkResult parse_generic_filter_environment_var(const struct loader_instance *inst, const char *env_var_name,
|
||||
struct loader_envvar_filter *filter_struct) {
|
||||
VkResult result = VK_SUCCESS;
|
||||
memset(filter_struct, 0, sizeof(struct loader_envvar_filter));
|
||||
char *parsing_string = NULL;
|
||||
char *env_var_value = loader_secure_getenv(env_var_name, inst);
|
||||
if (NULL == env_var_value) {
|
||||
return result;
|
||||
}
|
||||
const size_t env_var_len = strlen(env_var_value);
|
||||
if (env_var_len == 0) {
|
||||
goto out;
|
||||
}
|
||||
// Allocate a separate string since scan_for_next_comma modifies the original string
|
||||
parsing_string = loader_instance_heap_calloc(inst, env_var_len + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
||||
if (NULL == parsing_string) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"parse_generic_filter_environment_var: Failed to allocate space for parsing env var \'%s\'", env_var_name);
|
||||
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (uint32_t iii = 0; iii < env_var_len; ++iii) {
|
||||
parsing_string[iii] = (char)tolower(env_var_value[iii]);
|
||||
}
|
||||
parsing_string[env_var_len] = '\0';
|
||||
|
||||
char *context = NULL;
|
||||
char *token = thread_safe_strtok(parsing_string, ",", &context);
|
||||
while (NULL != token) {
|
||||
enum loader_filter_string_type cur_filter_type;
|
||||
const char *actual_start;
|
||||
size_t actual_len;
|
||||
determine_filter_type(token, &cur_filter_type, &actual_start, &actual_len);
|
||||
if (actual_len > VK_MAX_EXTENSION_NAME_SIZE) {
|
||||
loader_strncpy(filter_struct->filters[filter_struct->count].value, VK_MAX_EXTENSION_NAME_SIZE, actual_start,
|
||||
VK_MAX_EXTENSION_NAME_SIZE);
|
||||
} else {
|
||||
loader_strncpy(filter_struct->filters[filter_struct->count].value, VK_MAX_EXTENSION_NAME_SIZE, actual_start,
|
||||
actual_len);
|
||||
}
|
||||
filter_struct->filters[filter_struct->count].length = actual_len;
|
||||
filter_struct->filters[filter_struct->count++].type = cur_filter_type;
|
||||
if (filter_struct->count >= MAX_ADDITIONAL_FILTERS) {
|
||||
break;
|
||||
}
|
||||
token = thread_safe_strtok(NULL, ",", &context);
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
loader_instance_heap_free(inst, parsing_string);
|
||||
loader_free_getenv(env_var_value, inst);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parse the disable layer string. The layer disable has some special behavior because we allow it to disable
|
||||
// all layers (either with "~all~", "*", or "**"), all implicit layers (with "~implicit~"), and all explicit layers
|
||||
// (with "~explicit~"), in addition to the other layer filtering behavior.
|
||||
VkResult parse_layers_disable_filter_environment_var(const struct loader_instance *inst,
|
||||
struct loader_envvar_disable_layers_filter *disable_struct) {
|
||||
VkResult result = VK_SUCCESS;
|
||||
memset(disable_struct, 0, sizeof(struct loader_envvar_disable_layers_filter));
|
||||
char *parsing_string = NULL;
|
||||
char *env_var_value = loader_secure_getenv(VK_LAYERS_DISABLE_ENV_VAR, inst);
|
||||
if (NULL == env_var_value) {
|
||||
goto out;
|
||||
}
|
||||
const size_t env_var_len = strlen(env_var_value);
|
||||
if (env_var_len == 0) {
|
||||
goto out;
|
||||
}
|
||||
// Allocate a separate string since scan_for_next_comma modifies the original string
|
||||
parsing_string = loader_instance_heap_calloc(inst, env_var_len + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
||||
if (NULL == parsing_string) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"parse_layers_disable_filter_environment_var: Failed to allocate space for parsing env var "
|
||||
"\'VK_LAYERS_DISABLE_ENV_VAR\'");
|
||||
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (uint32_t iii = 0; iii < env_var_len; ++iii) {
|
||||
parsing_string[iii] = (char)tolower(env_var_value[iii]);
|
||||
}
|
||||
parsing_string[env_var_len] = '\0';
|
||||
|
||||
char *context = NULL;
|
||||
char *token = thread_safe_strtok(parsing_string, ",", &context);
|
||||
while (NULL != token) {
|
||||
uint32_t cur_count = disable_struct->additional_filters.count;
|
||||
enum loader_filter_string_type cur_filter_type;
|
||||
const char *actual_start;
|
||||
size_t actual_len;
|
||||
determine_filter_type(token, &cur_filter_type, &actual_start, &actual_len);
|
||||
if (cur_filter_type == FILTER_STRING_SPECIAL) {
|
||||
if (!strcmp(VK_LOADER_DISABLE_ALL_LAYERS_VAR_1, token) || !strcmp(VK_LOADER_DISABLE_ALL_LAYERS_VAR_2, token) ||
|
||||
!strcmp(VK_LOADER_DISABLE_ALL_LAYERS_VAR_3, token)) {
|
||||
disable_struct->disable_all = true;
|
||||
} else if (!strcmp(VK_LOADER_DISABLE_IMPLICIT_LAYERS_VAR, token)) {
|
||||
disable_struct->disable_all_implicit = true;
|
||||
} else if (!strcmp(VK_LOADER_DISABLE_EXPLICIT_LAYERS_VAR, token)) {
|
||||
disable_struct->disable_all_explicit = true;
|
||||
}
|
||||
} else {
|
||||
if (actual_len > VK_MAX_EXTENSION_NAME_SIZE) {
|
||||
loader_strncpy(disable_struct->additional_filters.filters[cur_count].value, VK_MAX_EXTENSION_NAME_SIZE,
|
||||
actual_start, VK_MAX_EXTENSION_NAME_SIZE);
|
||||
} else {
|
||||
loader_strncpy(disable_struct->additional_filters.filters[cur_count].value, VK_MAX_EXTENSION_NAME_SIZE,
|
||||
actual_start, actual_len);
|
||||
}
|
||||
disable_struct->additional_filters.filters[cur_count].length = actual_len;
|
||||
disable_struct->additional_filters.filters[cur_count].type = cur_filter_type;
|
||||
disable_struct->additional_filters.count++;
|
||||
if (disable_struct->additional_filters.count >= MAX_ADDITIONAL_FILTERS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
token = thread_safe_strtok(NULL, ",", &context);
|
||||
}
|
||||
out:
|
||||
loader_instance_heap_free(inst, parsing_string);
|
||||
loader_free_getenv(env_var_value, inst);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parses the filter environment variables to determine if we have any special behavior
|
||||
VkResult parse_layer_environment_var_filters(const struct loader_instance *inst, struct loader_envvar_all_filters *layer_filters) {
|
||||
VkResult res = parse_generic_filter_environment_var(inst, VK_LAYERS_ENABLE_ENV_VAR, &layer_filters->enable_filter);
|
||||
if (VK_SUCCESS != res) {
|
||||
return res;
|
||||
}
|
||||
res = parse_layers_disable_filter_environment_var(inst, &layer_filters->disable_filter);
|
||||
if (VK_SUCCESS != res) {
|
||||
return res;
|
||||
}
|
||||
res = parse_generic_filter_environment_var(inst, VK_LAYERS_ALLOW_ENV_VAR, &layer_filters->allow_filter);
|
||||
if (VK_SUCCESS != res) {
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Check to see if the provided layer name matches any of the filter strings.
|
||||
// This will properly check against:
|
||||
// - substrings "*string*"
|
||||
// - prefixes "string*"
|
||||
// - suffixes "*string"
|
||||
// - full string names "string"
|
||||
bool check_name_matches_filter_environment_var(const char *name, const struct loader_envvar_filter *filter_struct) {
|
||||
bool ret_value = false;
|
||||
const size_t name_len = strlen(name);
|
||||
char lower_name[VK_MAX_EXTENSION_NAME_SIZE];
|
||||
for (uint32_t iii = 0; iii < name_len; ++iii) {
|
||||
lower_name[iii] = (char)tolower(name[iii]);
|
||||
}
|
||||
lower_name[name_len] = '\0';
|
||||
for (uint32_t filt = 0; filt < filter_struct->count; ++filt) {
|
||||
// Check if the filter name is longer (this is with all special characters removed), and if it is
|
||||
// continue since it can't match.
|
||||
if (filter_struct->filters[filt].length > name_len) {
|
||||
continue;
|
||||
}
|
||||
switch (filter_struct->filters[filt].type) {
|
||||
case FILTER_STRING_SPECIAL:
|
||||
if (!strcmp(VK_LOADER_DISABLE_ALL_LAYERS_VAR_1, filter_struct->filters[filt].value) ||
|
||||
!strcmp(VK_LOADER_DISABLE_ALL_LAYERS_VAR_2, filter_struct->filters[filt].value) ||
|
||||
!strcmp(VK_LOADER_DISABLE_ALL_LAYERS_VAR_3, filter_struct->filters[filt].value)) {
|
||||
ret_value = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case FILTER_STRING_SUBSTRING:
|
||||
if (NULL != strstr(lower_name, filter_struct->filters[filt].value)) {
|
||||
ret_value = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case FILTER_STRING_SUFFIX:
|
||||
if (0 == strncmp(lower_name + name_len - filter_struct->filters[filt].length, filter_struct->filters[filt].value,
|
||||
filter_struct->filters[filt].length)) {
|
||||
ret_value = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case FILTER_STRING_PREFIX:
|
||||
if (0 == strncmp(lower_name, filter_struct->filters[filt].value, filter_struct->filters[filt].length)) {
|
||||
ret_value = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case FILTER_STRING_FULLNAME:
|
||||
if (0 == strncmp(lower_name, filter_struct->filters[filt].value, name_len)) {
|
||||
ret_value = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ret_value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
// Get the layer name(s) from the env_name environment variable. If layer is found in
|
||||
// search_list then add it to layer_list. But only add it to layer_list if type_flags matches.
|
||||
VkResult loader_add_environment_layers(struct loader_instance *inst, const enum layer_type_flags type_flags,
|
||||
const struct loader_envvar_all_filters *filters,
|
||||
struct loader_pointer_layer_list *target_list,
|
||||
struct loader_pointer_layer_list *expanded_target_list,
|
||||
const struct loader_layer_list *source_list) {
|
||||
VkResult res = VK_SUCCESS;
|
||||
char *layer_env = loader_getenv(ENABLED_LAYERS_ENV, inst);
|
||||
|
||||
// If the layer environment variable is present (i.e. VK_INSTANCE_LAYERS), we will always add it to the layer list.
|
||||
if (layer_env != NULL) {
|
||||
size_t layer_env_len = strlen(layer_env) + 1;
|
||||
char *name = loader_stack_alloc(layer_env_len);
|
||||
if (name != NULL) {
|
||||
loader_strncpy(name, layer_env_len, layer_env, layer_env_len);
|
||||
|
||||
loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0, "env var \'%s\' defined and adding layers \"%s\"",
|
||||
ENABLED_LAYERS_ENV, name);
|
||||
|
||||
// First look for the old-fashion layers forced on with VK_INSTANCE_LAYERS
|
||||
while (name && *name) {
|
||||
char *next = loader_get_next_path(name);
|
||||
|
||||
if (strlen(name) > 0) {
|
||||
bool found = false;
|
||||
for (uint32_t i = 0; i < source_list->count; i++) {
|
||||
struct loader_layer_properties *source_prop = &source_list->list[i];
|
||||
|
||||
if (0 == strcmp(name, source_prop->info.layerName)) {
|
||||
found = true;
|
||||
// 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)) {
|
||||
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);
|
||||
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
|
||||
} else {
|
||||
res = loader_add_meta_layer(inst, filters, source_prop, target_list, expanded_target_list,
|
||||
source_list, NULL);
|
||||
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_LAYER_BIT, 0,
|
||||
"Layer \"%s\" was not found but was requested by env var VK_INSTANCE_LAYERS!", name);
|
||||
}
|
||||
}
|
||||
name = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through all the layers and check the enable/disable filters
|
||||
for (uint32_t i = 0; i < source_list->count; i++) {
|
||||
struct loader_layer_properties *source_prop = &source_list->list[i];
|
||||
|
||||
// If it doesn't match the type, or the name isn't what we're looking for, just continue
|
||||
if ((source_prop->type_flags & type_flags) != type_flags) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We found a layer we're interested in, but has it been disabled...
|
||||
bool adding = true;
|
||||
bool is_implicit = (0 == (source_prop->type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER));
|
||||
bool disabled_by_type =
|
||||
(is_implicit) ? (filters->disable_filter.disable_all_implicit) : (filters->disable_filter.disable_all_explicit);
|
||||
if ((filters->disable_filter.disable_all || disabled_by_type ||
|
||||
check_name_matches_filter_environment_var(source_prop->info.layerName, &filters->disable_filter.additional_filters)) &&
|
||||
!check_name_matches_filter_environment_var(source_prop->info.layerName, &filters->allow_filter)) {
|
||||
loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0,
|
||||
"Layer \"%s\" ignored because it has been disabled by env var \'%s\'", source_prop->info.layerName,
|
||||
VK_LAYERS_DISABLE_ENV_VAR);
|
||||
adding = false;
|
||||
}
|
||||
|
||||
// If we are supposed to filter through all layers, we need to compare the layer name against the filter.
|
||||
// This can override the disable above, so we want to do it second.
|
||||
// Also make sure the layer isn't already in the output_list, skip adding it if it is.
|
||||
if (check_name_matches_filter_environment_var(source_prop->info.layerName, &filters->enable_filter) &&
|
||||
!loader_find_layer_name_in_list(source_prop->info.layerName, target_list)) {
|
||||
adding = true;
|
||||
// Only way is_substring is true is if there are enable variables. If that's the case, and we're past the
|
||||
// above, we should indicate that it was forced on in this way.
|
||||
loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0,
|
||||
"Layer \"%s\" forced enabled due to env var \'%s\'", source_prop->info.layerName, VK_LAYERS_ENABLE_ENV_VAR);
|
||||
} else {
|
||||
adding = false;
|
||||
}
|
||||
|
||||
if (!adding) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If not a meta-layer, simply add it.
|
||||
if (0 == (source_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
|
||||
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);
|
||||
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
|
||||
} else {
|
||||
res = loader_add_meta_layer(inst, filters, source_prop, target_list, expanded_target_list, source_list, NULL);
|
||||
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
if (layer_env != NULL) {
|
||||
loader_free_getenv(layer_env, inst);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
@ -35,10 +35,22 @@
|
||||
char *loader_getenv(const char *name, const struct loader_instance *inst);
|
||||
void loader_free_getenv(char *val, const struct loader_instance *inst);
|
||||
|
||||
#if defined(WIN32) || defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNXNTO__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#if defined(WIN32) || COMMON_UNIX_PLATFORMS
|
||||
|
||||
bool is_high_integrity();
|
||||
|
||||
char *loader_secure_getenv(const char *name, const struct loader_instance *inst);
|
||||
|
||||
#endif
|
||||
|
||||
VkResult parse_generic_filter_environment_var(const struct loader_instance *inst, const char *env_var_name,
|
||||
struct loader_envvar_filter *filter_struct);
|
||||
VkResult parse_layers_disable_filter_environment_var(const struct loader_instance *inst,
|
||||
struct loader_envvar_disable_layers_filter *disable_struct);
|
||||
VkResult parse_layer_environment_var_filters(const struct loader_instance *inst, struct loader_envvar_all_filters *layer_filters);
|
||||
bool check_name_matches_filter_environment_var(const char *name, const struct loader_envvar_filter *filter_struct);
|
||||
VkResult loader_add_environment_layers(struct loader_instance *inst, const enum layer_type_flags type_flags,
|
||||
const struct loader_envvar_all_filters *filters,
|
||||
struct loader_pointer_layer_list *target_list,
|
||||
struct loader_pointer_layer_list *expanded_target_list,
|
||||
const struct loader_layer_list *source_list);
|
@ -22,7 +22,7 @@
|
||||
|
||||
// Non-windows and non-apple only header file, guard it so that accidental
|
||||
// inclusion doesn't cause unknown header include errors
|
||||
#ifdef LOADER_ENABLE_LINUX_SORT
|
||||
#if defined(LOADER_ENABLE_LINUX_SORT)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -30,12 +30,12 @@
|
||||
#include "loader_linux.h"
|
||||
|
||||
#include "allocation.h"
|
||||
#include "get_environment.h"
|
||||
#include "loader_environment.h"
|
||||
#include "loader.h"
|
||||
#include "log.h"
|
||||
|
||||
// Determine a priority based on device type with the higher value being higher priority.
|
||||
static uint32_t determine_priority_type_value(VkPhysicalDeviceType type) {
|
||||
uint32_t determine_priority_type_value(VkPhysicalDeviceType type) {
|
||||
switch (type) {
|
||||
case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
|
||||
return 10;
|
||||
@ -55,7 +55,7 @@ static uint32_t determine_priority_type_value(VkPhysicalDeviceType type) {
|
||||
|
||||
// Compare the two device types.
|
||||
// This behaves similar to a qsort compare.
|
||||
static int32_t device_type_compare(VkPhysicalDeviceType a, VkPhysicalDeviceType b) {
|
||||
int32_t device_type_compare(VkPhysicalDeviceType a, VkPhysicalDeviceType b) {
|
||||
uint32_t a_value = determine_priority_type_value(a);
|
||||
uint32_t b_value = determine_priority_type_value(b);
|
||||
if (a_value > b_value) {
|
||||
@ -204,12 +204,12 @@ int32_t compare_device_groups(const void *a, const void *b) {
|
||||
}
|
||||
|
||||
// Search for the default device using the loader environment variable.
|
||||
static void linux_env_var_default_device(struct loader_instance *inst, uint32_t device_count,
|
||||
struct LinuxSortedDeviceInfo *sorted_device_info) {
|
||||
void linux_env_var_default_device(struct loader_instance *inst, uint32_t device_count,
|
||||
struct LinuxSortedDeviceInfo *sorted_device_info) {
|
||||
char *selection = loader_getenv("VK_LOADER_DEVICE_SELECT", inst);
|
||||
if (NULL != selection) {
|
||||
loader_log(inst, VULKAN_LOADER_DEBUG_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
|
||||
"linux_env_var_default_device: Found VK_LOADER_DEVICE_SELECT set to %s", selection);
|
||||
"linux_env_var_default_device: Found \'VK_LOADER_DEVICE_SELECT\' set to %s", selection);
|
||||
|
||||
// The environment variable exists, so grab the vendor ID and device ID of the
|
||||
// selected default device
|
||||
@ -233,7 +233,7 @@ static void linux_env_var_default_device(struct loader_instance *inst, uint32_t
|
||||
|
||||
// This function allocates an array in sorted_devices which must be freed by the caller if not null
|
||||
VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32_t icd_count,
|
||||
struct loader_phys_dev_per_icd *icd_devices, uint32_t phys_dev_count,
|
||||
struct loader_icd_physical_devices *icd_devices, uint32_t phys_dev_count,
|
||||
struct loader_physical_device_term **sorted_device_term) {
|
||||
VkResult res = VK_SUCCESS;
|
||||
bool app_is_vulkan_1_1 = loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version);
|
||||
@ -269,7 +269,7 @@ VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32
|
||||
bool device_is_1_1_capable =
|
||||
loader_check_version_meets_required(LOADER_VERSION_1_1_0, loader_make_version(dev_props.apiVersion));
|
||||
if (!sorted_device_info[index].has_pci_bus_info) {
|
||||
uint32_t ext_count;
|
||||
uint32_t ext_count = 0;
|
||||
icd_term->dispatch.EnumerateDeviceExtensionProperties(sorted_device_info[index].physical_device, NULL, &ext_count,
|
||||
NULL);
|
||||
if (ext_count > 0) {
|
||||
@ -437,16 +437,14 @@ VkResult linux_sort_physical_device_groups(struct loader_instance *inst, uint32_
|
||||
// Sort device groups by PCI info
|
||||
qsort(sorted_group_term, group_count, sizeof(struct loader_physical_device_group_term), compare_device_groups);
|
||||
|
||||
if (loader_get_debug_level() & (VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT)) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, "linux_sort_physical_device_groups: Sorted order:");
|
||||
for (uint32_t group = 0; group < group_count; ++group) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " Group %u", group);
|
||||
for (uint32_t gpu = 0; gpu < sorted_group_term[group].group_props.physicalDeviceCount; ++gpu) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " [%u] %s %p %s", gpu,
|
||||
sorted_group_term[group].internal_device_info[gpu].device_name,
|
||||
sorted_group_term[group].internal_device_info[gpu].physical_device,
|
||||
(sorted_group_term[group].internal_device_info[gpu].default_device ? "[default]" : ""));
|
||||
}
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, "linux_sort_physical_device_groups: Sorted order:");
|
||||
for (uint32_t group = 0; group < group_count; ++group) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " Group %u", group);
|
||||
for (uint32_t gpu = 0; gpu < sorted_group_term[group].group_props.physicalDeviceCount; ++gpu) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " [%u] %s %p %s", gpu,
|
||||
sorted_group_term[group].internal_device_info[gpu].device_name,
|
||||
sorted_group_term[group].internal_device_info[gpu].physical_device,
|
||||
(sorted_group_term[group].internal_device_info[gpu].default_device ? "[default]" : ""));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,17 +22,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef LOADER_ENABLE_LINUX_SORT
|
||||
#if defined(LOADER_ENABLE_LINUX_SORT)
|
||||
|
||||
#include "loader_common.h"
|
||||
|
||||
// This function allocates an array in sorted_devices which must be freed by the caller if not null
|
||||
VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32_t icd_count,
|
||||
struct loader_phys_dev_per_icd *icd_devices, uint32_t phys_dev_count,
|
||||
struct loader_icd_physical_devices *icd_devices, uint32_t phys_dev_count,
|
||||
struct loader_physical_device_term **sorted_device_term);
|
||||
|
||||
// This function sorts an array in physical device groups
|
||||
VkResult linux_sort_physical_device_groups(struct loader_instance *inst, uint32_t group_count,
|
||||
struct loader_physical_device_group_term *sorted_group_term);
|
||||
|
||||
#endif // LOADER_ENABLE_LINUX_SORT
|
||||
#endif // LOADER_ENABLE_LINUX_SORT
|
||||
|
@ -27,7 +27,7 @@
|
||||
*
|
||||
*/
|
||||
// Windows only header file, guard it so that accidental inclusion doesn't cause unknown header include errors
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32)
|
||||
|
||||
// This needs to be defined first, or else we'll get redefinitions on NTSTATUS values
|
||||
#define UMDF_USING_NTSTATUS
|
||||
@ -36,7 +36,7 @@
|
||||
#include "loader_windows.h"
|
||||
|
||||
#include "allocation.h"
|
||||
#include "get_environment.h"
|
||||
#include "loader_environment.h"
|
||||
#include "loader.h"
|
||||
#include "log.h"
|
||||
|
||||
@ -45,13 +45,13 @@
|
||||
#include <devpkey.h>
|
||||
#include <winternl.h>
|
||||
#include <strsafe.h>
|
||||
#ifdef __MINGW32__
|
||||
#undef strcpy // fix error with redfined strcpy when building with MinGW-w64
|
||||
#if defined(__MINGW32__)
|
||||
#undef strcpy // fix error with redefined strcpy when building with MinGW-w64
|
||||
#endif
|
||||
#include <dxgi1_6.h>
|
||||
#include "adapters.h"
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#if !defined(__MINGW32__)
|
||||
// not yet available with MinGW-w64 stable
|
||||
#include <appmodel.h>
|
||||
#endif
|
||||
@ -61,7 +61,10 @@
|
||||
#endif
|
||||
|
||||
typedef HRESULT(APIENTRY *PFN_CreateDXGIFactory1)(REFIID riid, void **ppFactory);
|
||||
static PFN_CreateDXGIFactory1 fpCreateDXGIFactory1;
|
||||
PFN_CreateDXGIFactory1 fpCreateDXGIFactory1;
|
||||
|
||||
// Empty function just so windows_initialization can find the current module location
|
||||
void function_for_finding_the_current_module(void) {}
|
||||
|
||||
void windows_initialization(void) {
|
||||
char dll_location[MAX_PATH];
|
||||
@ -69,7 +72,7 @@ void windows_initialization(void) {
|
||||
|
||||
// Get a module handle to a static function inside of this source
|
||||
if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
(LPCSTR)&loader_debug_init, &module_handle) != 0 &&
|
||||
(LPCSTR)&function_for_finding_the_current_module, &module_handle) != 0 &&
|
||||
GetModuleFileName(module_handle, dll_location, sizeof(dll_location)) != 0) {
|
||||
loader_log(NULL, VULKAN_LOADER_INFO_BIT, 0, "Using Vulkan Loader %s", dll_location);
|
||||
}
|
||||
@ -82,7 +85,8 @@ void windows_initialization(void) {
|
||||
GetSystemDirectoryW(systemPath, MAX_PATH);
|
||||
StringCchCatW(systemPath, MAX_PATH, L"\\dxgi.dll");
|
||||
HMODULE dxgi_module = LoadLibraryW(systemPath);
|
||||
fpCreateDXGIFactory1 = dxgi_module == NULL ? NULL : (PFN_CreateDXGIFactory1)GetProcAddress(dxgi_module, "CreateDXGIFactory1");
|
||||
fpCreateDXGIFactory1 =
|
||||
dxgi_module == NULL ? NULL : (PFN_CreateDXGIFactory1)(void *)GetProcAddress(dxgi_module, "CreateDXGIFactory1");
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
_set_error_mode(_OUT_TO_STDERR);
|
||||
@ -92,6 +96,7 @@ void windows_initialization(void) {
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
|
||||
(void)hinst;
|
||||
switch (reason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
loader_initialize();
|
||||
@ -227,9 +232,9 @@ out:
|
||||
|
||||
VkResult windows_get_device_registry_files(const struct loader_instance *inst, uint32_t log_target_flag, char **reg_data,
|
||||
PDWORD reg_data_size, LPCSTR value_name) {
|
||||
static const wchar_t *softwareComponentGUID = L"{5c4c3332-344d-483c-8739-259e934c9cc8}";
|
||||
static const wchar_t *displayGUID = L"{4d36e968-e325-11ce-bfc1-08002be10318}";
|
||||
#ifdef CM_GETIDLIST_FILTER_PRESENT
|
||||
const wchar_t *softwareComponentGUID = L"{5c4c3332-344d-483c-8739-259e934c9cc8}";
|
||||
const wchar_t *displayGUID = L"{4d36e968-e325-11ce-bfc1-08002be10318}";
|
||||
#if defined(CM_GETIDLIST_FILTER_PRESENT)
|
||||
const ULONG flags = CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT;
|
||||
#else
|
||||
const ULONG flags = 0x300;
|
||||
@ -348,7 +353,7 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
|
||||
PDWORD reg_data_size) {
|
||||
// This list contains all of the allowed ICDs. This allows us to verify that a device is actually present from the vendor
|
||||
// specified. This does disallow other vendors, but any new driver should use the device-specific registries anyway.
|
||||
static const struct {
|
||||
const struct {
|
||||
const char *filename;
|
||||
unsigned int vendor_id;
|
||||
} known_drivers[] = {
|
||||
@ -525,8 +530,8 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
|
||||
foundDuplicate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundDuplicate == false) {
|
||||
// Only skip if we are adding a driver and a duplicate was found
|
||||
if (!is_driver || (is_driver && foundDuplicate == false)) {
|
||||
// Add the new entry to the list.
|
||||
(void)snprintf(*reg_data + strlen(*reg_data), name_size + 2, "%c%s", PATH_SEPARATOR, name);
|
||||
found = true;
|
||||
@ -553,7 +558,8 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
|
||||
}
|
||||
|
||||
if (!found && result != VK_ERROR_OUT_OF_HOST_MEMORY) {
|
||||
loader_log(inst, log_target_flag, 0, "Found no registry files in %s", location);
|
||||
loader_log(inst, log_target_flag, 0, "Found no registry files in %s\\%s",
|
||||
(hive == DEFAULT_VK_REGISTRY_HIVE) ? DEFAULT_VK_REGISTRY_HIVE_STR : SECONDARY_VK_REGISTRY_HIVE_STR, location);
|
||||
result = VK_ERROR_INCOMPATIBLE_DRIVER;
|
||||
}
|
||||
|
||||
@ -581,9 +587,10 @@ VkResult windows_read_manifest_from_d3d_adapters(const struct loader_instance *i
|
||||
goto out;
|
||||
}
|
||||
|
||||
PFN_LoaderEnumAdapters2 fpLoaderEnumAdapters2 = (PFN_LoaderEnumAdapters2)GetProcAddress(gdi32_dll, "D3DKMTEnumAdapters2");
|
||||
PFN_LoaderEnumAdapters2 fpLoaderEnumAdapters2 =
|
||||
(PFN_LoaderEnumAdapters2)(void *)GetProcAddress(gdi32_dll, "D3DKMTEnumAdapters2");
|
||||
PFN_LoaderQueryAdapterInfo fpLoaderQueryAdapterInfo =
|
||||
(PFN_LoaderQueryAdapterInfo)GetProcAddress(gdi32_dll, "D3DKMTQueryAdapterInfo");
|
||||
(PFN_LoaderQueryAdapterInfo)(void *)GetProcAddress(gdi32_dll, "D3DKMTQueryAdapterInfo");
|
||||
if (fpLoaderEnumAdapters2 == NULL || fpLoaderQueryAdapterInfo == NULL) {
|
||||
result = VK_ERROR_INCOMPATIBLE_DRIVER;
|
||||
goto out;
|
||||
@ -615,7 +622,8 @@ VkResult windows_read_manifest_from_d3d_adapters(const struct loader_instance *i
|
||||
.value_type = REG_MULTI_SZ,
|
||||
.physical_adapter_index = 0,
|
||||
};
|
||||
wcsncpy(filename_info.value_name, value_name, sizeof(filename_info.value_name) / sizeof(WCHAR));
|
||||
size_t value_name_size = wcslen(value_name);
|
||||
wcsncpy_s(filename_info.value_name, MAX_PATH, value_name, value_name_size);
|
||||
LoaderQueryAdapterInfo query_info;
|
||||
query_info.handle = adapters.adapters[i].handle;
|
||||
query_info.type = LOADER_QUERY_TYPE_REGISTRY;
|
||||
@ -680,7 +688,7 @@ VkResult windows_read_manifest_from_d3d_adapters(const struct loader_instance *i
|
||||
goto out;
|
||||
}
|
||||
|
||||
// If this is a string and not a multi-string, we don't want to go throught the loop more than once
|
||||
// If this is a string and not a multi-string, we don't want to go through the loop more than once
|
||||
if (full_info->value_type == REG_SZ) {
|
||||
break;
|
||||
}
|
||||
@ -698,17 +706,19 @@ out:
|
||||
// Look for data files in the registry.
|
||||
VkResult windows_read_data_files_in_registry(const struct loader_instance *inst, enum loader_data_files_type data_file_type,
|
||||
bool warn_if_not_present, char *registry_location,
|
||||
struct loader_data_files *out_files) {
|
||||
struct loader_string_list *out_files) {
|
||||
VkResult vk_result = VK_SUCCESS;
|
||||
char *search_path = NULL;
|
||||
uint32_t log_target_flag = 0;
|
||||
|
||||
if (data_file_type == LOADER_DATA_FILE_MANIFEST_DRIVER) {
|
||||
log_target_flag = VULKAN_LOADER_DRIVER_BIT;
|
||||
loader_log(inst, log_target_flag, 0, "Checking for Driver Manifest files in Registry at %s", registry_location);
|
||||
loader_log(inst, log_target_flag, 0, "Checking for Driver Manifest files in Registry at %s\\%s",
|
||||
DEFAULT_VK_REGISTRY_HIVE_STR, registry_location);
|
||||
} else {
|
||||
log_target_flag = VULKAN_LOADER_LAYER_BIT;
|
||||
loader_log(inst, log_target_flag, 0, "Checking for Layer Manifest files in Registry at %s", registry_location);
|
||||
loader_log(inst, log_target_flag, 0, "Checking for Layer Manifest files in Registry at %s\\%s",
|
||||
DEFAULT_VK_REGISTRY_HIVE_STR, registry_location);
|
||||
}
|
||||
|
||||
// These calls look at the PNP/Device section of the registry.
|
||||
@ -783,12 +793,141 @@ out:
|
||||
return vk_result;
|
||||
}
|
||||
|
||||
// This function allocates an array in sorted_devices which must be freed by the caller if not null
|
||||
VkResult windows_read_sorted_physical_devices(struct loader_instance *inst, uint32_t *sorted_devices_count,
|
||||
struct loader_phys_dev_per_icd **sorted_devices) {
|
||||
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,
|
||||
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) {
|
||||
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
|
||||
}
|
||||
|
||||
// Take a pointer to the last element of icd_phys_devs_array to simplify usage
|
||||
struct loader_icd_physical_devices *next_icd_phys_devs = &icd_phys_devs_array[*icd_phys_devs_array_count];
|
||||
|
||||
// Get the actual physical devices
|
||||
do {
|
||||
next_icd_phys_devs->physical_devices = loader_instance_heap_realloc(
|
||||
inst, next_icd_phys_devs->physical_devices, next_icd_phys_devs->device_count * sizeof(VkPhysicalDevice),
|
||||
count * sizeof(VkPhysicalDevice), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (next_icd_phys_devs->physical_devices == NULL) {
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
next_icd_phys_devs->device_count = count;
|
||||
} while ((res = icd_term->scanned_icd->EnumerateAdapterPhysicalDevices(icd_term->instance, luid, &count,
|
||||
next_icd_phys_devs->physical_devices)) == VK_INCOMPLETE);
|
||||
|
||||
if (res != VK_SUCCESS) {
|
||||
loader_instance_heap_free(inst, next_icd_phys_devs->physical_devices);
|
||||
next_icd_phys_devs->physical_devices = NULL;
|
||||
// Unless OOHM occurs, only return VK_SUCCESS
|
||||
if (res != VK_ERROR_OUT_OF_HOST_MEMORY) {
|
||||
res = VK_SUCCESS;
|
||||
loader_log(inst, VULKAN_LOADER_WARN_BIT, 0, "Failed to convert DXGI adapter into Vulkan physical device");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Because the loader calls EnumerateAdapterPhysicalDevices on all drivers with each DXGI Adapter, if there are multiple drivers
|
||||
// that share a luid the physical device will get queried multiple times. We can prevent that by not adding them if the
|
||||
// enumerated physical devices have already been added.
|
||||
bool already_enumerated = false;
|
||||
for (uint32_t j = 0; j < *icd_phys_devs_array_count; j++) {
|
||||
if (count == icd_phys_devs_array[j].device_count) {
|
||||
bool matches = true;
|
||||
for (uint32_t k = 0; k < icd_phys_devs_array[j].device_count; k++) {
|
||||
if (icd_phys_devs_array[j].physical_devices[k] != next_icd_phys_devs->physical_devices[k]) {
|
||||
matches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (matches) {
|
||||
already_enumerated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
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)++;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
// Whenever there are multiple drivers for the same hardware and one of the drivers is an implementation layered on top of another
|
||||
// API (such as the Dozen driver which converts vulkan to Dx12), we want to make sure the layered driver appears after the 'native'
|
||||
// driver. This function iterates over all physical devices and make sure any with matching LUID's are sorted such that drivers with
|
||||
// a underlyingAPI of VK_LAYERED_DRIVER_UNDERLYING_API_D3D12_MSFT are ordered after drivers without it.
|
||||
void sort_physical_devices_with_same_luid(struct loader_instance *inst, uint32_t icd_phys_devs_array_count,
|
||||
struct loader_icd_physical_devices *icd_phys_devs_array) {
|
||||
bool app_is_vulkan_1_1 = loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version);
|
||||
|
||||
for (uint32_t i = 0; icd_phys_devs_array_count > 1 && i < icd_phys_devs_array_count - 1; i++) {
|
||||
for (uint32_t j = i + 1; j < icd_phys_devs_array_count; j++) {
|
||||
// Only want to reorder physical devices if their ICD's LUID's match
|
||||
if ((icd_phys_devs_array[i].windows_adapter_luid.HighPart != icd_phys_devs_array[j].windows_adapter_luid.HighPart) ||
|
||||
(icd_phys_devs_array[i].windows_adapter_luid.LowPart != icd_phys_devs_array[j].windows_adapter_luid.LowPart)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
VkLayeredDriverUnderlyingApiMSFT underlyingAPI = VK_LAYERED_DRIVER_UNDERLYING_API_NONE_MSFT;
|
||||
VkPhysicalDeviceLayeredDriverPropertiesMSFT layered_driver_properties_msft = {0};
|
||||
layered_driver_properties_msft.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LAYERED_DRIVER_PROPERTIES_MSFT;
|
||||
VkPhysicalDeviceProperties2 props2 = {0};
|
||||
props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||
props2.pNext = (void *)&layered_driver_properties_msft;
|
||||
|
||||
// Because there may be multiple physical devices associated with each ICD, we need to check each physical device
|
||||
// whether it is layered
|
||||
for (uint32_t k = 0; k < icd_phys_devs_array[i].device_count; k++) {
|
||||
VkPhysicalDeviceProperties dev_props = {0};
|
||||
icd_phys_devs_array[i].icd_term->dispatch.GetPhysicalDeviceProperties(icd_phys_devs_array[i].physical_devices[k],
|
||||
&dev_props);
|
||||
|
||||
bool device_is_1_1_capable =
|
||||
loader_check_version_meets_required(LOADER_VERSION_1_1_0, loader_make_version(dev_props.apiVersion));
|
||||
|
||||
PFN_vkGetPhysicalDeviceProperties2 GetPhysDevProps2 = NULL;
|
||||
if (app_is_vulkan_1_1 && device_is_1_1_capable) {
|
||||
GetPhysDevProps2 = icd_phys_devs_array[i].icd_term->dispatch.GetPhysicalDeviceProperties2;
|
||||
} else {
|
||||
GetPhysDevProps2 = (PFN_vkGetPhysicalDeviceProperties2)icd_phys_devs_array[i]
|
||||
.icd_term->dispatch.GetPhysicalDeviceProperties2KHR;
|
||||
}
|
||||
if (GetPhysDevProps2) {
|
||||
GetPhysDevProps2(icd_phys_devs_array[i].physical_devices[k], &props2);
|
||||
if (layered_driver_properties_msft.underlyingAPI != VK_LAYERED_DRIVER_UNDERLYING_API_NONE_MSFT) {
|
||||
underlyingAPI = layered_driver_properties_msft.underlyingAPI;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (underlyingAPI == VK_LAYERED_DRIVER_UNDERLYING_API_D3D12_MSFT) {
|
||||
struct loader_icd_physical_devices swap_icd = icd_phys_devs_array[i];
|
||||
icd_phys_devs_array[i] = icd_phys_devs_array[j];
|
||||
icd_phys_devs_array[j] = swap_icd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function allocates icd_phys_devs_array which must be freed by the caller if not null
|
||||
VkResult windows_read_sorted_physical_devices(struct loader_instance *inst, uint32_t *icd_phys_devs_array_count,
|
||||
struct loader_icd_physical_devices **icd_phys_devs_array) {
|
||||
VkResult res = VK_SUCCESS;
|
||||
|
||||
uint32_t sorted_alloc = 0;
|
||||
uint32_t icd_phys_devs_array_size = 0;
|
||||
struct loader_icd_term *icd_term = NULL;
|
||||
IDXGIFactory6 *dxgi_factory = NULL;
|
||||
HRESULT hres = fpCreateDXGIFactory1(&IID_IDXGIFactory6, (void **)&dxgi_factory);
|
||||
@ -796,10 +935,10 @@ VkResult windows_read_sorted_physical_devices(struct loader_instance *inst, uint
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "Failed to create DXGI factory 6. Physical devices will not be sorted");
|
||||
goto out;
|
||||
}
|
||||
sorted_alloc = 16;
|
||||
*sorted_devices = loader_instance_heap_calloc(inst, sorted_alloc * sizeof(struct loader_phys_dev_per_icd),
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (*sorted_devices == NULL) {
|
||||
icd_phys_devs_array_size = 16;
|
||||
*icd_phys_devs_array = loader_instance_heap_calloc(inst, icd_phys_devs_array_size * sizeof(struct loader_icd_physical_devices),
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (*icd_phys_devs_array == NULL) {
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
@ -823,20 +962,19 @@ VkResult windows_read_sorted_physical_devices(struct loader_instance *inst, uint
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sorted_alloc <= i) {
|
||||
uint32_t old_size = sorted_alloc * sizeof(struct loader_phys_dev_per_icd);
|
||||
*sorted_devices =
|
||||
loader_instance_heap_realloc(inst, *sorted_devices, old_size, 2 * old_size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (*sorted_devices == NULL) {
|
||||
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;
|
||||
}
|
||||
sorted_alloc *= 2;
|
||||
icd_phys_devs_array_size *= 2;
|
||||
}
|
||||
struct loader_phys_dev_per_icd *sorted_array = *sorted_devices;
|
||||
sorted_array[*sorted_devices_count].device_count = 0;
|
||||
sorted_array[*sorted_devices_count].physical_devices = NULL;
|
||||
(*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++) {
|
||||
@ -845,52 +983,12 @@ VkResult windows_read_sorted_physical_devices(struct loader_instance *inst, uint
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t count = 0;
|
||||
VkResult vkres =
|
||||
icd_term->scanned_icd->EnumerateAdapterPhysicalDevices(icd_term->instance, description.AdapterLuid, &count, NULL);
|
||||
if (vkres == VK_ERROR_INCOMPATIBLE_DRIVER) {
|
||||
continue; // This driver doesn't support the adapter
|
||||
} else if (vkres == VK_ERROR_OUT_OF_HOST_MEMORY) {
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
res = enumerate_adapter_physical_devices(inst, icd_term, icd_idx, 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;
|
||||
} else if (vkres != VK_SUCCESS) {
|
||||
loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
|
||||
"Failed to convert DXGI adapter into Vulkan physical device with unexpected error code");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the actual physical devices
|
||||
if (0 != count) {
|
||||
do {
|
||||
sorted_array[*sorted_devices_count].physical_devices =
|
||||
loader_instance_heap_realloc(inst, sorted_array[*sorted_devices_count].physical_devices,
|
||||
sorted_array[*sorted_devices_count].device_count * sizeof(VkPhysicalDevice),
|
||||
count * sizeof(VkPhysicalDevice), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (sorted_array[*sorted_devices_count].physical_devices == NULL) {
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
break;
|
||||
}
|
||||
sorted_array[*sorted_devices_count].device_count = count;
|
||||
} while ((vkres = icd_term->scanned_icd->EnumerateAdapterPhysicalDevices(
|
||||
icd_term->instance, description.AdapterLuid, &count,
|
||||
sorted_array[*sorted_devices_count].physical_devices)) == VK_INCOMPLETE);
|
||||
}
|
||||
|
||||
if (vkres != VK_SUCCESS) {
|
||||
loader_instance_heap_free(inst, sorted_array[*sorted_devices_count].physical_devices);
|
||||
sorted_array[*sorted_devices_count].physical_devices = NULL;
|
||||
if (vkres == VK_ERROR_OUT_OF_HOST_MEMORY) {
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
} else {
|
||||
loader_log(inst, VULKAN_LOADER_WARN_BIT, 0, "Failed to convert DXGI adapter into Vulkan physical device");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
sorted_array[*sorted_devices_count].device_count = count;
|
||||
sorted_array[*sorted_devices_count].icd_index = icd_idx;
|
||||
sorted_array[*sorted_devices_count].icd_term = icd_term;
|
||||
(*sorted_devices_count)++;
|
||||
}
|
||||
|
||||
adapter->lpVtbl->Release(adapter);
|
||||
@ -898,13 +996,13 @@ VkResult windows_read_sorted_physical_devices(struct loader_instance *inst, uint
|
||||
|
||||
dxgi_factory->lpVtbl->Release(dxgi_factory);
|
||||
|
||||
sort_physical_devices_with_same_luid(inst, *icd_phys_devs_array_count, *icd_phys_devs_array);
|
||||
|
||||
out:
|
||||
if (*sorted_devices_count == 0 && *sorted_devices != NULL) {
|
||||
loader_instance_heap_free(inst, *sorted_devices);
|
||||
*sorted_devices = NULL;
|
||||
if (*icd_phys_devs_array_count == 0 && *icd_phys_devs_array != NULL) {
|
||||
loader_instance_heap_free(inst, *icd_phys_devs_array);
|
||||
*icd_phys_devs_array = NULL;
|
||||
}
|
||||
*sorted_devices_count = *sorted_devices_count;
|
||||
*sorted_devices = *sorted_devices;
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -923,7 +1021,7 @@ VkLoaderFeatureFlags windows_initialize_dxgi(void) {
|
||||
// Multiple groups could have devices out of the same sorted list, however, a single group's devices must all come
|
||||
// from the same sorted list.
|
||||
void windows_sort_devices_in_group(struct loader_instance *inst, struct VkPhysicalDeviceGroupProperties *group_props,
|
||||
struct loader_phys_dev_per_icd *icd_sorted_list) {
|
||||
struct loader_icd_physical_devices *icd_sorted_list) {
|
||||
uint32_t cur_index = 0;
|
||||
for (uint32_t dev = 0; dev < icd_sorted_list->device_count; ++dev) {
|
||||
for (uint32_t grp_dev = cur_index; grp_dev < group_props->physicalDeviceCount; ++grp_dev) {
|
||||
@ -948,7 +1046,7 @@ void windows_sort_devices_in_group(struct loader_instance *inst, struct VkPhysic
|
||||
VkResult windows_sort_physical_device_groups(struct loader_instance *inst, const uint32_t group_count,
|
||||
struct loader_physical_device_group_term *sorted_group_term,
|
||||
const uint32_t sorted_device_count,
|
||||
struct loader_phys_dev_per_icd *sorted_phys_dev_array) {
|
||||
struct loader_icd_physical_devices *sorted_phys_dev_array) {
|
||||
if (0 == group_count || NULL == sorted_group_term) {
|
||||
loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
|
||||
"windows_sort_physical_device_groups: Called with invalid information (Group count %d, Sorted Info %p)",
|
||||
@ -993,13 +1091,13 @@ char *windows_get_app_package_manifest_path(const struct loader_instance *inst)
|
||||
// These functions are only available on Windows 8 and above, load them dynamically for compatibility with Windows 7
|
||||
typedef LONG(WINAPI * PFN_GetPackagesByPackageFamily)(PCWSTR, UINT32 *, PWSTR *, UINT32 *, WCHAR *);
|
||||
PFN_GetPackagesByPackageFamily fpGetPackagesByPackageFamily =
|
||||
(PFN_GetPackagesByPackageFamily)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetPackagesByPackageFamily");
|
||||
(PFN_GetPackagesByPackageFamily)(void *)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetPackagesByPackageFamily");
|
||||
if (!fpGetPackagesByPackageFamily) {
|
||||
return NULL;
|
||||
}
|
||||
typedef LONG(WINAPI * PFN_GetPackagePathByFullName)(PCWSTR, UINT32 *, PWSTR);
|
||||
PFN_GetPackagePathByFullName fpGetPackagePathByFullName =
|
||||
(PFN_GetPackagePathByFullName)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetPackagePathByFullName");
|
||||
(PFN_GetPackagePathByFullName)(void *)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetPackagePathByFullName");
|
||||
if (!fpGetPackagePathByFullName) {
|
||||
return NULL;
|
||||
}
|
||||
@ -1013,7 +1111,7 @@ char *windows_get_app_package_manifest_path(const struct loader_instance *inst)
|
||||
if (ERROR_INSUFFICIENT_BUFFER != fpGetPackagesByPackageFamily(familyName, &numPackages, NULL, &bufferLength, NULL) ||
|
||||
numPackages == 0 || bufferLength == 0) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
|
||||
"windows_get_app_package_manifest_path: Failed to find mapping layers packages by family name\n");
|
||||
"windows_get_app_package_manifest_path: Failed to find mapping layers packages by family name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1022,13 +1120,13 @@ char *windows_get_app_package_manifest_path(const struct loader_instance *inst)
|
||||
PWSTR *packages = loader_instance_heap_alloc(inst, sizeof(PWSTR) * numPackages, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (!buffer || !packages) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"windows_get_app_package_manifest_path: Failed to allocate memory for package names\n");
|
||||
"windows_get_app_package_manifest_path: Failed to allocate memory for package names");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ERROR_SUCCESS != fpGetPackagesByPackageFamily(familyName, &numPackages, packages, &bufferLength, buffer)) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"windows_get_app_package_manifest_path: Failed to mapping layers package full names\n");
|
||||
"windows_get_app_package_manifest_path: Failed to mapping layers package full names");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -1038,20 +1136,20 @@ char *windows_get_app_package_manifest_path(const struct loader_instance *inst)
|
||||
if (ERROR_INSUFFICIENT_BUFFER != fpGetPackagePathByFullName(packages[0], &pathLength, NULL) || pathLength > MAX_PATH ||
|
||||
ERROR_SUCCESS != fpGetPackagePathByFullName(packages[0], &pathLength, path)) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"windows_get_app_package_manifest_path: Failed to get mapping layers package path\n");
|
||||
"windows_get_app_package_manifest_path: Failed to get mapping layers package path");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
int narrowPathLength = WideCharToMultiByte(CP_ACP, 0, path, -1, NULL, 0, NULL, NULL);
|
||||
if (narrowPathLength == 0) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"windows_get_app_package_manifest_path: Failed to convert path from wide to narrow\n");
|
||||
"windows_get_app_package_manifest_path: Failed to convert path from wide to narrow");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = loader_instance_heap_alloc(inst, narrowPathLength, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (!ret) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "windows_get_app_package_manifest_path: Failed to allocate path\n");
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "windows_get_app_package_manifest_path: Failed to allocate path");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -1063,4 +1161,99 @@ cleanup:
|
||||
loader_instance_heap_free(inst, packages);
|
||||
return ret;
|
||||
}
|
||||
|
||||
VkResult get_settings_path_if_exists_in_registry_key(const struct loader_instance *inst, char **out_path, HKEY key) {
|
||||
VkResult result = VK_ERROR_INITIALIZATION_FAILED;
|
||||
|
||||
char name[MAX_STRING_SIZE] = {0};
|
||||
DWORD name_size = sizeof(name);
|
||||
|
||||
*out_path = NULL;
|
||||
|
||||
LONG rtn_value = ERROR_SUCCESS;
|
||||
for (DWORD idx = 0; rtn_value == ERROR_SUCCESS; idx++) {
|
||||
DWORD value = 0;
|
||||
DWORD value_size = sizeof(value);
|
||||
rtn_value = RegEnumValue(key, idx, name, &name_size, NULL, NULL, (LPBYTE)&value, &value_size);
|
||||
|
||||
if (ERROR_SUCCESS != rtn_value) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t start_of_path_filename = 0;
|
||||
for (uint32_t last_char = name_size; last_char > 0; last_char--) {
|
||||
if (name[last_char] == '\\') {
|
||||
start_of_path_filename = last_char + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
*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;
|
||||
}
|
||||
loader_strncpy(*out_path, name_size + 1, name, name_size);
|
||||
(*out_path)[name_size] = '\0';
|
||||
result = VK_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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;
|
||||
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
|
||||
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (NULL != key) {
|
||||
RegCloseKey(key);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
@ -97,17 +97,17 @@ VkResult windows_read_manifest_from_d3d_adapters(const struct loader_instance *i
|
||||
// Look for data files in the registry.
|
||||
VkResult windows_read_data_files_in_registry(const struct loader_instance *inst, enum loader_data_files_type data_file_type,
|
||||
bool warn_if_not_present, char *registry_location,
|
||||
struct loader_data_files *out_files);
|
||||
struct loader_string_list *out_files);
|
||||
|
||||
// This function allocates an array in sorted_devices which must be freed by the caller if not null
|
||||
VkResult windows_read_sorted_physical_devices(struct loader_instance *inst, uint32_t *sorted_devices_count,
|
||||
struct loader_phys_dev_per_icd **sorted_devices);
|
||||
VkResult windows_read_sorted_physical_devices(struct loader_instance *inst, uint32_t *icd_phys_devs_array_count,
|
||||
struct loader_icd_physical_devices **icd_phys_devs_array);
|
||||
|
||||
// This function sorts an array in physical device groups based on the sorted physical device information
|
||||
VkResult windows_sort_physical_device_groups(struct loader_instance *inst, const uint32_t group_count,
|
||||
struct loader_physical_device_group_term *sorted_group_term,
|
||||
const uint32_t sorted_device_count,
|
||||
struct loader_phys_dev_per_icd *sorted_phys_dev_array);
|
||||
struct loader_icd_physical_devices *sorted_phys_dev_array);
|
||||
|
||||
// Creates a DXGI factory
|
||||
// Returns VkLoaderFeatureFlags containing VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING if successful, otherwise 0
|
||||
@ -116,4 +116,10 @@ VkLoaderFeatureFlags windows_initialize_dxgi(void);
|
||||
// Retrieve a path to an installed app package that contains Vulkan manifests.
|
||||
// When done using the returned string, the caller should free the pointer.
|
||||
char *windows_get_app_package_manifest_path(const struct loader_instance *inst);
|
||||
|
||||
// Gets the path to the loader settings file, if it exists. If it doesn't exists, writes NULL to out_path.
|
||||
// The path is located through the registry as an entry in HKEY_CURRENT_USER/SOFTWARE/Khronos/Vulkan/LoaderSettings
|
||||
// and if nothing is there, will try to look in HKEY_LOCAL_MACHINE/SOFTWARE/Khronos/Vulkan/LoaderSettings.
|
||||
// If running with elevated privileges, this function only looks in HKEY_LOCAL_MACHINE.
|
||||
VkResult windows_get_loader_settings_file_path(const struct loader_instance *inst, char **out_path);
|
||||
#endif // WIN32
|
||||
|
177
loader/log.c
177
loader/log.c
@ -32,14 +32,17 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "debug_utils.h"
|
||||
#include "get_environment.h"
|
||||
#include "loader_common.h"
|
||||
#include "loader_environment.h"
|
||||
#include "settings.h"
|
||||
#include "vk_loader_platform.h"
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
#include "loader_hilog.h"
|
||||
#endif
|
||||
|
||||
uint32_t g_loader_debug = ~0u;
|
||||
|
||||
void loader_debug_init(void) {
|
||||
void loader_init_global_debug_level(void) {
|
||||
char *env, *orig;
|
||||
|
||||
if (g_loader_debug > 0) return;
|
||||
@ -86,18 +89,15 @@ void loader_debug_init(void) {
|
||||
loader_free_getenv(orig, NULL);
|
||||
}
|
||||
|
||||
uint32_t loader_get_debug_level(void) { return g_loader_debug; }
|
||||
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, ...) {
|
||||
char msg[512];
|
||||
char cmd_line_msg[512];
|
||||
size_t cmd_line_size = sizeof(cmd_line_msg);
|
||||
size_t num_used = 0;
|
||||
va_list ap;
|
||||
int ret;
|
||||
(void)msg_code;
|
||||
char msg[512] = {0};
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
ret = vsnprintf(msg, sizeof(msg), format, ap);
|
||||
int ret = vsnprintf(msg, sizeof(msg), format, ap);
|
||||
if ((ret >= (int)sizeof(msg)) || ret < 0) {
|
||||
msg[sizeof(msg) - 1] = '\0';
|
||||
}
|
||||
@ -105,9 +105,9 @@ void loader_log(const struct loader_instance *inst, VkFlags msg_type, int32_t ms
|
||||
|
||||
if (inst) {
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT severity = 0;
|
||||
VkDebugUtilsMessageTypeFlagsEXT type;
|
||||
VkDebugUtilsMessengerCallbackDataEXT callback_data;
|
||||
VkDebugUtilsObjectNameInfoEXT object_name;
|
||||
VkDebugUtilsMessageTypeFlagsEXT type = 0;
|
||||
VkDebugUtilsMessengerCallbackDataEXT callback_data = {0};
|
||||
VkDebugUtilsObjectNameInfoEXT object_name = {0};
|
||||
|
||||
if ((msg_type & VULKAN_LOADER_INFO_BIT) != 0) {
|
||||
severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
|
||||
@ -133,106 +133,107 @@ void loader_log(const struct loader_instance *inst, VkFlags msg_type, int32_t ms
|
||||
}
|
||||
|
||||
callback_data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
|
||||
callback_data.pNext = NULL;
|
||||
callback_data.flags = 0;
|
||||
callback_data.pMessageIdName = "Loader Message";
|
||||
callback_data.messageIdNumber = 0;
|
||||
callback_data.pMessage = msg;
|
||||
callback_data.queueLabelCount = 0;
|
||||
callback_data.pQueueLabels = NULL;
|
||||
callback_data.cmdBufLabelCount = 0;
|
||||
callback_data.pCmdBufLabels = NULL;
|
||||
callback_data.objectCount = 1;
|
||||
callback_data.pObjects = &object_name;
|
||||
object_name.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
|
||||
object_name.pNext = NULL;
|
||||
object_name.objectType = VK_OBJECT_TYPE_INSTANCE;
|
||||
object_name.objectHandle = (uint64_t)(uintptr_t)inst;
|
||||
object_name.pObjectName = NULL;
|
||||
|
||||
util_SubmitDebugUtilsMessageEXT(inst, severity, type, &callback_data);
|
||||
}
|
||||
|
||||
uint32_t filtered_msg_type = (msg_type & g_loader_debug);
|
||||
if (0 == filtered_msg_type) {
|
||||
return;
|
||||
// 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;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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];
|
||||
size_t cmd_line_size = sizeof(cmd_line_msg);
|
||||
size_t num_used = 0;
|
||||
|
||||
cmd_line_msg[0] = '\0';
|
||||
cmd_line_size -= 1;
|
||||
num_used = 1;
|
||||
|
||||
// Helper macro which strncat's the given string literal, then updates num_used & cmd_line_end
|
||||
// Assumes that we haven't used the entire buffer - must manually check this when adding new filter types
|
||||
// We concat at the end of cmd_line_msg, so that strncat isn't a victim of Schlemiel the Painter
|
||||
// We write to the end - 1 of cmd_line_msg, as the end is actually a null terminator
|
||||
#define STRNCAT_TO_BUFFER(string_literal_to_cat) \
|
||||
loader_strncat(cmd_line_msg + num_used, cmd_line_size - num_used, string_literal_to_cat, sizeof(string_literal_to_cat)); \
|
||||
num_used += sizeof(string_literal_to_cat) - 1; // subtract one to remove the null terminator in the string literal
|
||||
|
||||
if ((msg_type & VULKAN_LOADER_ERROR_BIT) != 0) {
|
||||
strncat(cmd_line_msg, "ERROR", cmd_line_size - num_used);
|
||||
num_used += 5;
|
||||
STRNCAT_TO_BUFFER("ERROR");
|
||||
} else if ((msg_type & VULKAN_LOADER_WARN_BIT) != 0) {
|
||||
strncat(cmd_line_msg, "WARNING", cmd_line_size - num_used);
|
||||
num_used += 7;
|
||||
STRNCAT_TO_BUFFER("WARNING");
|
||||
} else if ((msg_type & VULKAN_LOADER_INFO_BIT) != 0) {
|
||||
strncat(cmd_line_msg, "INFO", cmd_line_size - num_used);
|
||||
num_used += 4;
|
||||
STRNCAT_TO_BUFFER("INFO");
|
||||
} else if ((msg_type & VULKAN_LOADER_DEBUG_BIT) != 0) {
|
||||
strncat(cmd_line_msg, "DEBUG", cmd_line_size - num_used);
|
||||
num_used += 5;
|
||||
}
|
||||
// For the remaining messages, we only want to add any tags that are
|
||||
// explicitly enabled by the tools.
|
||||
if ((filtered_msg_type & VULKAN_LOADER_PERF_BIT) != 0) {
|
||||
if (num_used > 1) {
|
||||
strncat(cmd_line_msg, " | ", cmd_line_size - num_used);
|
||||
num_used += 3;
|
||||
}
|
||||
strncat(cmd_line_msg, "PERF", cmd_line_size - num_used);
|
||||
num_used += 4;
|
||||
}
|
||||
if ((filtered_msg_type & VULKAN_LOADER_DRIVER_BIT) != 0) {
|
||||
if (num_used > 1) {
|
||||
strncat(cmd_line_msg, " | ", cmd_line_size - num_used);
|
||||
num_used += 3;
|
||||
}
|
||||
strncat(cmd_line_msg, "DRIVER", cmd_line_size - num_used);
|
||||
num_used += 6;
|
||||
}
|
||||
if ((filtered_msg_type & VULKAN_LOADER_LAYER_BIT) != 0) {
|
||||
if (num_used > 1) {
|
||||
strncat(cmd_line_msg, " | ", cmd_line_size - num_used);
|
||||
num_used += 3;
|
||||
}
|
||||
strncat(cmd_line_msg, "LAYER", cmd_line_size - num_used);
|
||||
num_used += 5;
|
||||
}
|
||||
// Add any preceeding spaces so we can have clean output
|
||||
if (num_used > 1) {
|
||||
strncat(cmd_line_msg, ": ", cmd_line_size - num_used);
|
||||
num_used += 2;
|
||||
}
|
||||
while (num_used < 19) {
|
||||
strncat(cmd_line_msg, " ", cmd_line_size - num_used);
|
||||
num_used++;
|
||||
STRNCAT_TO_BUFFER("DEBUG");
|
||||
}
|
||||
|
||||
size_t available_space = cmd_line_size - num_used;
|
||||
if (available_space > 0) {
|
||||
// If the message is too long, trim it down
|
||||
if (strlen(msg) > available_space) {
|
||||
msg[available_space - 1] = '\0';
|
||||
if ((msg_type & VULKAN_LOADER_PERF_BIT) != 0) {
|
||||
if (num_used > 1) {
|
||||
STRNCAT_TO_BUFFER(" | ");
|
||||
}
|
||||
strncat(cmd_line_msg, msg, cmd_line_size);
|
||||
STRNCAT_TO_BUFFER("PERF");
|
||||
}
|
||||
if ((msg_type & VULKAN_LOADER_DRIVER_BIT) != 0) {
|
||||
if (num_used > 1) {
|
||||
STRNCAT_TO_BUFFER(" | ");
|
||||
}
|
||||
STRNCAT_TO_BUFFER("DRIVER");
|
||||
}
|
||||
if ((msg_type & VULKAN_LOADER_LAYER_BIT) != 0) {
|
||||
if (num_used > 1) {
|
||||
STRNCAT_TO_BUFFER(" | ");
|
||||
}
|
||||
STRNCAT_TO_BUFFER("LAYER");
|
||||
}
|
||||
|
||||
// Add a ": " to separate the filters from the message
|
||||
STRNCAT_TO_BUFFER(": ");
|
||||
#undef STRNCAT_TO_BUFFER
|
||||
|
||||
// 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;
|
||||
}
|
||||
// Assert that we didn't write more than what is available in cmd_line_msg
|
||||
assert(cmd_line_size > num_used);
|
||||
|
||||
#if !defined (__OHOS__)
|
||||
fputs(cmd_line_msg, stderr);
|
||||
fputs(msg, stderr);
|
||||
fputc('\n', stderr);
|
||||
#endif
|
||||
#if defined(WIN32)
|
||||
OutputDebugString(cmd_line_msg);
|
||||
OutputDebugString("\n");
|
||||
OutputDebugString(cmd_line_msg);
|
||||
OutputDebugString(msg);
|
||||
OutputDebugString("\n");
|
||||
#endif
|
||||
|
||||
#if defined(VK_USE_PLATFORM_OHOS)
|
||||
OpenHarmonyLog(msg_type, cmd_line_msg);
|
||||
#if defined(__OHOS__)
|
||||
char result[512 + 64];
|
||||
strcpy(result, cmd_line_msg);
|
||||
strcat(result, msg);
|
||||
OpenHarmonyLog(msg_type, result);
|
||||
#endif
|
||||
|
||||
fputs(cmd_line_msg, stderr);
|
||||
fputc('\n', stderr);
|
||||
} else {
|
||||
// Shouldn't get here, but check to make sure if we've already overrun
|
||||
// the string boundary
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void loader_log_asm_function_not_supported(const struct loader_instance *inst, VkFlags msg_type, int32_t msg_code,
|
||||
const char *func_name) {
|
||||
loader_log(inst, msg_type, msg_code, "Function %s not supported for this physical device", func_name);
|
||||
}
|
||||
|
33
loader/log.h
33
loader/log.h
@ -26,7 +26,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "loader_common.h"
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "vulkan/vulkan_core.h"
|
||||
|
||||
struct loader_instance;
|
||||
|
||||
enum vulkan_loader_debug_flags {
|
||||
VULKAN_LOADER_INFO_BIT = 0x01,
|
||||
@ -37,15 +44,31 @@ enum vulkan_loader_debug_flags {
|
||||
VULKAN_LOADER_LAYER_BIT = 0x20,
|
||||
VULKAN_LOADER_DRIVER_BIT = 0x40,
|
||||
VULKAN_LOADER_VALIDATION_BIT = 0x80,
|
||||
VULKAN_LOADER_FATAL_ERROR_BIT = 0x100, // only forces the output to be printed to stderr, has no other effect
|
||||
};
|
||||
|
||||
// Checks for the environment variable VK_LOADER_DEBUG and sets up the current debug level accordingly
|
||||
// This should be called before any Vulkan API calls, eg in the initialization of the .dll or .so
|
||||
void loader_debug_init(void);
|
||||
void loader_init_global_debug_level(void);
|
||||
|
||||
// Returns a bitmask that indicates the current flags that should be output
|
||||
uint32_t loader_get_debug_level(void);
|
||||
// Sets the global debug level - used by global settings files
|
||||
void loader_set_global_debug_level(uint32_t new_loader_debug);
|
||||
|
||||
// The asm declaration prevents name mangling which is necessary for macOS
|
||||
#if defined(MODIFY_UNKNOWN_FUNCTION_DECLS)
|
||||
#define ASM_NAME(name) __asm(name)
|
||||
#else
|
||||
#define ASM_NAME(name)
|
||||
#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, ...);
|
||||
void 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
|
||||
void loader_log_asm_function_not_supported(const struct loader_instance *inst, VkFlags msg_type, int32_t msg_code,
|
||||
const char *func_name) ASM_NAME("loader_log_asm_function_not_supported");
|
||||
|
||||
#undef ASM_NAME
|
||||
|
File diff suppressed because it is too large
Load Diff
807
loader/settings.c
Normal file
807
loader/settings.c
Normal file
@ -0,0 +1,807 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2023 The Khronos Group Inc.
|
||||
* Copyright (c) 2023 Valve Corporation
|
||||
* Copyright (c) 2023 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: Charles Giessen <charles@lunarg.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
#include "allocation.h"
|
||||
#include "cJSON.h"
|
||||
#include "loader.h"
|
||||
#include "loader_environment.h"
|
||||
#include "loader_windows.h"
|
||||
#include "log.h"
|
||||
#include "stack_allocation.h"
|
||||
#include "vk_loader_platform.h"
|
||||
|
||||
loader_platform_thread_mutex global_loader_settings_lock;
|
||||
loader_settings global_loader_settings;
|
||||
|
||||
void free_layer_configuration(const struct loader_instance* inst, loader_settings_layer_configuration* layer_configuration) {
|
||||
loader_instance_heap_free(inst, layer_configuration->name);
|
||||
loader_instance_heap_free(inst, layer_configuration->path);
|
||||
memset(layer_configuration, 0, sizeof(loader_settings_layer_configuration));
|
||||
}
|
||||
|
||||
void free_loader_settings(const struct loader_instance* inst, loader_settings* settings) {
|
||||
if (NULL != settings->layer_configurations) {
|
||||
for (uint32_t i = 0; i < settings->layer_configuration_count; i++) {
|
||||
free_layer_configuration(inst, &settings->layer_configurations[i]);
|
||||
}
|
||||
}
|
||||
loader_instance_heap_free(inst, settings->layer_configurations);
|
||||
loader_instance_heap_free(inst, settings->settings_file_path);
|
||||
memset(settings, 0, sizeof(loader_settings));
|
||||
}
|
||||
|
||||
loader_settings_layer_control parse_control_string(char* control_string) {
|
||||
loader_settings_layer_control layer_control = LOADER_SETTINGS_LAYER_CONTROL_DEFAULT;
|
||||
if (strcmp(control_string, "auto") == 0)
|
||||
layer_control = LOADER_SETTINGS_LAYER_CONTROL_DEFAULT;
|
||||
else if (strcmp(control_string, "on") == 0)
|
||||
layer_control = LOADER_SETTINGS_LAYER_CONTROL_ON;
|
||||
else if (strcmp(control_string, "off") == 0)
|
||||
layer_control = LOADER_SETTINGS_LAYER_CONTROL_OFF;
|
||||
else if (strcmp(control_string, "unordered_layer_location") == 0)
|
||||
layer_control = LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION;
|
||||
return layer_control;
|
||||
}
|
||||
|
||||
const char* loader_settings_layer_control_to_string(loader_settings_layer_control control) {
|
||||
switch (control) {
|
||||
case (LOADER_SETTINGS_LAYER_CONTROL_DEFAULT):
|
||||
return "auto";
|
||||
case (LOADER_SETTINGS_LAYER_CONTROL_ON):
|
||||
return "on";
|
||||
case (LOADER_SETTINGS_LAYER_CONTROL_OFF):
|
||||
return "off";
|
||||
case (LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION):
|
||||
return "unordered_layer_location";
|
||||
default:
|
||||
return "UNKNOWN_LAYER_CONTROl";
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t parse_log_filters_from_strings(struct loader_string_list* log_filters) {
|
||||
uint32_t filters = 0;
|
||||
for (uint32_t i = 0; i < log_filters->count; i++) {
|
||||
if (strcmp(log_filters->list[i], "all") == 0)
|
||||
filters |= VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_PERF_BIT | VULKAN_LOADER_ERROR_BIT |
|
||||
VULKAN_LOADER_DEBUG_BIT | VULKAN_LOADER_LAYER_BIT | VULKAN_LOADER_DRIVER_BIT | VULKAN_LOADER_VALIDATION_BIT;
|
||||
else if (strcmp(log_filters->list[i], "info") == 0)
|
||||
filters |= VULKAN_LOADER_INFO_BIT;
|
||||
else if (strcmp(log_filters->list[i], "warn") == 0)
|
||||
filters |= VULKAN_LOADER_WARN_BIT;
|
||||
else if (strcmp(log_filters->list[i], "perf") == 0)
|
||||
filters |= VULKAN_LOADER_PERF_BIT;
|
||||
else if (strcmp(log_filters->list[i], "error") == 0)
|
||||
filters |= VULKAN_LOADER_ERROR_BIT;
|
||||
else if (strcmp(log_filters->list[i], "debug") == 0)
|
||||
filters |= VULKAN_LOADER_DEBUG_BIT;
|
||||
else if (strcmp(log_filters->list[i], "layer") == 0)
|
||||
filters |= VULKAN_LOADER_LAYER_BIT;
|
||||
else if (strcmp(log_filters->list[i], "driver") == 0)
|
||||
filters |= VULKAN_LOADER_DRIVER_BIT;
|
||||
else if (strcmp(log_filters->list[i], "validation") == 0)
|
||||
filters |= VULKAN_LOADER_VALIDATION_BIT;
|
||||
}
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
bool enable = false;
|
||||
if (strcmp(str, "enabled") == 0) {
|
||||
enable = true;
|
||||
}
|
||||
loader_instance_heap_free(inst, str);
|
||||
return enable;
|
||||
}
|
||||
|
||||
VkResult parse_layer_configuration(const struct loader_instance* inst, cJSON* layer_configuration_json,
|
||||
loader_settings_layer_configuration* layer_configuration) {
|
||||
char* control_string = NULL;
|
||||
VkResult res = loader_parse_json_string(layer_configuration_json, "control", &control_string);
|
||||
if (res != VK_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
layer_configuration->control = parse_control_string(control_string);
|
||||
loader_instance_heap_free(inst, control_string);
|
||||
|
||||
// If that is the only value - do no further parsing
|
||||
if (layer_configuration->control == LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
res = loader_parse_json_string(layer_configuration_json, "name", &(layer_configuration->name));
|
||||
if (res != VK_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
res = loader_parse_json_string(layer_configuration_json, "path", &(layer_configuration->path));
|
||||
if (res != VK_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
cJSON* treat_as_implicit_manifest = loader_cJSON_GetObjectItem(layer_configuration_json, "treat_as_implicit_manifest");
|
||||
if (treat_as_implicit_manifest && treat_as_implicit_manifest->type == cJSON_True) {
|
||||
layer_configuration->treat_as_implicit_manifest = true;
|
||||
}
|
||||
out:
|
||||
if (VK_SUCCESS != res) {
|
||||
free_layer_configuration(inst, layer_configuration);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
VkResult parse_layer_configurations(const struct loader_instance* inst, cJSON* settings_object, loader_settings* loader_settings) {
|
||||
VkResult res = VK_SUCCESS;
|
||||
|
||||
cJSON* layer_configurations = loader_cJSON_GetObjectItem(settings_object, "layers");
|
||||
if (NULL == layer_configurations) {
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
uint32_t layer_configurations_count = loader_cJSON_GetArraySize(layer_configurations);
|
||||
if (layer_configurations_count == 0) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
loader_settings->layer_configuration_count = layer_configurations_count;
|
||||
|
||||
loader_settings->layer_configurations = loader_instance_heap_calloc(
|
||||
inst, sizeof(loader_settings_layer_configuration) * layer_configurations_count, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
||||
if (NULL == loader_settings->layer_configurations) {
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < layer_configurations_count; i++) {
|
||||
cJSON* layer = loader_cJSON_GetArrayItem(layer_configurations, i);
|
||||
if (NULL == layer) {
|
||||
res = VK_ERROR_INITIALIZATION_FAILED;
|
||||
goto out;
|
||||
}
|
||||
res = parse_layer_configuration(inst, layer, &(loader_settings->layer_configurations[i]));
|
||||
if (VK_SUCCESS != res) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
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]));
|
||||
}
|
||||
loader_settings->layer_configuration_count = 0;
|
||||
loader_instance_heap_free(inst, loader_settings->layer_configurations);
|
||||
loader_settings->layer_configurations = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
VkResult check_if_settings_path_exists(const struct loader_instance* inst, char* base, char* suffix, char** settings_file_path) {
|
||||
if (NULL == base || NULL == suffix) {
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
size_t base_len = strlen(base);
|
||||
size_t suffix_len = strlen(suffix);
|
||||
size_t path_len = base_len + suffix_len + 1;
|
||||
*settings_file_path = loader_instance_heap_calloc(inst, path_len, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (NULL == *settings_file_path) {
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
loader_strncpy(*settings_file_path, path_len, base, base_len);
|
||||
loader_strncat(*settings_file_path, path_len, suffix, suffix_len);
|
||||
|
||||
if (!loader_platform_file_exists(*settings_file_path)) {
|
||||
loader_instance_heap_free(inst, *settings_file_path);
|
||||
*settings_file_path = NULL;
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
VkResult get_unix_settings_path(const struct loader_instance* inst, char** settings_file_path) {
|
||||
VkResult res =
|
||||
check_if_settings_path_exists(inst, loader_secure_getenv("HOME", inst),
|
||||
"/.local/share/vulkan/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path);
|
||||
if (res == VK_SUCCESS) {
|
||||
return res;
|
||||
}
|
||||
// If HOME isn't set, fallback to XDG_DATA_HOME
|
||||
res = check_if_settings_path_exists(inst, loader_secure_getenv("XDG_DATA_HOME", inst),
|
||||
"/vulkan/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path);
|
||||
if (res == VK_SUCCESS) {
|
||||
return res;
|
||||
}
|
||||
// if XDG_DATA_HOME isn't set, fallback to /etc.
|
||||
// note that the settings_fil_path_suffix stays the same since its the same layout as for XDG_DATA_HOME
|
||||
return check_if_settings_path_exists(inst, "/etc", "/vulkan/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME,
|
||||
settings_file_path);
|
||||
}
|
||||
|
||||
bool check_if_settings_are_equal(loader_settings* a, loader_settings* b) {
|
||||
// If either pointer is null, return true
|
||||
if (NULL == a || NULL == b) return false;
|
||||
bool are_equal = true;
|
||||
are_equal &= a->settings_active == b->settings_active;
|
||||
are_equal &= a->has_unordered_layer_location == b->has_unordered_layer_location;
|
||||
are_equal &= a->debug_level == b->debug_level;
|
||||
are_equal &= a->layer_configuration_count == b->layer_configuration_count;
|
||||
if (!are_equal) return false;
|
||||
for (uint32_t i = 0; i < a->layer_configuration_count && i < b->layer_configuration_count; i++) {
|
||||
if (a->layer_configurations[i].name && b->layer_configurations[i].name) {
|
||||
are_equal &= 0 == strcmp(a->layer_configurations[i].name, b->layer_configurations[i].name);
|
||||
} else {
|
||||
are_equal = false;
|
||||
}
|
||||
if (a->layer_configurations[i].path && b->layer_configurations[i].path) {
|
||||
are_equal &= 0 == strcmp(a->layer_configurations[i].path, b->layer_configurations[i].path);
|
||||
} else {
|
||||
are_equal = false;
|
||||
}
|
||||
are_equal &= a->layer_configurations[i].control == b->layer_configurations[i].control;
|
||||
}
|
||||
return are_equal;
|
||||
}
|
||||
|
||||
void log_settings(const struct loader_instance* inst, loader_settings* settings) {
|
||||
if (settings == NULL) {
|
||||
return;
|
||||
}
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "Using layer configurations found in loader settings from %s",
|
||||
settings->settings_file_path);
|
||||
|
||||
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, "Control: %s",
|
||||
loader_settings_layer_control_to_string(settings->layer_configurations[i].control));
|
||||
}
|
||||
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "---------------------------------");
|
||||
}
|
||||
|
||||
// Loads the vk_loader_settings.json file
|
||||
// Returns VK_SUCCESS if it was found & was successfully parsed. Otherwise, it returns VK_ERROR_INITIALIZATION_FAILED if it
|
||||
// wasn't found or failed to parse, and returns VK_ERROR_OUT_OF_HOST_MEMORY if it was unable to allocate enough memory.
|
||||
VkResult get_loader_settings(const struct loader_instance* inst, loader_settings* loader_settings) {
|
||||
VkResult res = VK_SUCCESS;
|
||||
cJSON* json = NULL;
|
||||
char* file_format_version_string = NULL;
|
||||
char* settings_file_path = NULL;
|
||||
#if defined(WIN32)
|
||||
res = windows_get_loader_settings_file_path(inst, &settings_file_path);
|
||||
if (res != VK_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
#elif COMMON_UNIX_PLATFORMS
|
||||
res = get_unix_settings_path(inst, &settings_file_path);
|
||||
if (res != VK_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
#warning "Unsupported platform - must specify platform specific location for vk_loader_settings.json"
|
||||
#endif
|
||||
|
||||
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) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
res = loader_parse_json_string(json, "file_format_version", &file_format_version_string);
|
||||
if (res != VK_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
uint32_t settings_array_count = 0;
|
||||
bool has_multi_setting_file = false;
|
||||
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);
|
||||
} else if (NULL != single_settings_object) {
|
||||
settings_array_count = 1;
|
||||
}
|
||||
|
||||
// Corresponds to the settings object that has no app keys
|
||||
int global_settings_index = -1;
|
||||
// Corresponds to the settings object which has a matching app key
|
||||
int index_to_use = -1;
|
||||
|
||||
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* app_keys = loader_cJSON_GetObjectItem(single_settings_object, "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
|
||||
}
|
||||
continue;
|
||||
} else if (valid_exe_path) {
|
||||
int app_key_count = loader_cJSON_GetArraySize(app_keys);
|
||||
if (app_key_count == 0) {
|
||||
continue; // empty array
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No app specific settings match - either use global settings or exit
|
||||
if (index_to_use == -1) {
|
||||
if (global_settings_index == -1) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// optional
|
||||
cJSON* stderr_filter = loader_cJSON_GetObjectItem(single_settings_object, "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);
|
||||
if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
|
||||
goto out;
|
||||
}
|
||||
loader_settings->debug_level = parse_log_filters_from_strings(&stderr_log);
|
||||
free_string_list(inst, &stderr_log);
|
||||
}
|
||||
|
||||
// optional
|
||||
cJSON* logs_to_use = loader_cJSON_GetObjectItem(single_settings_object, "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);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res = parse_layer_configurations(inst, single_settings_object, loader_settings);
|
||||
if (res != VK_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Determine if there exists a layer configuration indicating where to put layers not contained in the settings file
|
||||
// LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION
|
||||
for (uint32_t i = 0; i < loader_settings->layer_configuration_count; i++) {
|
||||
if (loader_settings->layer_configurations[i].control == LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION) {
|
||||
loader_settings->has_unordered_layer_location = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
loader_settings->settings_file_path = settings_file_path;
|
||||
settings_file_path = NULL;
|
||||
loader_settings->settings_active = true;
|
||||
out:
|
||||
if (NULL != json) {
|
||||
loader_cJSON_Delete(json);
|
||||
}
|
||||
|
||||
loader_instance_heap_free(inst, settings_file_path);
|
||||
|
||||
loader_instance_heap_free(inst, file_format_version_string);
|
||||
return res;
|
||||
}
|
||||
|
||||
VkResult update_global_loader_settings(void) {
|
||||
loader_settings settings = {0};
|
||||
VkResult res = get_loader_settings(NULL, &settings);
|
||||
loader_platform_thread_lock_mutex(&global_loader_settings_lock);
|
||||
|
||||
free_loader_settings(NULL, &global_loader_settings);
|
||||
if (res == VK_SUCCESS) {
|
||||
if (!check_if_settings_are_equal(&settings, &global_loader_settings)) {
|
||||
log_settings(NULL, &settings);
|
||||
}
|
||||
|
||||
memcpy(&global_loader_settings, &settings, sizeof(loader_settings));
|
||||
if (global_loader_settings.settings_active) {
|
||||
loader_set_global_debug_level(global_loader_settings.debug_level);
|
||||
}
|
||||
}
|
||||
loader_platform_thread_unlock_mutex(&global_loader_settings_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
void init_global_loader_settings(void) {
|
||||
loader_platform_thread_create_mutex(&global_loader_settings_lock);
|
||||
// Free out the global settings in case the process was loaded & unloaded
|
||||
free_loader_settings(NULL, &global_loader_settings);
|
||||
}
|
||||
void teardown_global_loader_settings(void) {
|
||||
free_loader_settings(NULL, &global_loader_settings);
|
||||
loader_platform_thread_delete_mutex(&global_loader_settings_lock);
|
||||
}
|
||||
|
||||
bool should_skip_logging_global_messages(VkFlags msg_type) {
|
||||
loader_platform_thread_lock_mutex(&global_loader_settings_lock);
|
||||
bool should_skip = global_loader_settings.settings_active && 0 != (msg_type & global_loader_settings.debug_level);
|
||||
loader_platform_thread_unlock_mutex(&global_loader_settings_lock);
|
||||
return should_skip;
|
||||
}
|
||||
|
||||
// Use this function to get the correct settings to use based on the context
|
||||
// If inst is NULL - use the global settings and lock the mutex
|
||||
// Else return the settings local to the instance - but do nto lock the mutex
|
||||
const loader_settings* get_current_settings_and_lock(const struct loader_instance* inst) {
|
||||
if (inst) {
|
||||
return &inst->settings;
|
||||
}
|
||||
loader_platform_thread_lock_mutex(&global_loader_settings_lock);
|
||||
return &global_loader_settings;
|
||||
}
|
||||
// Release the global settings lock if we are using the global settings - aka if inst is NULL
|
||||
void release_current_settings_lock(const struct loader_instance* inst) {
|
||||
if (inst == NULL) {
|
||||
loader_platform_thread_unlock_mutex(&global_loader_settings_lock);
|
||||
}
|
||||
}
|
||||
|
||||
VkResult get_settings_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
|
||||
bool* should_search_for_other_layers) {
|
||||
VkResult res = VK_SUCCESS;
|
||||
*should_search_for_other_layers = true; // default to true
|
||||
|
||||
const loader_settings* settings = get_current_settings_and_lock(inst);
|
||||
|
||||
if (NULL == settings || !settings->settings_active) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Assume the list doesn't contain LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION at first
|
||||
*should_search_for_other_layers = false;
|
||||
|
||||
for (uint32_t i = 0; i < settings->layer_configuration_count; i++) {
|
||||
loader_settings_layer_configuration* layer_config = &settings->layer_configurations[i];
|
||||
|
||||
// If we encountered a layer that should be forced off, we add it to the settings_layers list but only
|
||||
// with the data required to compare it with layers not in the settings file (aka name and manifest path)
|
||||
if (layer_config->control == LOADER_SETTINGS_LAYER_CONTROL_OFF) {
|
||||
struct loader_layer_properties props = {0};
|
||||
props.settings_control_value = LOADER_SETTINGS_LAYER_CONTROL_OFF;
|
||||
loader_strncpy(props.info.layerName, VK_MAX_EXTENSION_NAME_SIZE, layer_config->name, VK_MAX_EXTENSION_NAME_SIZE);
|
||||
props.info.layerName[VK_MAX_EXTENSION_NAME_SIZE - 1] = '\0';
|
||||
res = loader_copy_to_new_str(inst, layer_config->path, &props.manifest_file_name);
|
||||
if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
|
||||
goto out;
|
||||
}
|
||||
res = loader_append_layer_property(inst, settings_layers, &props);
|
||||
if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
|
||||
loader_free_layer_properties(inst, &props);
|
||||
goto out;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// The special layer location that indicates where unordered layers should go only should have the
|
||||
// settings_control_value set - everything else should be NULL
|
||||
if (layer_config->control == LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION) {
|
||||
struct loader_layer_properties props = {0};
|
||||
props.settings_control_value = LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION;
|
||||
res = loader_append_layer_property(inst, settings_layers, &props);
|
||||
if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
|
||||
loader_free_layer_properties(inst, &props);
|
||||
goto out;
|
||||
}
|
||||
*should_search_for_other_layers = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layer_config->path == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cJSON* json = NULL;
|
||||
VkResult local_res = loader_get_json(inst, layer_config->path, &json);
|
||||
if (VK_ERROR_OUT_OF_HOST_MEMORY == local_res) {
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
} else if (VK_SUCCESS != local_res || NULL == json) {
|
||||
continue;
|
||||
}
|
||||
|
||||
local_res =
|
||||
loader_add_layer_properties(inst, settings_layers, json, layer_config->treat_as_implicit_manifest, layer_config->path);
|
||||
loader_cJSON_Delete(json);
|
||||
|
||||
// If the error is anything other than out of memory we still want to try to load the other layers
|
||||
if (VK_ERROR_OUT_OF_HOST_MEMORY == local_res) {
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
struct loader_layer_properties* newly_added_layer = &settings_layers->list[settings_layers->count - 1];
|
||||
newly_added_layer->settings_control_value = layer_config->control;
|
||||
// If the manifest file found has a name that differs from the one in the settings, remove this layer from consideration
|
||||
bool should_remove = false;
|
||||
if (strncmp(newly_added_layer->info.layerName, layer_config->name, VK_MAX_EXTENSION_NAME_SIZE) != 0) {
|
||||
should_remove = true;
|
||||
loader_remove_layer_in_list(inst, settings_layers, settings_layers->count - 1);
|
||||
}
|
||||
// Make sure the layer isn't already in the list
|
||||
for (uint32_t j = 0; settings_layers->count > 0 && j < settings_layers->count - 1; j++) {
|
||||
if (0 ==
|
||||
strncmp(settings_layers->list[j].info.layerName, newly_added_layer->info.layerName, VK_MAX_EXTENSION_NAME_SIZE)) {
|
||||
if (0 == (newly_added_layer->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER) &&
|
||||
strcmp(settings_layers->list[j].lib_name, newly_added_layer->lib_name) == 0) {
|
||||
should_remove = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (should_remove) {
|
||||
loader_remove_layer_in_list(inst, settings_layers, settings_layers->count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
release_current_settings_lock(inst);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Check if layers has an element with the same name.
|
||||
// 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
|
||||
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) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
VkResult combine_settings_layers_with_regular_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
|
||||
struct loader_layer_list* regular_layers,
|
||||
struct loader_layer_list* output_layers) {
|
||||
VkResult res = VK_SUCCESS;
|
||||
bool has_unordered_layer_location = false;
|
||||
uint32_t unordered_layer_location_index = 0;
|
||||
// Location to put layers that aren't known to the settings file
|
||||
// Find it here so we dont have to pass in a loader_settings struct
|
||||
for (uint32_t i = 0; i < settings_layers->count; i++) {
|
||||
if (settings_layers->list[i].settings_control_value == LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION) {
|
||||
has_unordered_layer_location = true;
|
||||
unordered_layer_location_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (settings_layers->count == 0 && regular_layers->count == 0) {
|
||||
// No layers to combine
|
||||
goto out;
|
||||
} else if (settings_layers->count == 0) {
|
||||
// No settings layers - just copy regular to output_layers - memset regular layers to prevent double frees
|
||||
*output_layers = *regular_layers;
|
||||
memset(regular_layers, 0, sizeof(struct loader_layer_list));
|
||||
goto out;
|
||||
} else if (regular_layers->count == 0 || !has_unordered_layer_location) {
|
||||
// No regular layers or has_unordered_layer_location is false - just copy settings to output_layers -
|
||||
// memset settings layers to prevent double frees
|
||||
*output_layers = *settings_layers;
|
||||
memset(settings_layers, 0, sizeof(struct loader_layer_list));
|
||||
goto out;
|
||||
}
|
||||
|
||||
res = loader_init_generic_list(inst, (struct loader_generic_list*)output_layers,
|
||||
(settings_layers->count + regular_layers->count) * sizeof(struct loader_layer_properties));
|
||||
if (VK_SUCCESS != res) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Insert the settings layers into output_layers up to unordered_layer_index
|
||||
for (uint32_t i = 0; i < unordered_layer_location_index; i++) {
|
||||
if (!check_if_layer_is_in_list(output_layers, &settings_layers->list[i])) {
|
||||
res = loader_append_layer_property(inst, output_layers, &settings_layers->list[i]);
|
||||
if (VK_SUCCESS != res) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < regular_layers->count; i++) {
|
||||
// Check if its already been put in the output_layers list as well as the remaining settings_layers
|
||||
bool regular_layer_is_ordered = check_if_layer_is_in_list(output_layers, ®ular_layers->list[i]) ||
|
||||
check_if_layer_is_in_list(settings_layers, ®ular_layers->list[i]);
|
||||
// If it isn't found, add it
|
||||
if (!regular_layer_is_ordered) {
|
||||
res = loader_append_layer_property(inst, output_layers, ®ular_layers->list[i]);
|
||||
if (VK_SUCCESS != res) {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
// layer is already ordered and can be safely freed
|
||||
loader_free_layer_properties(inst, ®ular_layers->list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the rest of the settings layers into combined_layers from unordered_layer_index to the end
|
||||
// start at one after the unordered_layer_index
|
||||
for (uint32_t i = unordered_layer_location_index + 1; i < settings_layers->count; i++) {
|
||||
res = loader_append_layer_property(inst, output_layers, &settings_layers->list[i]);
|
||||
if (VK_SUCCESS != res) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (res != VK_SUCCESS) {
|
||||
loader_delete_layer_list_and_properties(inst, output_layers);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
VkResult enable_correct_layers_from_settings(const struct loader_instance* inst, const struct loader_envvar_all_filters* filters,
|
||||
uint32_t app_enabled_name_count, const char* const* app_enabled_names,
|
||||
const struct loader_layer_list* instance_layers,
|
||||
struct loader_pointer_layer_list* target_layer_list,
|
||||
struct loader_pointer_layer_list* activated_layer_list) {
|
||||
VkResult res = VK_SUCCESS;
|
||||
char* vk_instance_layers_env = loader_getenv(ENABLED_LAYERS_ENV, inst);
|
||||
size_t vk_instance_layers_env_len = 0;
|
||||
char* vk_instance_layers_env_copy = NULL;
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
for (uint32_t i = 0; i < instance_layers->count; i++) {
|
||||
bool enable_layer = false;
|
||||
struct loader_layer_properties* props = &instance_layers->list[i];
|
||||
|
||||
// Do not enable the layer if the settings have it set as off
|
||||
if (props->settings_control_value == LOADER_SETTINGS_LAYER_CONTROL_OFF) {
|
||||
continue;
|
||||
}
|
||||
// Force enable it based on settings
|
||||
if (props->settings_control_value == LOADER_SETTINGS_LAYER_CONTROL_ON) {
|
||||
enable_layer = true;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
// Check the enable filter
|
||||
if (!enable_layer && check_name_matches_filter_environment_var(props->info.layerName, &filters->enable_filter)) {
|
||||
enable_layer = true;
|
||||
}
|
||||
|
||||
// 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
|
||||
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)) {
|
||||
enable_layer = true;
|
||||
break;
|
||||
}
|
||||
vk_instance_layers_env_copy = next;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if it should be enabled by the application
|
||||
if (!enable_layer) {
|
||||
for (uint32_t j = 0; j < app_enabled_name_count; j++) {
|
||||
if (strcmp(props->info.layerName, app_enabled_names[j]) == 0) {
|
||||
enable_layer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if its an implicit layers and thus enabled by default
|
||||
if (!enable_layer && (0 == (props->type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER)) &&
|
||||
loader_implicit_layer_is_enabled(inst, filters, props)) {
|
||||
enable_layer = true;
|
||||
}
|
||||
|
||||
if (enable_layer) {
|
||||
// Check if the layer is a meta layer reuse the existing function to add the meta layer
|
||||
if (props->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER) {
|
||||
res = loader_add_meta_layer(inst, filters, props, target_layer_list, activated_layer_list, instance_layers, NULL);
|
||||
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
|
||||
} else {
|
||||
res = loader_add_layer_properties_to_list(inst, target_layer_list, props);
|
||||
if (res != VK_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
res = loader_add_layer_properties_to_list(inst, activated_layer_list, props);
|
||||
if (res != VK_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
return res;
|
||||
}
|
114
loader/settings.h
Normal file
114
loader/settings.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2023 The Khronos Group Inc.
|
||||
* Copyright (c) 2023 Valve Corporation
|
||||
* Copyright (c) 2023 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: Charles Giessen <charles@lunarg.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "vulkan/vulkan_core.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
struct loader_instance;
|
||||
struct loader_layer_list;
|
||||
struct loader_pointer_layer_list;
|
||||
struct loader_envvar_all_filters;
|
||||
typedef struct log_configuration log_configuration;
|
||||
|
||||
typedef enum loader_settings_layer_control {
|
||||
LOADER_SETTINGS_LAYER_CONTROL_DEFAULT, // layer is not enabled by settings file but can be enabled through other means
|
||||
LOADER_SETTINGS_LAYER_CONTROL_ON, // layer is enabled by settings file
|
||||
LOADER_SETTINGS_LAYER_CONTROL_OFF, // layer is prevented from being enabled
|
||||
LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION // special control indicating unspecified layers should go here. If this is not
|
||||
// in the settings file, then the loader assume no other layers should be
|
||||
// searched & loaded.
|
||||
} loader_settings_layer_control;
|
||||
|
||||
// If a loader_settings_layer_configuration has a name of loader_settings_unknown_layers_location, then it specifies that the
|
||||
// layer configuration it was found in shall be the location all layers not listed in the settings file that are enabled.
|
||||
#define LOADER_SETTINGS_UNKNOWN_LAYERS_LOCATION "loader_settings_unknown_layers_location"
|
||||
|
||||
#define LOADER_SETTINGS_MAX_NAME_SIZE 256U;
|
||||
|
||||
typedef struct loader_settings_layer_configuration {
|
||||
char* name;
|
||||
char* path;
|
||||
loader_settings_layer_control control;
|
||||
bool treat_as_implicit_manifest; // whether or not the layer should be parsed as if it is implicit
|
||||
|
||||
} loader_settings_layer_configuration;
|
||||
|
||||
typedef struct loader_settings {
|
||||
bool settings_active;
|
||||
bool has_unordered_layer_location;
|
||||
enum vulkan_loader_debug_flags debug_level;
|
||||
|
||||
uint32_t layer_configuration_count;
|
||||
loader_settings_layer_configuration* layer_configurations;
|
||||
|
||||
char* settings_file_path;
|
||||
} loader_settings;
|
||||
|
||||
// Call this function to get the current settings that the loader should use.
|
||||
// It will open up the current loader settings file and return a loader_settings in out_loader_settings if it.
|
||||
// It should be called on every call to the global functions excluding vkGetInstanceProcAddr
|
||||
// Caller is responsible for cleaning up by calling free_loader_settings()
|
||||
VkResult get_loader_settings(const struct loader_instance* inst, loader_settings* out_loader_settings);
|
||||
|
||||
void free_loader_settings(const struct loader_instance* inst, loader_settings* loader_settings);
|
||||
|
||||
// Log the settings to the console
|
||||
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);
|
||||
|
||||
// Needs to be called during startup -
|
||||
void init_global_loader_settings(void);
|
||||
void teardown_global_loader_settings(void);
|
||||
|
||||
// Check the global settings and return true if msg_type does not correspond to the active global loader settings
|
||||
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);
|
||||
|
||||
// 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
|
||||
// layer configuration with LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION set
|
||||
VkResult combine_settings_layers_with_regular_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
|
||||
struct loader_layer_list* regular_layers,
|
||||
struct loader_layer_list* output_layers);
|
||||
|
||||
// Fill out activated_layer_list with the layers that should be activated, based on environment variables, VkInstanceCreateInfo, and
|
||||
// the settings
|
||||
VkResult enable_correct_layers_from_settings(const struct loader_instance* inst, const struct loader_envvar_all_filters* filters,
|
||||
uint32_t app_enabled_name_count, const char* const* app_enabled_names,
|
||||
const struct loader_layer_list* instance_layers,
|
||||
struct loader_pointer_layer_list* target_layer_list,
|
||||
struct loader_pointer_layer_list* activated_layer_list);
|
@ -36,8 +36,10 @@
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNXNTO__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#if COMMON_UNIX_PLATFORMS
|
||||
#define loader_stack_alloc(size) alloca(size)
|
||||
#elif defined(_WIN32)
|
||||
#define loader_stack_alloc(size) _alloca(size)
|
||||
#else
|
||||
#warning "alloca not available on this platform!"
|
||||
#endif // defined(_WIN32)
|
||||
|
@ -4,6 +4,8 @@
|
||||
* Copyright (c) 2014-2021 Valve Corporation
|
||||
* Copyright (c) 2014-2021 LunarG, Inc.
|
||||
* Copyright (C) 2015 Google Inc.
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (c) 2023-2023 RasterGrid Kft.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -113,6 +115,8 @@ VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperti
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
|
||||
VkLayerProperties *pProperties) {
|
||||
(void)pPropertyCount;
|
||||
(void)pProperties;
|
||||
struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
|
||||
struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
|
||||
loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
@ -280,8 +284,8 @@ VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties2(VkPhysi
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties2(
|
||||
VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
|
||||
VkImageFormatProperties2KHR *pImageFormatProperties) {
|
||||
VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
|
||||
VkImageFormatProperties2 *pImageFormatProperties) {
|
||||
struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
|
||||
struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
|
||||
const struct loader_instance *inst = icd_term->this_instance;
|
||||
@ -321,7 +325,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
|
||||
uint32_t *pQueueFamilyPropertyCount,
|
||||
VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
|
||||
VkQueueFamilyProperties2 *pQueueFamilyProperties) {
|
||||
struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
|
||||
struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
|
||||
const struct loader_instance *inst = icd_term->this_instance;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -48,7 +48,7 @@
|
||||
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, "Extension %s not supported for this physical device", \
|
||||
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); \
|
||||
|
@ -27,6 +27,11 @@
|
||||
|
||||
.macro PhysDevExtTramp num
|
||||
.global vkPhysDevExtTramp\num
|
||||
#if defined(__ELF__)
|
||||
.hidden vkPhysDevExtTramp\num
|
||||
#endif
|
||||
.balign 4
|
||||
|
||||
vkPhysDevExtTramp\num:
|
||||
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
|
||||
@ -37,6 +42,10 @@ vkPhysDevExtTramp\num:
|
||||
|
||||
.macro PhysDevExtTermin num
|
||||
.global vkPhysDevExtTermin\num
|
||||
#if defined(__ELF__)
|
||||
.hidden vkPhysDevExtTermin\num
|
||||
#endif
|
||||
.balign 4
|
||||
vkPhysDevExtTermin\num:
|
||||
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
|
||||
@ -46,20 +55,22 @@ vkPhysDevExtTermin\num:
|
||||
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)
|
||||
adrp x9, termin_error_string
|
||||
add x3, x9, #:lo12:termin_error_string // The error string (fourth arg)
|
||||
ldr x4, [x11, x10] // The function name (fifth arg)
|
||||
bl loader_log // Log the error message before we crash
|
||||
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
|
||||
br x0 // 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\num:
|
||||
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
|
||||
@ -76,7 +87,7 @@ vkdev_ext\num:
|
||||
.data
|
||||
|
||||
termin_error_string:
|
||||
.string "Extension %s not supported for this physical device"
|
||||
.string "Function %s not supported for this physical device"
|
||||
|
||||
.text
|
||||
|
||||
|
@ -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-2023 The Khronos Group Inc.
|
||||
# Copyright (c) 2017-2023 Valve Corporation
|
||||
# Copyright (c) 2017-2023 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,9 @@
|
||||
# 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
|
||||
|
||||
#ifdef HAVE_CET_H
|
||||
# The .hidden directive is only supported in ELF executables so in APPLE builds, the directive is removed
|
||||
|
||||
#if defined(HAVE_CET_H)
|
||||
#include <cet.h>
|
||||
#else
|
||||
#define _CET_ENDBR
|
||||
@ -37,6 +39,9 @@
|
||||
|
||||
.macro PhysDevExtTramp num
|
||||
.global vkPhysDevExtTramp\num
|
||||
#if defined(__ELF__)
|
||||
.hidden vkPhysDevExtTramp\num
|
||||
#endif
|
||||
vkPhysDevExtTramp\num:
|
||||
_CET_ENDBR
|
||||
mov rax, [rdi]
|
||||
@ -46,6 +51,9 @@ vkPhysDevExtTramp\num:
|
||||
|
||||
.macro PhysDevExtTermin num
|
||||
.global vkPhysDevExtTermin\num
|
||||
#if defined(__ELF__)
|
||||
.hidden vkPhysDevExtTermin\num
|
||||
#endif
|
||||
vkPhysDevExtTermin\num:
|
||||
_CET_ENDBR
|
||||
mov rax, [rdi + ICD_TERM_OFFSET_PHYS_DEV_TERM] # Store the loader_icd_term* in rax
|
||||
@ -58,7 +66,7 @@ terminError\num:
|
||||
mov rdi, [rax + INSTANCE_OFFSET_ICD_TERM] # Load the loader_instance into rdi (first arg)
|
||||
lea rsi, [VULKAN_LOADER_ERROR_BIT] # Write the error logging bit to rsi (second arg)
|
||||
xor rdx, rdx # Set rdx to zero (third arg)
|
||||
lea rcx, [rip + termin_error_string] # Load the error string into rcx (fourth arg)
|
||||
lea rcx, [rip + termin_error_string] # Load the error string into rcx (fourth arg)
|
||||
mov r8, [rdi + (FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * \num))] # Load the func name into r8 (fifth arg)
|
||||
call loader_log # Log the error message before we crash
|
||||
add rsp, 56 # Clean up the stack frame
|
||||
@ -68,6 +76,9 @@ terminError\num:
|
||||
|
||||
.macro DevExtTramp num
|
||||
.global vkdev_ext\num
|
||||
#if defined(__ELF__)
|
||||
.hidden vkdev_ext\num
|
||||
#endif
|
||||
vkdev_ext\num:
|
||||
_CET_ENDBR
|
||||
mov rax, [rdi] # Dereference the handle to get the dispatch table
|
||||
@ -78,6 +89,9 @@ vkdev_ext\num:
|
||||
|
||||
.macro PhysDevExtTramp num
|
||||
.global vkPhysDevExtTramp\num
|
||||
#if defined(__ELF__)
|
||||
.hidden vkPhysDevExtTramp\num
|
||||
#endif
|
||||
vkPhysDevExtTramp\num:
|
||||
_CET_ENDBR
|
||||
mov eax, [esp + 4] # Load the wrapped VkPhysicalDevice into eax
|
||||
@ -89,6 +103,9 @@ vkPhysDevExtTramp\num:
|
||||
|
||||
.macro PhysDevExtTermin num
|
||||
.global vkPhysDevExtTermin\num
|
||||
#if defined(__ELF__)
|
||||
.hidden vkPhysDevExtTermin\num
|
||||
#endif
|
||||
vkPhysDevExtTermin\num:
|
||||
_CET_ENDBR
|
||||
mov ecx, [esp + 4] # Move the wrapped VkPhysicalDevice into ecx
|
||||
@ -100,12 +117,11 @@ vkPhysDevExtTermin\num:
|
||||
jmp [eax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))] # Jump to the next function in the chain
|
||||
terminError\num:
|
||||
mov eax, dword ptr [eax + INSTANCE_OFFSET_ICD_TERM] # Load the loader_instance into eax
|
||||
push dword ptr [eax + (FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * \num))] # Push the func name (fifth arg)
|
||||
push offset termin_error_string@GOT # Push the error string (fourth arg)
|
||||
push dword ptr [eax + (FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * \num))] # Push the func name (fourth arg)
|
||||
push 0 # Push zero (third arg)
|
||||
push VULKAN_LOADER_ERROR_BIT # Push the error logging bit (second arg)
|
||||
push eax # Push the loader_instance (first arg)
|
||||
call loader_log # Log the error message before we crash
|
||||
call loader_log_asm_function_not_supported # Log the error message before we crash
|
||||
add esp, 20 # Clean up the args
|
||||
mov eax, 0
|
||||
jmp eax # Crash intentionally by jumping to address zero
|
||||
@ -113,6 +129,9 @@ terminError\num:
|
||||
|
||||
.macro DevExtTramp num
|
||||
.global vkdev_ext\num
|
||||
#if defined(__ELF__)
|
||||
.hidden vkdev_ext\num
|
||||
#endif
|
||||
vkdev_ext\num:
|
||||
_CET_ENDBR
|
||||
mov eax, dword ptr [esp + 4] # Dereference the handle to get the dispatch table
|
||||
@ -129,7 +148,7 @@ vkdev_ext\num:
|
||||
.data
|
||||
|
||||
termin_error_string:
|
||||
.string "Extension %s not supported for this physical device"
|
||||
.string "Function %s not supported for this physical device"
|
||||
|
||||
.text
|
||||
|
||||
|
@ -119,7 +119,7 @@ endm
|
||||
ENDIF
|
||||
|
||||
.const
|
||||
termin_error_string db 'Extension %s not supported for this physical device', 0
|
||||
termin_error_string db 'Function %s not supported for this physical device', 0
|
||||
|
||||
.code
|
||||
|
||||
|
@ -85,17 +85,16 @@ bool loader_check_icds_for_dev_ext_address(struct loader_instance *inst, const c
|
||||
// Look in the layers list of device extensions, which contain names of entry points. If funcName is present, return true
|
||||
// If not, call down the first layer's vkGetInstanceProcAddr to determine if any layers support the function
|
||||
bool loader_check_layer_list_for_dev_ext_address(struct loader_instance *inst, const char *funcName) {
|
||||
struct loader_layer_properties *layer_prop_list = inst->expanded_activated_layer_list.list;
|
||||
|
||||
// Iterate over the layers.
|
||||
for (uint32_t layer = 0; layer < inst->expanded_activated_layer_list.count; ++layer) {
|
||||
// Iterate over the extensions.
|
||||
const struct loader_device_extension_list *const extensions = &(layer_prop_list[layer].device_extension_list);
|
||||
const struct loader_device_extension_list *const extensions =
|
||||
&(inst->expanded_activated_layer_list.list[layer]->device_extension_list);
|
||||
for (uint32_t extension = 0; extension < extensions->count; ++extension) {
|
||||
// Iterate over the entry points.
|
||||
const struct loader_dev_ext_props *const property = &(extensions->list[extension]);
|
||||
for (uint32_t entry = 0; entry < property->entrypoint_count; ++entry) {
|
||||
if (strcmp(property->entrypoints[entry], funcName) == 0) {
|
||||
for (uint32_t entry = 0; entry < property->entrypoints.count; ++entry) {
|
||||
if (strcmp(property->entrypoints.list[entry], funcName) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -104,7 +103,7 @@ bool loader_check_layer_list_for_dev_ext_address(struct loader_instance *inst, c
|
||||
// If the function pointer doesn't appear in the layer manifest for intercepted device functions, look down the
|
||||
// vkGetInstanceProcAddr chain
|
||||
if (inst->expanded_activated_layer_list.count > 0) {
|
||||
const struct loader_layer_functions *const functions = &(layer_prop_list[0].functions);
|
||||
const struct loader_layer_functions *const functions = &(inst->expanded_activated_layer_list.list[0]->functions);
|
||||
if (NULL != functions->get_instance_proc_addr) {
|
||||
return NULL != functions->get_instance_proc_addr((VkInstance)inst->instance, funcName);
|
||||
}
|
||||
@ -165,7 +164,7 @@ void *loader_dev_ext_gpa_impl(struct loader_instance *inst, const char *funcName
|
||||
// failed to allocate memory, return NULL
|
||||
return NULL;
|
||||
}
|
||||
strncpy(inst->dev_ext_disp_functions[inst->dev_ext_disp_function_count], funcName, funcName_len);
|
||||
loader_strncpy(inst->dev_ext_disp_functions[inst->dev_ext_disp_function_count], funcName_len, funcName, funcName_len);
|
||||
// init any dev dispatch table entries as needed
|
||||
loader_init_dispatch_dev_ext_entry(inst, NULL, inst->dev_ext_disp_function_count, funcName);
|
||||
void *out_function = loader_get_dev_ext_trampoline(inst->dev_ext_disp_function_count);
|
||||
@ -188,6 +187,7 @@ bool loader_check_icds_for_phys_dev_ext_address(struct loader_instance *inst, co
|
||||
icd_term = inst->icd_terms;
|
||||
while (NULL != icd_term) {
|
||||
if (icd_term->scanned_icd->interface_version >= MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION &&
|
||||
icd_term->scanned_icd->GetPhysicalDeviceProcAddr &&
|
||||
icd_term->scanned_icd->GetPhysicalDeviceProcAddr(icd_term->instance, funcName))
|
||||
// this icd supports funcName
|
||||
return true;
|
||||
@ -198,13 +198,13 @@ bool loader_check_icds_for_phys_dev_ext_address(struct loader_instance *inst, co
|
||||
}
|
||||
|
||||
bool loader_check_layer_list_for_phys_dev_ext_address(struct loader_instance *inst, const char *funcName) {
|
||||
struct loader_layer_properties *layer_prop_list = inst->expanded_activated_layer_list.list;
|
||||
for (uint32_t layer = 0; layer < inst->expanded_activated_layer_list.count; layer++) {
|
||||
struct loader_layer_properties *layer_prop_list = inst->expanded_activated_layer_list.list[layer];
|
||||
// Find the first layer in the call chain which supports vk_layerGetPhysicalDeviceProcAddr
|
||||
// and call that, returning whether it found a valid pointer for this function name.
|
||||
// We return if the topmost layer supports GPDPA since the layer should call down the chain for us.
|
||||
if (layer_prop_list[layer].interface_version > 1) {
|
||||
const struct loader_layer_functions *const functions = &(layer_prop_list[layer].functions);
|
||||
if (layer_prop_list->interface_version > 1) {
|
||||
const struct loader_layer_functions *const functions = &(layer_prop_list->functions);
|
||||
if (NULL != functions->get_physical_device_proc_addr) {
|
||||
return NULL != functions->get_physical_device_proc_addr((VkInstance)inst->instance, funcName);
|
||||
}
|
||||
@ -276,12 +276,12 @@ void *loader_phys_dev_ext_gpa_impl(struct loader_instance *inst, const char *fun
|
||||
// failed to allocate memory, return NULL
|
||||
return NULL;
|
||||
}
|
||||
strncpy(inst->phys_dev_ext_disp_functions[inst->phys_dev_ext_disp_function_count], funcName, funcName_len);
|
||||
loader_strncpy(inst->phys_dev_ext_disp_functions[inst->phys_dev_ext_disp_function_count], funcName_len, funcName,
|
||||
funcName_len);
|
||||
|
||||
new_function_index = inst->phys_dev_ext_disp_function_count;
|
||||
// increment the count so that the subsequent logic includes the newly added entry point when searching for functions
|
||||
inst->phys_dev_ext_disp_function_count++;
|
||||
has_found = true;
|
||||
}
|
||||
|
||||
// Setup the ICD function pointers
|
||||
@ -310,7 +310,7 @@ void *loader_phys_dev_ext_gpa_impl(struct loader_instance *inst, const char *fun
|
||||
// point. Only set the instance dispatch table to it if it isn't NULL.
|
||||
if (is_tramp) {
|
||||
for (uint32_t i = 0; i < inst->expanded_activated_layer_list.count; i++) {
|
||||
struct loader_layer_properties *layer_prop = &inst->expanded_activated_layer_list.list[i];
|
||||
struct loader_layer_properties *layer_prop = inst->expanded_activated_layer_list.list[i];
|
||||
if (layer_prop->interface_version > 1 && NULL != layer_prop->functions.get_physical_device_proc_addr) {
|
||||
void *layer_ret_function =
|
||||
(PFN_PhysDevExt)layer_prop->functions.get_physical_device_proc_addr(inst->instance, funcName);
|
||||
|
@ -3,6 +3,8 @@
|
||||
* Copyright (c) 2015-2022 The Khronos Group Inc.
|
||||
* Copyright (c) 2015-2022 Valve Corporation
|
||||
* Copyright (c) 2015-2022 LunarG, Inc.
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (c) 2023-2023 RasterGrid Kft.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -29,21 +31,26 @@
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
// WinSock2.h must be included *BEFORE* windows.h
|
||||
#include <winsock2.h>
|
||||
#endif // _WIN32
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__Fuchsia__)
|
||||
#include "dlopen_fuchsia.h"
|
||||
#endif // defined(__Fuchsia__)
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNXNTO__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
// Set of platforms with a common set of functionality which is queried throughout the program
|
||||
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNX__) || defined(__FreeBSD__) || \
|
||||
defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__)
|
||||
#define COMMON_UNIX_PLATFORMS 1
|
||||
#else
|
||||
#define COMMON_UNIX_PLATFORMS 0
|
||||
#endif
|
||||
|
||||
#if COMMON_UNIX_PLATFORMS
|
||||
#include <unistd.h>
|
||||
// Note: The following file is for dynamic loading:
|
||||
#include <dlfcn.h>
|
||||
@ -51,14 +58,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#elif defined(_WIN32) // defined(__linux__)
|
||||
/* Windows-specific common code: */
|
||||
#elif defined(_WIN32)
|
||||
// WinBase.h defines CreateSemaphore and synchapi.h defines CreateEvent
|
||||
// undefine them to avoid conflicts with VkLayerDispatchTable struct members.
|
||||
#ifdef CreateSemaphore
|
||||
#if defined(CreateSemaphore)
|
||||
#undef CreateSemaphore
|
||||
#endif
|
||||
#ifdef CreateEvent
|
||||
#if defined(CreateEvent)
|
||||
#undef CreateEvent
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
@ -69,7 +75,13 @@
|
||||
|
||||
#include "stack_allocation.h"
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 4
|
||||
#if defined(APPLE_STATIC_LOADER) && !defined(__APPLE__)
|
||||
#error "APPLE_STATIC_LOADER can only be defined on Apple platforms!"
|
||||
#endif
|
||||
|
||||
#if defined(APPLE_STATIC_LOADER)
|
||||
#define LOADER_EXPORT
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define LOADER_EXPORT __attribute__((visibility("default")))
|
||||
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
|
||||
#define LOADER_EXPORT __attribute__((visibility("default")))
|
||||
@ -81,24 +93,39 @@
|
||||
|
||||
// This is defined in vk_layer.h, but if there's problems we need to create the define
|
||||
// here.
|
||||
#ifndef MAX_NUM_UNKNOWN_EXTS
|
||||
#if !defined(MAX_NUM_UNKNOWN_EXTS)
|
||||
#define MAX_NUM_UNKNOWN_EXTS 250
|
||||
#endif
|
||||
|
||||
// Environment Variable information
|
||||
#define VK_ICD_FILENAMES_ENV_VAR "VK_ICD_FILENAMES" // Deprecated
|
||||
#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_ADDITIONAL_DRIVER_FILES_ENV_VAR "VK_ADD_DRIVER_FILES"
|
||||
#define VK_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"
|
||||
// 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"
|
||||
#define VK_LAYERS_ALLOW_ENV_VAR "VK_LOADER_LAYERS_ALLOW"
|
||||
#define VK_DRIVERS_SELECT_ENV_VAR "VK_LOADER_DRIVERS_SELECT"
|
||||
#define VK_DRIVERS_DISABLE_ENV_VAR "VK_LOADER_DRIVERS_DISABLE"
|
||||
#define VK_LOADER_DISABLE_ALL_LAYERS_VAR_1 "~all~"
|
||||
#define VK_LOADER_DISABLE_ALL_LAYERS_VAR_2 "*"
|
||||
#define VK_LOADER_DISABLE_ALL_LAYERS_VAR_3 "**"
|
||||
#define VK_LOADER_DISABLE_IMPLICIT_LAYERS_VAR "~implicit~"
|
||||
#define VK_LOADER_DISABLE_EXPLICIT_LAYERS_VAR "~explicit~"
|
||||
|
||||
// Override layer information
|
||||
#define VK_OVERRIDE_LAYER_NAME "VK_LAYER_LUNARG_override"
|
||||
|
||||
// Loader Settings filename
|
||||
#define VK_LOADER_SETTINGS_FILENAME "vk_loader_settings.json"
|
||||
|
||||
#define LAYERS_PATH_ENV "VK_LAYER_PATH"
|
||||
#define ENABLED_LAYERS_ENV "VK_INSTANCE_LAYERS"
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNXNTO__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#if COMMON_UNIX_PLATFORMS
|
||||
/* Linux-specific common code: */
|
||||
|
||||
// VK Library Filenames, Paths, etc.:
|
||||
@ -119,11 +146,11 @@
|
||||
#define VK_ILAYERS_INFO_RELATIVE_DIR VULKAN_DIR VULKAN_ILAYERCONF_DIR
|
||||
|
||||
#define VK_DRIVERS_INFO_REGISTRY_LOC ""
|
||||
#define VK_SETTINGS_INFO_REGISTRY_LOC ""
|
||||
#define VK_ELAYERS_INFO_REGISTRY_LOC ""
|
||||
#define VK_ILAYERS_INFO_REGISTRY_LOC ""
|
||||
#define VK_SETTINGS_INFO_REGISTRY_LOC ""
|
||||
|
||||
#if defined(__QNXNTO__)
|
||||
#if defined(__QNX__)
|
||||
#define SYSCONFDIR "/etc"
|
||||
#endif
|
||||
|
||||
@ -144,8 +171,8 @@ typedef pthread_mutex_t loader_platform_thread_mutex;
|
||||
|
||||
typedef pthread_cond_t loader_platform_thread_cond;
|
||||
|
||||
#elif defined(_WIN32) // defined(__linux__)
|
||||
|
||||
#elif defined(_WIN32)
|
||||
/* Windows-specific common code: */
|
||||
// VK Library Filenames, Paths, etc.:
|
||||
#define PATH_SEPARATOR ';'
|
||||
#define DIRECTORY_SYMBOL '\\'
|
||||
@ -159,15 +186,13 @@ typedef pthread_cond_t loader_platform_thread_cond;
|
||||
#define VK_ELAYERS_INFO_RELATIVE_DIR ""
|
||||
#define VK_ILAYERS_INFO_RELATIVE_DIR ""
|
||||
|
||||
#ifdef _WIN64
|
||||
#define HKR_VK_DRIVER_NAME API_NAME "DriverName"
|
||||
#else
|
||||
#define HKR_VK_DRIVER_NAME API_NAME "DriverNameWow"
|
||||
#endif
|
||||
#define VK_DRIVERS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\" API_NAME "\\Drivers"
|
||||
#define VK_SETTINGS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\" API_NAME "\\Settings"
|
||||
#define VK_ELAYERS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\" API_NAME "\\ExplicitLayers"
|
||||
#define VK_ILAYERS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\" API_NAME "\\ImplicitLayers"
|
||||
#define VK_VARIANT_REG_STR ""
|
||||
#define VK_VARIANT_REG_STR_W L""
|
||||
|
||||
#define VK_DRIVERS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\Vulkan" VK_VARIANT_REG_STR "\\Drivers"
|
||||
#define VK_ELAYERS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\Vulkan" VK_VARIANT_REG_STR "\\ExplicitLayers"
|
||||
#define VK_ILAYERS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\Vulkan" VK_VARIANT_REG_STR "\\ImplicitLayers"
|
||||
#define VK_SETTINGS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\Vulkan" VK_VARIANT_REG_STR "\\LoaderSettings"
|
||||
|
||||
#define PRINTF_SIZE_T_SPECIFIER "%Iu"
|
||||
|
||||
@ -185,16 +210,19 @@ typedef CRITICAL_SECTION loader_platform_thread_mutex;
|
||||
|
||||
typedef CONDITION_VARIABLE loader_platform_thread_cond;
|
||||
|
||||
#else // defined(_WIN32)
|
||||
#else
|
||||
|
||||
#error The "vk_loader_platform.h" file must be modified for this OS.
|
||||
#warning The "vk_loader_platform.h" file must be modified for this OS.
|
||||
|
||||
// NOTE: In order to support another OS, an #elif needs to be added (above the
|
||||
// "#else // defined(_WIN32)") for that OS, and OS-specific versions of the
|
||||
// contents of this file must be created, or extend one of the existing OS specific
|
||||
// sections with the necessary changes.
|
||||
|
||||
#endif // defined(_WIN32)
|
||||
#endif
|
||||
|
||||
// controls whether loader_platform_close_library() closes the libraries or not - controlled by an environment variables
|
||||
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; }
|
||||
@ -203,7 +231,7 @@ static inline bool loader_platform_is_path(const char *path) { return strchr(pat
|
||||
// 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.
|
||||
|
||||
#if defined(__APPLE__) && defined(BUILD_STATIC_LOADER)
|
||||
#if defined(APPLE_STATIC_LOADER)
|
||||
static inline void loader_platform_thread_once_fn(pthread_once_t *ctl, void (*func)(void)) {
|
||||
assert(func != NULL);
|
||||
assert(ctl != NULL);
|
||||
@ -219,7 +247,7 @@ static inline void loader_platform_thread_once_fn(pthread_once_t *ctl, void (*fu
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNXNTO__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#if COMMON_UNIX_PLATFORMS
|
||||
|
||||
// File IO
|
||||
static inline bool loader_platform_file_exists(const char *path) {
|
||||
@ -242,7 +270,7 @@ static inline char *loader_platform_dirname(char *path) { return dirname(path);
|
||||
|
||||
// loader_platform_executable_path finds application path + name.
|
||||
// Path cannot be longer than 1024, returns NULL if it is greater than that.
|
||||
#if defined(__linux__)
|
||||
#if defined(__linux__) || defined(__GNU__)
|
||||
static inline char *loader_platform_executable_path(char *buffer, size_t size) {
|
||||
ssize_t count = readlink("/proc/self/exe", buffer, size);
|
||||
if (count == -1) return NULL;
|
||||
@ -250,15 +278,32 @@ static inline char *loader_platform_executable_path(char *buffer, size_t size) {
|
||||
buffer[count] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
#elif defined(__APPLE__) // defined(__linux__)
|
||||
#elif defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
// TARGET_OS_IPHONE isn't just iOS it's also iOS/tvOS/watchOS. See TargetConditionals.h documentation.
|
||||
#if TARGET_OS_IPHONE
|
||||
static inline char *loader_platform_executable_path(char *buffer, size_t size) {
|
||||
(void)size;
|
||||
buffer[0] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
#endif
|
||||
#if TARGET_OS_OSX
|
||||
#include <libproc.h>
|
||||
static inline char *loader_platform_executable_path(char *buffer, size_t size) {
|
||||
// proc_pidpath takes a uint32_t for the buffer size
|
||||
if (size > UINT32_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
pid_t pid = getpid();
|
||||
int ret = proc_pidpath(pid, buffer, size);
|
||||
if (ret <= 0) return NULL;
|
||||
int ret = proc_pidpath(pid, buffer, (uint32_t)size);
|
||||
if (ret <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
buffer[ret] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
#endif
|
||||
#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#include <sys/sysctl.h>
|
||||
static inline char *loader_platform_executable_path(char *buffer, size_t size) {
|
||||
@ -282,7 +327,7 @@ static inline char *loader_platform_executable_path(char *buffer, size_t size) {
|
||||
}
|
||||
#elif defined(__Fuchsia__) || defined(__OpenBSD__)
|
||||
static inline char *loader_platform_executable_path(char *buffer, size_t size) { return NULL; }
|
||||
#elif defined(__QNXNTO__)
|
||||
#elif defined(__QNX__)
|
||||
|
||||
#define SYSCONFDIR "/etc"
|
||||
|
||||
@ -306,15 +351,15 @@ static inline char *loader_platform_executable_path(char *buffer, size_t size) {
|
||||
|
||||
return buffer;
|
||||
}
|
||||
#endif // defined (__QNXNTO__)
|
||||
#endif // defined (__QNX__)
|
||||
|
||||
// Compatability with compilers that don't support __has_feature
|
||||
#ifndef __has_feature
|
||||
// Compatibility with compilers that don't support __has_feature
|
||||
#if !defined(__has_feature)
|
||||
#define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
||||
#define LOADER_ADDRESS_SANITIZER // TODO: Add proper build flag for ASAN support
|
||||
#define LOADER_ADDRESS_SANITIZER_ACTIVE // TODO: Add proper build flag for ASAN support
|
||||
#endif
|
||||
|
||||
// When loading the library, we use RTLD_LAZY so that not all symbols have to be
|
||||
@ -337,23 +382,29 @@ static inline loader_platform_dl_handle loader_platform_open_library(const char
|
||||
#endif
|
||||
|
||||
static inline const char *loader_platform_open_library_error(const char *libPath) {
|
||||
#ifdef __Fuchsia__
|
||||
(void)libPath;
|
||||
#if defined(__Fuchsia__)
|
||||
return dlerror_fuchsia();
|
||||
#else
|
||||
return dlerror();
|
||||
#endif
|
||||
}
|
||||
static inline void loader_platform_close_library(loader_platform_dl_handle library) {
|
||||
#if !defined (__OHOS__)
|
||||
dlclose(library);
|
||||
#endif
|
||||
if (!loader_disable_dynamic_library_unloading) {
|
||||
dlclose(library);
|
||||
} else {
|
||||
(void)library;
|
||||
}
|
||||
}
|
||||
static inline void *loader_platform_get_proc_address(loader_platform_dl_handle library, const char *name) {
|
||||
assert(library);
|
||||
assert(name);
|
||||
return dlsym(library, name);
|
||||
}
|
||||
static inline const char *loader_platform_get_proc_address_error(const char *name) { return dlerror(); }
|
||||
static inline const char *loader_platform_get_proc_address_error(const char *name) {
|
||||
(void)name;
|
||||
return dlerror();
|
||||
}
|
||||
|
||||
// Thread mutex:
|
||||
static inline void loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) { pthread_mutex_init(pMutex, NULL); }
|
||||
@ -361,19 +412,31 @@ static inline void loader_platform_thread_lock_mutex(loader_platform_thread_mute
|
||||
static inline void loader_platform_thread_unlock_mutex(loader_platform_thread_mutex *pMutex) { pthread_mutex_unlock(pMutex); }
|
||||
static inline void loader_platform_thread_delete_mutex(loader_platform_thread_mutex *pMutex) { pthread_mutex_destroy(pMutex); }
|
||||
|
||||
#elif defined(_WIN32) // defined(__linux__)
|
||||
static inline void *thread_safe_strtok(char *str, const char *delim, char **saveptr) { return strtok_r(str, delim, saveptr); }
|
||||
|
||||
static inline FILE *loader_fopen(const char *fileName, const char *mode) { return fopen(fileName, mode); }
|
||||
static inline char *loader_strncat(char *dest, size_t dest_sz, const char *src, size_t count) {
|
||||
(void)dest_sz;
|
||||
return strncat(dest, src, count);
|
||||
}
|
||||
static inline char *loader_strncpy(char *dest, size_t dest_sz, const char *src, size_t count) {
|
||||
(void)dest_sz;
|
||||
return strncpy(dest, src, count);
|
||||
}
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
// Get the key for the plug n play driver registry
|
||||
// The string returned by this function should NOT be freed
|
||||
static inline const char *LoaderPnpDriverRegistry() {
|
||||
BOOL is_wow;
|
||||
IsWow64Process(GetCurrentProcess(), &is_wow);
|
||||
return is_wow ? "VulkanDriverNameWow" : "VulkanDriverName";
|
||||
return is_wow ? "Vulkan" VK_VARIANT_REG_STR "DriverNameWow" : "Vulkan" VK_VARIANT_REG_STR "DriverName";
|
||||
}
|
||||
static inline const wchar_t *LoaderPnpDriverRegistryWide() {
|
||||
BOOL is_wow;
|
||||
IsWow64Process(GetCurrentProcess(), &is_wow);
|
||||
return is_wow ? L"VulkanDriverNameWow" : L"VulkanDriverName";
|
||||
return is_wow ? L"Vulkan" VK_VARIANT_REG_STR_W L"DriverNameWow" : L"Vulkan" VK_VARIANT_REG_STR_W L"DriverName";
|
||||
}
|
||||
|
||||
// Get the key for the plug 'n play explicit layer registry
|
||||
@ -381,12 +444,12 @@ static inline const wchar_t *LoaderPnpDriverRegistryWide() {
|
||||
static inline const char *LoaderPnpELayerRegistry() {
|
||||
BOOL is_wow;
|
||||
IsWow64Process(GetCurrentProcess(), &is_wow);
|
||||
return is_wow ? "VulkanExplicitLayersWow" : "VulkanExplicitLayers";
|
||||
return is_wow ? "Vulkan" VK_VARIANT_REG_STR "ExplicitLayersWow" : "Vulkan" VK_VARIANT_REG_STR "ExplicitLayers";
|
||||
}
|
||||
static inline const wchar_t *LoaderPnpELayerRegistryWide() {
|
||||
BOOL is_wow;
|
||||
IsWow64Process(GetCurrentProcess(), &is_wow);
|
||||
return is_wow ? L"VulkanExplicitLayersWow" : L"VulkanExplicitLayers";
|
||||
return is_wow ? L"Vulkan" VK_VARIANT_REG_STR_W L"ExplicitLayersWow" : L"Vulkan" VK_VARIANT_REG_STR_W L"ExplicitLayers";
|
||||
}
|
||||
|
||||
// Get the key for the plug 'n play implicit layer registry
|
||||
@ -394,16 +457,16 @@ static inline const wchar_t *LoaderPnpELayerRegistryWide() {
|
||||
static inline const char *LoaderPnpILayerRegistry() {
|
||||
BOOL is_wow;
|
||||
IsWow64Process(GetCurrentProcess(), &is_wow);
|
||||
return is_wow ? "VulkanImplicitLayersWow" : "VulkanImplicitLayers";
|
||||
return is_wow ? "Vulkan" VK_VARIANT_REG_STR "ImplicitLayersWow" : "Vulkan" VK_VARIANT_REG_STR "ImplicitLayers";
|
||||
}
|
||||
static inline const wchar_t *LoaderPnpILayerRegistryWide() {
|
||||
BOOL is_wow;
|
||||
IsWow64Process(GetCurrentProcess(), &is_wow);
|
||||
return is_wow ? L"VulkanImplicitLayersWow" : L"VulkanImplicitLayers";
|
||||
return is_wow ? L"Vulkan" VK_VARIANT_REG_STR_W L"ImplicitLayersWow" : L"Vulkan" VK_VARIANT_REG_STR_W L"ImplicitLayers";
|
||||
}
|
||||
|
||||
// File IO
|
||||
static bool loader_platform_file_exists(const char *path) {
|
||||
static inline bool loader_platform_file_exists(const char *path) {
|
||||
int path_utf16_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
|
||||
if (path_utf16_size <= 0) {
|
||||
return false;
|
||||
@ -420,7 +483,7 @@ static bool loader_platform_file_exists(const char *path) {
|
||||
|
||||
// Returns true if the given string appears to be a relative or absolute
|
||||
// path, as opposed to a bare filename.
|
||||
static bool loader_platform_is_path_absolute(const char *path) {
|
||||
static inline bool loader_platform_is_path_absolute(const char *path) {
|
||||
if (!path || !*path) {
|
||||
return false;
|
||||
}
|
||||
@ -469,7 +532,7 @@ static inline char *loader_platform_executable_path(char *buffer, size_t size) {
|
||||
}
|
||||
|
||||
// Dynamic Loading:
|
||||
static loader_platform_dl_handle loader_platform_open_library(const char *lib_path) {
|
||||
static inline loader_platform_dl_handle loader_platform_open_library(const char *lib_path) {
|
||||
int lib_path_utf16_size = MultiByteToWideChar(CP_UTF8, 0, lib_path, -1, NULL, 0);
|
||||
if (lib_path_utf16_size <= 0) {
|
||||
return NULL;
|
||||
@ -486,32 +549,61 @@ static loader_platform_dl_handle loader_platform_open_library(const char *lib_pa
|
||||
}
|
||||
return lib_handle;
|
||||
}
|
||||
static const char *loader_platform_open_library_error(const char *libPath) {
|
||||
static inline const char *loader_platform_open_library_error(const char *libPath) {
|
||||
static char errorMsg[512];
|
||||
(void)snprintf(errorMsg, 511, "Failed to open dynamic library \"%s\" with error %lu", libPath, GetLastError());
|
||||
return errorMsg;
|
||||
}
|
||||
static void loader_platform_close_library(loader_platform_dl_handle library) { FreeLibrary(library); }
|
||||
static void *loader_platform_get_proc_address(loader_platform_dl_handle library, const char *name) {
|
||||
static inline void loader_platform_close_library(loader_platform_dl_handle library) {
|
||||
if (!loader_disable_dynamic_library_unloading) {
|
||||
FreeLibrary(library);
|
||||
} else {
|
||||
(void)library;
|
||||
}
|
||||
}
|
||||
static inline void *loader_platform_get_proc_address(loader_platform_dl_handle library, const char *name) {
|
||||
assert(library);
|
||||
assert(name);
|
||||
return (void *)GetProcAddress(library, name);
|
||||
}
|
||||
static const char *loader_platform_get_proc_address_error(const char *name) {
|
||||
static inline const char *loader_platform_get_proc_address_error(const char *name) {
|
||||
static char errorMsg[120];
|
||||
(void)snprintf(errorMsg, 119, "Failed to find function \"%s\" in dynamic library", name);
|
||||
return errorMsg;
|
||||
}
|
||||
|
||||
// Thread mutex:
|
||||
static void loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) { InitializeCriticalSection(pMutex); }
|
||||
static void loader_platform_thread_lock_mutex(loader_platform_thread_mutex *pMutex) { EnterCriticalSection(pMutex); }
|
||||
static void loader_platform_thread_unlock_mutex(loader_platform_thread_mutex *pMutex) { LeaveCriticalSection(pMutex); }
|
||||
static void loader_platform_thread_delete_mutex(loader_platform_thread_mutex *pMutex) { DeleteCriticalSection(pMutex); }
|
||||
static inline void loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) { InitializeCriticalSection(pMutex); }
|
||||
static inline void loader_platform_thread_lock_mutex(loader_platform_thread_mutex *pMutex) { EnterCriticalSection(pMutex); }
|
||||
static inline void loader_platform_thread_unlock_mutex(loader_platform_thread_mutex *pMutex) { LeaveCriticalSection(pMutex); }
|
||||
static inline void loader_platform_thread_delete_mutex(loader_platform_thread_mutex *pMutex) { DeleteCriticalSection(pMutex); }
|
||||
|
||||
static inline void *thread_safe_strtok(char *str, const char *delimiters, char **context) {
|
||||
return strtok_s(str, delimiters, context);
|
||||
}
|
||||
|
||||
static inline FILE *loader_fopen(const char *fileName, const char *mode) {
|
||||
FILE *file = NULL;
|
||||
errno_t err = fopen_s(&file, fileName, mode);
|
||||
if (err != 0) return NULL;
|
||||
return file;
|
||||
}
|
||||
|
||||
static inline char *loader_strncat(char *dest, size_t dest_sz, const char *src, size_t count) {
|
||||
errno_t err = strncat_s(dest, dest_sz, src, count);
|
||||
if (err != 0) return NULL;
|
||||
return dest;
|
||||
}
|
||||
|
||||
static inline char *loader_strncpy(char *dest, size_t dest_sz, const char *src, size_t count) {
|
||||
errno_t err = strncpy_s(dest, dest_sz, src, count);
|
||||
if (err != 0) return NULL;
|
||||
return dest;
|
||||
}
|
||||
|
||||
#else // defined(_WIN32)
|
||||
|
||||
#error The "vk_loader_platform.h" file must be modified for this OS.
|
||||
#warning The "vk_loader_platform.h" file must be modified for this OS.
|
||||
|
||||
// NOTE: In order to support another OS, an #elif needs to be added (above the
|
||||
// "#else // defined(_WIN32)") for that OS, and OS-specific versions of the
|
||||
|
@ -1,12 +1,10 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
|
||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
||||
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR_PC@
|
||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR_PC@
|
||||
|
||||
Name: @CMAKE_PROJECT_NAME@
|
||||
Name: Vulkan-Loader
|
||||
Description: Vulkan Loader
|
||||
Version: @VK_API_VERSION@
|
||||
Version: @VULKAN_LOADER_VERSION@
|
||||
Libs: -L${libdir} -lvulkan@VULKAN_LIB_SUFFIX@
|
||||
Libs.private: @PRIVATE_LIBS@
|
||||
Cflags: -I${includedir}
|
||||
|
||||
|
485
loader/wsi.c
485
loader/wsi.c
File diff suppressed because it is too large
Load Diff
48
loader/wsi.h
48
loader/wsi.h
@ -26,37 +26,37 @@
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
VkIcdSurfaceWayland wayland_surf;
|
||||
#endif // VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
VkIcdSurfaceWin32 win_surf;
|
||||
#endif // VK_USE_PLATFORM_WIN32_KHR
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
VkIcdSurfaceXcb xcb_surf;
|
||||
#endif // VK_USE_PLATFORM_XCB_KHR
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
VkIcdSurfaceXlib xlib_surf;
|
||||
#endif // VK_USE_PLATFORM_XLIB_KHR
|
||||
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
|
||||
VkIcdSurfaceDirectFB directfb_surf;
|
||||
#endif // VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#ifdef VK_USE_PLATFORM_MACOS_MVK
|
||||
#if defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
VkIcdSurfaceMacOS macos_surf;
|
||||
#endif // VK_USE_PLATFORM_MACOS_MVK
|
||||
#ifdef VK_USE_PLATFORM_GGP
|
||||
#if defined(VK_USE_PLATFORM_GGP)
|
||||
VkIcdSurfaceGgp ggp_surf;
|
||||
#endif // VK_USE_PLATFORM_GGP
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
VkIcdSurfaceImagePipe imagepipe_surf;
|
||||
#endif // VK_USE_PLATFORM_FUCHSIA
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
VkIcdSurfaceMetal metal_surf;
|
||||
#endif // VK_USE_PLATFORM_METAL_EXT
|
||||
#ifdef VK_USE_PLATFORM_SCREEN_QNX
|
||||
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
|
||||
VkIcdSurfaceScreen screen_surf;
|
||||
#endif // VK_USE_PLATFORM_SCREEN_QNX
|
||||
#ifdef VK_USE_PLATFORM_VI_NN
|
||||
#if defined(VK_USE_PLATFORM_VI_NN)
|
||||
VkIcdSurfaceVi vi_surf;
|
||||
#endif // VK_USE_PLATFORM_VI_NN
|
||||
VkIcdSurfaceDisplay display_surf;
|
||||
@ -103,13 +103,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModesKH
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface,
|
||||
VkDeviceGroupPresentModeFlagsKHR *pModes);
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
|
||||
uint32_t queueFamilyIndex);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(VkInstance instance,
|
||||
const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
@ -117,7 +117,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWaylandPresentationSu
|
||||
uint32_t queueFamilyIndex,
|
||||
struct wl_display *display);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
|
||||
@ -126,14 +126,14 @@ VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXcbPresentationSuppor
|
||||
xcb_connection_t *connection,
|
||||
xcb_visualid_t visual_id);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
|
||||
uint32_t queueFamilyIndex, Display *dpy,
|
||||
VisualID visualID);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDirectFBSurfaceEXT(VkInstance instance,
|
||||
const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
@ -141,15 +141,15 @@ VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceDirectFBPresentationS
|
||||
uint32_t queueFamilyIndex,
|
||||
IDirectFB *dfb);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_MACOS_MVK
|
||||
#if defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_IOS_MVK
|
||||
#if defined(VK_USE_PLATFORM_IOS_MVK)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_GGP
|
||||
#if defined(VK_USE_PLATFORM_GGP)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
@ -158,7 +158,7 @@ terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamD
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_SCREEN_QNX
|
||||
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateScreenSurfaceQNX(VkInstance instance,
|
||||
const VkScreenSurfaceCreateInfoQNX *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
@ -166,7 +166,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceScreenPresentationSup
|
||||
uint32_t queueFamilyIndex,
|
||||
struct _screen_window *window);
|
||||
#endif // VK_USE_PLATFORM_SCREEN_QNX
|
||||
#ifdef VK_USE_PLATFORM_VI_NN
|
||||
#if defined(VK_USE_PLATFORM_VI_NN)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
#endif // VK_USE_PLATFORM_VI_NN
|
||||
@ -216,20 +216,20 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModeProperties2KHR(VkPhysica
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,
|
||||
const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
|
||||
VkDisplayPlaneCapabilities2KHR *pCapabilities);
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#if defined(VK_USE_PLATFORM_FUCHSIA)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(VkInstance instance,
|
||||
const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkSurfaceKHR *pSurface);
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateAndroidSurfaceKHR(VkInstance instance,
|
||||
const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_OHOS
|
||||
#if defined(VK_USE_PLATFORM_OHOS)
|
||||
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSurfaceOHOS(VkInstance instance,
|
||||
const VkSurfaceCreateInfoOHOS* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
|
146
scripts/CMakeLists.txt
Normal file
146
scripts/CMakeLists.txt
Normal file
@ -0,0 +1,146 @@
|
||||
# ~~~
|
||||
# Copyright (c) 2023 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.
|
||||
# ~~~
|
||||
|
||||
option(UPDATE_DEPS "Run update_deps.py for user")
|
||||
if (UPDATE_DEPS)
|
||||
find_package(Python3 REQUIRED QUIET)
|
||||
|
||||
set(update_dep_py "${CMAKE_CURRENT_LIST_DIR}/update_deps.py")
|
||||
set(known_good_json "${CMAKE_CURRENT_LIST_DIR}/known_good.json")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${update_dep_py} ${known_good_json})
|
||||
|
||||
list(APPEND update_dep_command "${update_dep_py}")
|
||||
list(APPEND update_dep_command "--generator")
|
||||
list(APPEND update_dep_command "${CMAKE_GENERATOR}")
|
||||
|
||||
if (CMAKE_GENERATOR_PLATFORM)
|
||||
list(APPEND update_dep_command "--arch")
|
||||
list(APPEND update_dep_command "${CMAKE_GENERATOR_PLATFORM}")
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_OSX_ARCHITECTURES}" MATCHES ";")
|
||||
list(APPEND update_dep_command "--osx-archs")
|
||||
string(REPLACE ";" ":" osx_archs "${CMAKE_OSX_ARCHITECTURES}")
|
||||
list(APPEND update_dep_command "${osx_archs}")
|
||||
|
||||
set(APPLE_UNIVERSAL_BINARY ON)
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
message(WARNING "CMAKE_BUILD_TYPE not set. Using Debug for dependency build type")
|
||||
set(_build_type Debug)
|
||||
else()
|
||||
set(_build_type ${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
list(APPEND update_dep_command "--config")
|
||||
list(APPEND update_dep_command "${_build_type}")
|
||||
list(APPEND update_dep_command "--api")
|
||||
list(APPEND update_dep_command "${API_TYPE}")
|
||||
|
||||
set(UPDATE_DEPS_DIR_SUFFIX "${_build_type}")
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
if (APPLE_UNIVERSAL_BINARY)
|
||||
set(UPDATE_DEPS_DIR_SUFFIX "${CMAKE_SYSTEM_NAME}/${UPDATE_DEPS_DIR_SUFFIX}/universal")
|
||||
else()
|
||||
set(UPDATE_DEPS_DIR_SUFFIX "${CMAKE_SYSTEM_NAME}/${UPDATE_DEPS_DIR_SUFFIX}/${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
else()
|
||||
if (APPLE_UNIVERSAL_BINARY)
|
||||
set(UPDATE_DEPS_DIR_SUFFIX "${UPDATE_DEPS_DIR_SUFFIX}/universal")
|
||||
else()
|
||||
math(EXPR bitness "8 * ${CMAKE_SIZEOF_VOID_P}")
|
||||
set(UPDATE_DEPS_DIR_SUFFIX "${UPDATE_DEPS_DIR_SUFFIX}/${bitness}")
|
||||
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}")
|
||||
|
||||
if (NOT BUILD_TESTS)
|
||||
list(APPEND update_dep_command "--optional=tests")
|
||||
endif()
|
||||
|
||||
if (UPDATE_DEPS_SKIP_EXISTING_INSTALL)
|
||||
list(APPEND update_dep_command "--skip-existing-install")
|
||||
endif()
|
||||
|
||||
list(APPEND cmake_vars "CMAKE_TOOLCHAIN_FILE")
|
||||
|
||||
# Avoids manually setting CMAKE_SYSTEM_NAME unless it's needed:
|
||||
# https://cmake.org/cmake/help/latest/variable/CMAKE_CROSSCOMPILING.html
|
||||
if (NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "${CMAKE_HOST_SYSTEM_NAME}")
|
||||
list(APPEND cmake_vars "CMAKE_SYSTEM_NAME")
|
||||
endif()
|
||||
if (APPLE)
|
||||
list(APPEND cmake_vars "CMAKE_OSX_DEPLOYMENT_TARGET")
|
||||
endif()
|
||||
if (NOT MSVC_IDE)
|
||||
list(APPEND cmake_vars "CMAKE_CXX_COMPILER" "CMAKE_C_COMPILER" "CMAKE_ASM_COMPILER")
|
||||
endif()
|
||||
if (ANDROID)
|
||||
list(APPEND cmake_vars "ANDROID_PLATFORM" "CMAKE_ANDROID_ARCH_ABI" "CMAKE_ANDROID_STL_TYPE" "CMAKE_ANDROID_RTTI" "CMAKE_ANDROID_EXCEPTIONS" "ANDROID_USE_LEGACY_TOOLCHAIN_FILE")
|
||||
endif()
|
||||
|
||||
set(cmake_var)
|
||||
foreach(var IN LISTS cmake_vars)
|
||||
if (DEFINED ${var})
|
||||
list(APPEND update_dep_command "--cmake_var")
|
||||
list(APPEND update_dep_command "${var}=${${var}}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (cmake_var)
|
||||
list(APPEND update_dep_command "${cmake_var}")
|
||||
endif()
|
||||
|
||||
file(TIMESTAMP ${update_dep_py} timestamp_1)
|
||||
file(TIMESTAMP ${known_good_json} timestamp_2)
|
||||
|
||||
string("MD5" md5_hash "${timestamp_1}-${timestamp_2}-${update_dep_command}")
|
||||
|
||||
set(UPDATE_DEPS_HASH "0" CACHE STRING "Default value until we run update_deps.py")
|
||||
mark_as_advanced(UPDATE_DEPS_HASH)
|
||||
|
||||
if ("${UPDATE_DEPS_HASH}" STREQUAL "0")
|
||||
list(APPEND update_dep_command "--clean-build")
|
||||
list(APPEND update_dep_command "--clean-install")
|
||||
endif()
|
||||
|
||||
if ("${md5_hash}" STREQUAL $CACHE{UPDATE_DEPS_HASH})
|
||||
message(DEBUG "update_deps.py: no work to do.")
|
||||
else()
|
||||
execute_process(
|
||||
COMMAND ${Python3_EXECUTABLE} ${update_dep_command}
|
||||
RESULT_VARIABLE _update_deps_result
|
||||
)
|
||||
if (NOT (${_update_deps_result} EQUAL 0))
|
||||
message(FATAL_ERROR "Could not run update_deps.py which is necessary to download dependencies.")
|
||||
endif()
|
||||
set(UPDATE_DEPS_HASH ${md5_hash} CACHE STRING "Ensure we only run update_deps.py when we need to." FORCE)
|
||||
include("${UPDATE_DEPS_DIR}/helper.cmake")
|
||||
endif()
|
||||
endif()
|
||||
if (VULKAN_HEADERS_INSTALL_DIR)
|
||||
list(APPEND CMAKE_PREFIX_PATH ${VULKAN_HEADERS_INSTALL_DIR})
|
||||
set(CMAKE_REQUIRE_FIND_PACKAGE_VulkanHeaders TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
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()
|
@ -1,41 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) 2017 Google Inc.
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Script to determine if source code in Pull Request is properly formatted.
|
||||
# Exits with non 0 exit code if formatting is needed.
|
||||
#
|
||||
# This script assumes to be invoked at the project root directory.
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
FILES_TO_CHECK=$(git diff --name-only master | grep -v -E "^include/vulkan" | grep -E ".*\.(cpp|cc|c\+\+|cxx|c|h|hpp)$")
|
||||
|
||||
if [ -z "${FILES_TO_CHECK}" ]; then
|
||||
echo -e "${GREEN}No source code to check for formatting.${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
FORMAT_DIFF=$(git diff -U0 master -- ${FILES_TO_CHECK} | python ./scripts/clang-format-diff.py -p1 -style=file)
|
||||
|
||||
if [ -z "${FORMAT_DIFF}" ]; then
|
||||
echo -e "${GREEN}All source code in PR properly formatted.${NC}"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}Found formatting errors!${NC}"
|
||||
echo "${FORMAT_DIFF}"
|
||||
exit 1
|
||||
fi
|
@ -1,102 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) 2018 Valve Corporation
|
||||
# Copyright (c) 2018 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.
|
||||
#
|
||||
# Checks commit messages against project standards in CONTRIBUTING.md document
|
||||
# Script to determine if commit messages in Pull Request are properly formatted.
|
||||
# Exits with non 0 exit code if reformatting is needed.
|
||||
|
||||
# Disable subshells
|
||||
shopt -s lastpipe
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# TRAVIS_COMMIT_RANGE contains range of commits for this PR
|
||||
|
||||
# Get user-supplied commit message text for applicable commits and insert
|
||||
# a unique separator string identifier. The git command returns ONLY the
|
||||
# subject line and body for each of the commits.
|
||||
COMMIT_TEXT=$(git log ${TRAVIS_COMMIT_RANGE} --pretty=format:"XXXNEWLINEXXX"%n%B)
|
||||
|
||||
# Bail if there are none
|
||||
if [ -z "${COMMIT_TEXT}" ]; then
|
||||
echo -e "${GREEN}No commit messgages to check for formatting.${NC}"
|
||||
exit 0
|
||||
elif ! echo $TRAVIS_COMMIT_RANGE | grep -q "\.\.\."; then
|
||||
echo -e "${GREEN}No commit messgages to check for formatting.${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Process commit messages
|
||||
success=1
|
||||
current_line=0
|
||||
prevline=""
|
||||
|
||||
# Process each line of the commit message output, resetting counter on separator
|
||||
printf %s "$COMMIT_TEXT" | while IFS='' read -r line; do
|
||||
# echo "Count = $current_line <Line> = $line"
|
||||
current_line=$((current_line+1))
|
||||
if [ "$line" = "XXXNEWLINEXXX" ]; then
|
||||
current_line=0
|
||||
fi
|
||||
chars=${#line}
|
||||
if [ $current_line -eq 1 ]; then
|
||||
# Subject line should be 50 chars or less (but give some slack here)
|
||||
if [ $chars -gt 54 ]; then
|
||||
echo "The following subject line exceeds 50 characters in length."
|
||||
echo " '$line'"
|
||||
success=0
|
||||
fi
|
||||
i=$(($chars-1))
|
||||
last_char=${line:$i:1}
|
||||
# Output error if last char of subject line is not alpha-numeric
|
||||
if [[ ! $last_char =~ [0-9a-zA-Z] ]]; then
|
||||
echo "For the following commit, the last character of the subject line must not be non-alphanumeric."
|
||||
echo " '$line'"
|
||||
success=0
|
||||
fi
|
||||
# Checking if subject line doesn't start with 'module: '
|
||||
prefix=$(echo $line | cut -f1 -d " ")
|
||||
if [ "${prefix: -1}" != ":" ]; then
|
||||
echo "The following subject line must start with a single word specifying the functional area of the change, followed by a colon and space. I.e., 'layers: Subject line here'"
|
||||
echo " '$line'"
|
||||
success=0
|
||||
fi
|
||||
elif [ $current_line -eq 2 ]; then
|
||||
# Commit message must have a blank line between subject and body
|
||||
if [ $chars -ne 0 ]; then
|
||||
echo "The following subject line must be followed by a blank line."
|
||||
echo " '$prevline'"
|
||||
success=0
|
||||
fi
|
||||
else
|
||||
# Lines in a commit message body must be less than 72 characters in length (but give some slack)
|
||||
if [ $chars -gt 76 ]; then
|
||||
echo "The following commit message body line exceeds the 72 character limit."
|
||||
echo "'$line\'"
|
||||
success=0
|
||||
fi
|
||||
fi
|
||||
prevline=$line
|
||||
done
|
||||
|
||||
if [ $success -eq 1 ]; then
|
||||
echo -e "${GREEN}All commit messages in pull request are properly formatted.${NC}"
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
@ -103,7 +103,7 @@ class DispatchTableHelperOutputGenerator(OutputGenerator):
|
||||
write(s, file=self.outFile)
|
||||
# File Comment
|
||||
file_comment = '// *** THIS FILE IS GENERATED - DO NOT EDIT ***\n'
|
||||
file_comment += '// See dispatch_helper_generator.py for modifications\n'
|
||||
file_comment += '// See dispatch_table_helper_generator.py for modifications\n'
|
||||
write(file_comment, file=self.outFile)
|
||||
# Copyright Notice
|
||||
copyright = '/*\n'
|
||||
@ -132,7 +132,7 @@ class DispatchTableHelperOutputGenerator(OutputGenerator):
|
||||
preamble += '#include <vulkan/vulkan.h>\n'
|
||||
preamble += '#include <vulkan/vk_layer.h>\n'
|
||||
preamble += '#include <string.h>\n'
|
||||
preamble += '#include "vk_layer_dispatch_table.h"\n'
|
||||
preamble += '#include "loader/generated/vk_layer_dispatch_table.h"\n'
|
||||
|
||||
write(copyright, file=self.outFile)
|
||||
write(preamble, file=self.outFile)
|
||||
@ -183,27 +183,6 @@ class DispatchTableHelperOutputGenerator(OutputGenerator):
|
||||
return
|
||||
if handle_type != 'VkInstance' and handle_type != 'VkPhysicalDevice' and name != 'vkGetInstanceProcAddr':
|
||||
self.device_dispatch_list.append((name, self.featureExtraProtect))
|
||||
if "VK_VERSION" not in self.featureName and self.extension_type == 'device':
|
||||
self.device_extension_list.append(name)
|
||||
# Build up stub function
|
||||
decl = self.makeCDecls(cmdinfo.elem)[1]
|
||||
return_type = cmdinfo.elem.find('proto/type').text
|
||||
return_statement = "" # default type is void, so no return type
|
||||
try:
|
||||
return_statement = 'return ' + return_type_table[return_type] + ';'
|
||||
except KeyError:
|
||||
if return_type != "void":
|
||||
raise AssertionError("return_type_table does not contain all possible types. Add an entry for `" + return_type + "`.")
|
||||
decl = decl.split('*PFN_vk')[1]
|
||||
decl = decl.replace(')(', '(')
|
||||
decl = 'static VKAPI_ATTR ' + return_type + ' VKAPI_CALL Stub' + decl
|
||||
func_body = ' { ' + return_statement + ' }'
|
||||
decl = decl.replace (';', func_body)
|
||||
if self.featureExtraProtect is not None:
|
||||
self.dev_ext_stub_list.append('#ifdef %s' % self.featureExtraProtect)
|
||||
self.dev_ext_stub_list.append(decl)
|
||||
if self.featureExtraProtect is not None:
|
||||
self.dev_ext_stub_list.append('#endif // %s' % self.featureExtraProtect)
|
||||
else:
|
||||
self.instance_dispatch_list.append((name, self.featureExtraProtect))
|
||||
return
|
||||
@ -240,7 +219,7 @@ class DispatchTableHelperOutputGenerator(OutputGenerator):
|
||||
base_name = item[0][2:]
|
||||
|
||||
if item[1] is not None:
|
||||
table += '#ifdef %s\n' % item[1]
|
||||
table += '#if defined(%s)\n' % item[1]
|
||||
|
||||
# If we're looking for the proc we are passing in, just point the table to it. This fixes the issue where
|
||||
# a layer overrides the function name for the loader.
|
||||
@ -250,9 +229,6 @@ class DispatchTableHelperOutputGenerator(OutputGenerator):
|
||||
table += ' table->GetInstanceProcAddr = gpa;\n'
|
||||
else:
|
||||
table += ' table->%s = (PFN_%s) gpa(%s, "%s");\n' % (base_name, item[0], table_type, item[0])
|
||||
if item[0] in self.device_extension_list:
|
||||
stub_check = ' if (table->%s == nullptr) { table->%s = (PFN_%s)Stub%s; }\n' % (base_name, base_name, item[0], base_name)
|
||||
table += stub_check
|
||||
if item[1] is not None:
|
||||
table += '#endif // %s\n' % item[1]
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
# Copyright (c) 2019 Valve Corporation
|
||||
# Copyright (c) 2019 LunarG, Inc.
|
||||
# Copyright (c) 2019 Google Inc.
|
||||
# Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# Copyright (c) 2023-2023 RasterGrid Kft.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -26,13 +28,17 @@ import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
# files to exclude from --verify check
|
||||
verify_exclude = ['.clang-format']
|
||||
import datetime
|
||||
import re
|
||||
|
||||
def main(argv):
|
||||
parser = argparse.ArgumentParser(description='Generate source code for this repository')
|
||||
parser.add_argument('registry', metavar='REGISTRY_PATH', help='path to the Vulkan-Headers registry directory')
|
||||
parser.add_argument('--api',
|
||||
default='vulkan',
|
||||
choices=['vulkan'],
|
||||
help='Specify API name to generate')
|
||||
parser.add_argument('--generated-version', help='sets the header version used to generate the repo')
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument('-i', '--incremental', action='store_true', help='only update repo files that change')
|
||||
group.add_argument('-v', '--verify', action='store_true', help='verify repo files match generator output')
|
||||
@ -41,19 +47,17 @@ def main(argv):
|
||||
gen_cmds = [[common_codegen.repo_relative('scripts/loader_genvk.py'),
|
||||
'-registry', os.path.abspath(os.path.join(args.registry, 'vk.xml')),
|
||||
'-quiet',
|
||||
filename] for filename in ['vk_dispatch_table_helper.h',
|
||||
'vk_layer_dispatch_table.h',
|
||||
filename] for filename in ['vk_layer_dispatch_table.h',
|
||||
'vk_loader_extensions.h',
|
||||
'vk_loader_extensions.c',
|
||||
'vk_object_types.h',
|
||||
'loader_generated_header_version.cmake']]
|
||||
'vk_object_types.h']]
|
||||
|
||||
repo_dir = common_codegen.repo_relative('loader/generated')
|
||||
|
||||
# get directory where generators will run
|
||||
if args.verify or args.incremental:
|
||||
# generate in temp directory so we can compare or copy later
|
||||
temp_obj = tempfile.TemporaryDirectory(prefix='VulkanLoader_generated_source_')
|
||||
temp_obj = tempfile.TemporaryDirectory(prefix='loader_codegen_')
|
||||
temp_dir = temp_obj.name
|
||||
gen_dir = temp_dir
|
||||
else:
|
||||
@ -78,7 +82,7 @@ def main(argv):
|
||||
temp_files = set(os.listdir(temp_dir))
|
||||
repo_files = set(os.listdir(repo_dir))
|
||||
files_match = True
|
||||
for filename in sorted((temp_files | repo_files) - set(verify_exclude)):
|
||||
for filename in sorted((temp_files | repo_files)):
|
||||
if filename not in repo_files:
|
||||
print('ERROR: Missing repo file', filename)
|
||||
files_match = False
|
||||
@ -107,6 +111,26 @@ def main(argv):
|
||||
print('update', repo_filename)
|
||||
shutil.copyfile(temp_filename, repo_filename)
|
||||
|
||||
# write out the header version used to generate the code to a checked in CMake file
|
||||
if args.generated_version:
|
||||
# Update the CMake project version
|
||||
with open(common_codegen.repo_relative('CMakeLists.txt'), "r+") as f:
|
||||
data = f.read()
|
||||
f.seek(0)
|
||||
f.write(re.sub("project.*VERSION.*", f"project(VULKAN_LOADER VERSION {args.generated_version} LANGUAGES C)", data))
|
||||
f.truncate()
|
||||
|
||||
with open(common_codegen.repo_relative('loader/loader.rc.in'), "r") as rc_file:
|
||||
rc_file_contents = rc_file.read()
|
||||
rc_ver = ', '.join(args.generated_version.split('.') + ['0'])
|
||||
rc_file_contents = rc_file_contents.replace('${LOADER_VER_FILE_VERSION}', f'{rc_ver}')
|
||||
rc_file_contents = rc_file_contents.replace('${LOADER_VER_FILE_DESCRIPTION_STR}', f'"{args.generated_version}.Dev Build"')
|
||||
rc_file_contents = rc_file_contents.replace('${LOADER_VER_FILE_VERSION_STR}', f'"Vulkan Loader - Dev Build"')
|
||||
rc_file_contents = rc_file_contents.replace('${LOADER_CUR_COPYRIGHT_YEAR}', f'{datetime.date.today().year}')
|
||||
with open(common_codegen.repo_relative('loader/loader.rc'), "w") as rc_file_out:
|
||||
rc_file_out.write(rc_file_contents)
|
||||
rc_file_out.close()
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
68
scripts/gn/DEPS
Normal file
68
scripts/gn/DEPS
Normal file
@ -0,0 +1,68 @@
|
||||
gclient_gn_args_file = 'build/config/gclient_args.gni'
|
||||
|
||||
vars = {
|
||||
'chromium_git': 'https://chromium.googlesource.com',
|
||||
'ninja_version': 'version:2@1.11.1.chromium.6',
|
||||
}
|
||||
|
||||
deps = {
|
||||
|
||||
'build': {
|
||||
'url': '{chromium_git}/chromium/src/build.git@1015724d82945f9ef7e51c6f804034ccf5f79951',
|
||||
},
|
||||
|
||||
'buildtools': {
|
||||
'url': '{chromium_git}/chromium/src/buildtools.git@3c7e3f1b8b1e4c0b6ec693430379cea682de78d6',
|
||||
},
|
||||
|
||||
'buildtools/linux64': {
|
||||
'packages': [
|
||||
{
|
||||
'package': 'gn/gn/linux-${{arch}}',
|
||||
'version': 'git_revision:5e19d2fb166fbd4f6f32147fbb2f497091a54ad8',
|
||||
}
|
||||
],
|
||||
'dep_type': 'cipd',
|
||||
'condition': 'host_os == "linux"',
|
||||
},
|
||||
|
||||
'testing': {
|
||||
'url': '{chromium_git}/chromium/src/testing@949b2864b6bd27656753b917c9aa7731dc7a06f6',
|
||||
},
|
||||
|
||||
'tools/clang': {
|
||||
'url': '{chromium_git}/chromium/src/tools/clang.git@566877f1ff1a5fa6beaca3ab4b47bd0b92eb614f',
|
||||
},
|
||||
|
||||
'third_party/ninja': {
|
||||
'packages': [
|
||||
{
|
||||
'package': 'infra/3pp/tools/ninja/${{platform}}',
|
||||
'version': Var('ninja_version'),
|
||||
}
|
||||
],
|
||||
'dep_type': 'cipd',
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
hooks = [
|
||||
{
|
||||
'name': 'sysroot_x64',
|
||||
'pattern': '.',
|
||||
'condition': 'checkout_linux and checkout_x64',
|
||||
'action': ['python3', 'build/linux/sysroot_scripts/install-sysroot.py',
|
||||
'--arch=x64'],
|
||||
},
|
||||
{
|
||||
# Note: On Win, this should run after win_toolchain, as it may use it.
|
||||
'name': 'clang',
|
||||
'pattern': '.',
|
||||
'action': ['python3', 'tools/clang/scripts/update.py'],
|
||||
},
|
||||
]
|
||||
|
||||
recursedeps = [
|
||||
# buildtools provides clang_format.
|
||||
'buildtools',
|
||||
]
|
56
scripts/gn/gn.py
Normal file
56
scripts/gn/gn.py
Normal file
@ -0,0 +1,56 @@
|
||||
#!/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 os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
# helper to define paths relative to the repo root
|
||||
def RepoRelative(path):
|
||||
return os.path.abspath(os.path.join(os.path.dirname(__file__), '../../', path))
|
||||
|
||||
def BuildGn():
|
||||
if not os.path.exists(RepoRelative("depot_tools")):
|
||||
print("Cloning Chromium depot_tools\n", flush=True)
|
||||
clone_cmd = 'git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git depot_tools'.split(" ")
|
||||
subprocess.call(clone_cmd)
|
||||
|
||||
os.environ['PATH'] = os.environ.get('PATH') + ":" + RepoRelative("depot_tools")
|
||||
|
||||
print("Updating Repo Dependencies and GN Toolchain\n", flush=True)
|
||||
update_cmd = './scripts/gn/update_deps.sh'
|
||||
subprocess.call(update_cmd)
|
||||
|
||||
print("Checking Header Dependencies\n", flush=True)
|
||||
gn_check_cmd = 'gn gen --check out/Debug'.split(" ")
|
||||
subprocess.call(gn_check_cmd)
|
||||
|
||||
print("Generating Ninja Files\n", flush=True)
|
||||
gn_gen_cmd = 'gn gen out/Debug'.split(" ")
|
||||
subprocess.call(gn_gen_cmd)
|
||||
|
||||
print("Running Ninja Build\n", flush=True)
|
||||
ninja_build_cmd = 'ninja -C out/Debug'.split(" ")
|
||||
subprocess.call(ninja_build_cmd)
|
||||
|
||||
#
|
||||
# Module Entrypoint
|
||||
def main():
|
||||
try:
|
||||
BuildGn()
|
||||
|
||||
except subprocess.CalledProcessError as proc_error:
|
||||
print('Command "%s" failed with return code %s' % (' '.join(proc_error.cmd), proc_error.returncode))
|
||||
sys.exit(proc_error.returncode)
|
||||
except Exception as unknown_error:
|
||||
print('An unkown error occured: %s', unknown_error)
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user