use Zig build system
This commit is contained in:
parent
63af1cf1ee
commit
e44309e935
33 changed files with 22 additions and 116558 deletions
16
.gitattributes
vendored
16
.gitattributes
vendored
|
|
@ -1,16 +0,0 @@
|
|||
# See https://git-scm.com/docs/gitattributes
|
||||
# See https://help.github.com/articles/dealing-with-line-endings/
|
||||
|
||||
# Default behavior, if core.autocrlf is unset.
|
||||
* text=auto
|
||||
|
||||
# Files to be converted to native line endings on checkout.
|
||||
*.cpp text
|
||||
*.h text
|
||||
|
||||
# Text files to always have CRLF (dos) line endings on checkout.
|
||||
*.bat text eol=crlf
|
||||
|
||||
# Text files to always have LF (unix) line endings on checkout.
|
||||
*.sh text eol=lf
|
||||
|
||||
54
.github/ISSUE_TEMPLATE/bug_report.md
vendored
54
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -1,54 +0,0 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is this issue appropriate for the repository?**
|
||||
|
||||
Vulkan-Headers exists as a publishing mechanism for headers and related material sourced from multiple other repositories. If you have a problem with that material, it should *not* be reported here, but in the appropriate repository:
|
||||
|
||||
This repository is responsible for the following files
|
||||
|
||||
* BUILD.gn
|
||||
* BUILD.md
|
||||
* cmake/
|
||||
* CMakeLists.txt
|
||||
* tests/*
|
||||
* CODE_OF_CONDUCT.md
|
||||
* INTEGRATION.md
|
||||
* LICENSE.txt
|
||||
* README.md
|
||||
* Non-API headers
|
||||
* include/vulkan/vk_icd.h
|
||||
* include/vulkan/vk_layer.h
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
A clear and concise description of what the bug is. Please refer to specific files that are only in this repository, not copied from Vulkan-Docs or Vulkan-Hpp.
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
**Code**
|
||||
|
||||
<details>
|
||||
<summary>code or terminal output</summary>
|
||||
|
||||
```cpp
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
20
.github/pull_request_template.md
vendored
20
.github/pull_request_template.md
vendored
|
|
@ -1,20 +0,0 @@
|
|||
<!-- Please note when contributing what files this repository actually is responsible for.
|
||||
|
||||
Vulkan-Headers exists as a publishing mechanism for headers and related material sourced from multiple other repositories. If you have a problem with that material, it should *not* be reported here, but in the appropriate repository:
|
||||
|
||||
This repository is responsible for the following files
|
||||
|
||||
* BUILD.gn
|
||||
* BUILD.md
|
||||
* cmake/
|
||||
* CMakeLists.txt
|
||||
* tests/*
|
||||
* CODE_OF_CONDUCT.md
|
||||
* INTEGRATION.md
|
||||
* LICENSE.txt
|
||||
* README.md
|
||||
* Non-API headers
|
||||
* include/vulkan/vk_icd.h
|
||||
* include/vulkan/vk_layer.h
|
||||
|
||||
-->
|
||||
60
.github/workflows/linux.yml
vendored
60
.github/workflows/linux.yml
vendored
|
|
@ -1,60 +0,0 @@
|
|||
# Copyright (c) 2022-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: Linux
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
ubuntu-cmake-install:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: lukka/get-cmake@latest
|
||||
with:
|
||||
cmakeVersion: 3.17.0
|
||||
- name: Configure Vulkan-Headers
|
||||
run: cmake -S . -B build -G "Ninja"
|
||||
- name: Install Vulkan-Headers
|
||||
run: cmake --install build --prefix ${{ github.workspace }}/build/install
|
||||
- name: Test Vulkan-Headers find_package support
|
||||
run: cmake -S tests/find_package -B build/tests/find_package -D CMAKE_PREFIX_PATH=${{ github.workspace }}/build/install
|
||||
|
||||
ubuntu-cmake-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: lukka/get-cmake@latest
|
||||
with:
|
||||
cmakeVersion: 3.25.0
|
||||
- name: Configure Vulkan-Headers
|
||||
run: cmake -S . -B build -D BUILD_TESTS=ON --log-level=DEBUG -G "Ninja"
|
||||
- name: Build Vulkan-Headers Tests
|
||||
run: cmake --build build
|
||||
|
||||
test-cmake-minimum:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: lukka/get-cmake@latest
|
||||
with:
|
||||
cmakeVersion: 3.15.0
|
||||
- name: Configure Vulkan-Headers
|
||||
run: cmake -S . -B build/ -G "Ninja" --loglevel=DEBUG
|
||||
- name: Install Vulkan-Headers
|
||||
run: cmake --install build/ --prefix build/install
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
|
|
@ -1,6 +1 @@
|
|||
# Python cache
|
||||
__pycache__
|
||||
*.pyc
|
||||
build
|
||||
.vscode/
|
||||
**/.*.swp
|
||||
zig-*
|
||||
|
|
|
|||
72
BUILD.gn
72
BUILD.gn
|
|
@ -1,72 +0,0 @@
|
|||
# Copyright (C) 2018-2023 The ANGLE Project Authors.
|
||||
# Copyright (C) 2019-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
|
||||
#
|
||||
# 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.
|
||||
|
||||
import("//build_overrides/vulkan_headers.gni")
|
||||
|
||||
config("vulkan_headers_config") {
|
||||
include_dirs = [ "include" ]
|
||||
defines = []
|
||||
|
||||
if (is_win) {
|
||||
defines += [ "VK_USE_PLATFORM_WIN32_KHR" ]
|
||||
}
|
||||
if (defined(vulkan_use_x11) && vulkan_use_x11) {
|
||||
defines += [ "VK_USE_PLATFORM_XCB_KHR" ]
|
||||
}
|
||||
if (defined(vulkan_use_wayland) && vulkan_use_wayland) {
|
||||
defines += [ "VK_USE_PLATFORM_WAYLAND_KHR" ]
|
||||
if (defined(vulkan_wayland_include_dirs)) {
|
||||
include_dirs += vulkan_wayland_include_dirs
|
||||
}
|
||||
}
|
||||
if (is_android) {
|
||||
defines += [ "VK_USE_PLATFORM_ANDROID_KHR" ]
|
||||
}
|
||||
if (is_fuchsia) {
|
||||
defines += [ "VK_USE_PLATFORM_FUCHSIA" ]
|
||||
}
|
||||
if (is_mac) {
|
||||
defines += [ "VK_USE_PLATFORM_METAL_EXT" ]
|
||||
}
|
||||
if (defined(is_ggp) && is_ggp) {
|
||||
defines += [ "VK_USE_PLATFORM_GGP" ]
|
||||
}
|
||||
if (is_clang) {
|
||||
cflags = [
|
||||
"-Wno-redundant-parens",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# Vulkan headers only, no compiled sources.
|
||||
source_set("vulkan_headers") {
|
||||
sources = [
|
||||
"include/vulkan/vk_icd.h",
|
||||
"include/vulkan/vk_layer.h",
|
||||
"include/vulkan/vk_platform.h",
|
||||
"include/vulkan/vulkan.h",
|
||||
"include/vulkan/vulkan.hpp",
|
||||
"include/vulkan/vulkan_core.h",
|
||||
"include/vulkan/vulkan_screen.h",
|
||||
"include/vk_video/vulkan_video_codec_h264std_decode.h",
|
||||
"include/vk_video/vulkan_video_codec_h264std_encode.h",
|
||||
"include/vk_video/vulkan_video_codec_h264std.h",
|
||||
"include/vk_video/vulkan_video_codec_h265std_decode.h",
|
||||
"include/vk_video/vulkan_video_codec_h265std_encode.h",
|
||||
"include/vk_video/vulkan_video_codec_h265std.h",
|
||||
"include/vk_video/vulkan_video_codecs_common.h",
|
||||
]
|
||||
public_configs = [ ":vulkan_headers_config" ]
|
||||
}
|
||||
42
BUILD.md
42
BUILD.md
|
|
@ -1,42 +0,0 @@
|
|||
# Build Instructions
|
||||
|
||||
Instructions for building this repository.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
|
||||
cd Vulkan-Headers/
|
||||
|
||||
# Configure the project
|
||||
cmake -S . -B build/
|
||||
|
||||
# Because Vulkan-Headers is header only we don't need to build anything.
|
||||
# Users can install it where they need to.
|
||||
cmake --install build --prefix build/install
|
||||
```
|
||||
|
||||
See the official [CMake documentation](https://cmake.org/cmake/help/latest/index.html) for more information.
|
||||
|
||||
## Installed Files
|
||||
|
||||
The `install` target installs the following files under the directory
|
||||
indicated by *install_dir*:
|
||||
|
||||
- *install_dir*`/include/vulkan` : The header files found in the
|
||||
`include/vulkan` directory of this repository
|
||||
- *install_dir*`/share/cmake/VulkanHeaders`: The CMake config files needed
|
||||
for find_package support
|
||||
- *install_dir*`/share/vulkan/registry` : The registry files found in the
|
||||
`registry` directory of this repository
|
||||
|
||||
## Usage in CMake
|
||||
|
||||
```cmake
|
||||
find_package(VulkanHeaders REQUIRED CONFIG)
|
||||
|
||||
target_link_libraries(foobar PRIVATE Vulkan::Headers)
|
||||
|
||||
message(STATUS "Vulkan Headers Registry: ${VULKAN_HEADERS_REGISTRY_DIRECTORY}")
|
||||
|
||||
message(STATUS "Vulkan Headers Version: ${VulkanHeaders_VERSION}")
|
||||
```
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
# ~~~
|
||||
# Copyright (c) 2018-2023 Valve Corporation
|
||||
# Copyright (c) 2018-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.
|
||||
# ~~~
|
||||
cmake_minimum_required(VERSION 3.15...3.25)
|
||||
|
||||
function(vlk_get_header_version)
|
||||
set(vulkan_core_header_file "${CMAKE_CURRENT_SOURCE_DIR}/include/vulkan/vulkan_core.h")
|
||||
if (NOT EXISTS ${vulkan_core_header_file})
|
||||
message(FATAL_ERROR "Couldn't find vulkan_core.h!")
|
||||
endif()
|
||||
|
||||
file(READ ${vulkan_core_header_file} ver)
|
||||
|
||||
if (ver MATCHES "#define[ ]+VK_HEADER_VERSION_COMPLETE[ ]+VK_MAKE_API_VERSION\\([ ]*[0-9]+,[ ]*([0-9]+),[ ]*([0-9]+),[ ]*VK_HEADER_VERSION[ ]*\\)")
|
||||
set(MAJOR_VERSION "${CMAKE_MATCH_1}")
|
||||
set(MINOR_VERSION "${CMAKE_MATCH_2}")
|
||||
else()
|
||||
message(FATAL_ERROR "Couldn't get major/minor version")
|
||||
endif()
|
||||
|
||||
if (ver MATCHES "#define[ ]+VK_HEADER_VERSION[ ]+([0-9]+)")
|
||||
set(PATCH_VERSION "${CMAKE_MATCH_1}")
|
||||
else()
|
||||
message(FATAL_ERROR "Couldn't get the patch version")
|
||||
endif()
|
||||
|
||||
set(VK_VERSION_STRING "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
vlk_get_header_version()
|
||||
|
||||
project(VULKAN_HEADERS LANGUAGES C VERSION ${VK_VERSION_STRING})
|
||||
|
||||
add_library(Vulkan-Headers INTERFACE)
|
||||
add_library(Vulkan::Headers ALIAS Vulkan-Headers)
|
||||
target_include_directories(Vulkan-Headers INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS "3.21")
|
||||
# https://cmake.org/cmake/help/latest/variable/PROJECT_IS_TOP_LEVEL.html
|
||||
string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_TOP_LEVEL)
|
||||
endif()
|
||||
|
||||
if (PROJECT_IS_TOP_LEVEL)
|
||||
option(BUILD_TESTS "Build the tests")
|
||||
if (BUILD_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
set(VLK_REGISTRY_DIR "${CMAKE_INSTALL_DATADIR}/vulkan")
|
||||
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/vk_video" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/vulkan" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
# Preserve source permissions https://github.com/KhronosGroup/Vulkan-Headers/issues/336
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/registry" DESTINATION ${VLK_REGISTRY_DIR} USE_SOURCE_PERMISSIONS)
|
||||
|
||||
set(cmake_files_install_dir ${CMAKE_INSTALL_DATADIR}/cmake/VulkanHeaders/)
|
||||
|
||||
set_target_properties(Vulkan-Headers PROPERTIES EXPORT_NAME "Headers")
|
||||
|
||||
install(TARGETS Vulkan-Headers EXPORT VulkanHeadersTargets INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
|
||||
install(EXPORT VulkanHeadersTargets FILE VulkanHeadersTargets.cmake NAMESPACE "Vulkan::" DESTINATION ${cmake_files_install_dir})
|
||||
|
||||
set(vulkan_headers_config "${CMAKE_CURRENT_BINARY_DIR}/VulkanHeadersConfig.cmake")
|
||||
set(VULKAN_HEADERS_REGISTRY_DIRECTORY "${VLK_REGISTRY_DIR}/registry")
|
||||
|
||||
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/VulkanHeadersConfig.cmake.in ${vulkan_headers_config}
|
||||
INSTALL_DESTINATION ${cmake_files_install_dir}
|
||||
PATH_VARS VULKAN_HEADERS_REGISTRY_DIRECTORY
|
||||
NO_SET_AND_CHECK_MACRO
|
||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
||||
)
|
||||
|
||||
set(config_version "${CMAKE_CURRENT_BINARY_DIR}/VulkanHeadersConfigVersion.cmake")
|
||||
|
||||
write_basic_package_version_file(${config_version} COMPATIBILITY SameMajorVersion ARCH_INDEPENDENT)
|
||||
|
||||
install(FILES ${config_version} ${vulkan_headers_config} DESTINATION ${cmake_files_install_dir})
|
||||
endif()
|
||||
|
|
@ -1 +0,0 @@
|
|||
A reminder that this issue tracker is managed by the Khronos Group. Interactions here should follow the Khronos Code of Conduct (https://www.khronos.org/developers/code-of-conduct), which prohibits aggressive or derogatory language. Please keep the discussion friendly and civil.
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
# CONTRIBUTING
|
||||
|
||||
Please note when contributing what files this repository actually is responsible for.
|
||||
|
||||
The majority for the Vulkan headers come from [Vulkan-Docs](https://github.com/KhronosGroup/Vulkan-Docs) or [Vulkan-Hpp](https://github.com/KhronosGroup/Vulkan-Hpp)
|
||||
|
||||
### This repository (https://github.com/KhronosGroup/Vulkan-Headers)
|
||||
|
||||
* BUILD.gn
|
||||
* BUILD.md
|
||||
* cmake/
|
||||
* CMakeLists.txt
|
||||
* tests/*
|
||||
* CODE_OF_CONDUCT.md
|
||||
* INTEGRATION.md
|
||||
* LICENSE.txt
|
||||
* README.md
|
||||
* Non-API headers
|
||||
* include/vulkan/vk_icd.h
|
||||
* include/vulkan/vk_layer.h
|
||||
|
||||
### Specification repository (https://github.com/KhronosGroup/Vulkan-Docs)
|
||||
|
||||
* registry/*.py
|
||||
* registry/spec_tools/*.py
|
||||
* registry/profiles/*.json
|
||||
* All files under include/vulkan/ which are *not* listed explicitly as originating from another repository.
|
||||
|
||||
### Vulkan C++ Binding Repository (https://github.com/KhronosGroup/Vulkan-Hpp)
|
||||
|
||||
As of the Vulkan-Docs 1.2.182 spec update, the Vulkan-Hpp headers have been
|
||||
split into multiple files. All of those files are now included in this
|
||||
repository.
|
||||
|
||||
* include/vulkan/*.hpp
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
# Integrating Updated Vulkan Headers into Vulkan Repositories
|
||||
|
||||
- This guide assumes the [Vulkan-Headers](https://github.com/KhronosGroup/Vulkan-Headers), [Vulkan-Loader](https://github.com/KhronosGroup/Vulkan-Loader), [Vulkan-Tools](https://github.com/KhronosGroup/Vulkan-Tools), [Vulkan-ValidationLayers](https://github.com/KhronosGroup/Vulkan-ValidationLayers), [LunarG/VulkanSamples](https://github.com/LunarG/VulkanSamples), and [LunarG/VulkanTools](https://github.com/LunarG/VulkanTools) repositories have been cloned to a known directory on the system. If necessary, see the `BUILD.md` file in each repository for information on how to clone and build the projects.
|
||||
- If build issues exist at any point in the Vulkan header integration process, include the fix in the known-good update commit, propose a fix by creating a pull request, or create an issue in the relevant repository and wait for resolution.
|
||||
|
||||
# Clone and build the Vulkan-Headers
|
||||
|
||||
The first step of integrating Vulkan header updates is to checkout and build the desired Vulkan-Headers commit. Typically this is the latest tagged release.
|
||||
|
||||
Pull and build the dependent repositories
|
||||
|
||||
Update the Vulkan-Loader, Vulkan-ValidationLayers, and Vulkan-Tools known-good files
|
||||
|
||||
### Recommended order for updating the repositories
|
||||
|
||||
If the known-good of a repository needs to be updated, all repositories of interest that appear in its known-good files must be updated first using the procedure described in this wiki. See section [5. Update the Known Good Files](https://github.com/KhronosGroup/Vulkan-Headers/wiki/Integrating-Updated-Vulkan-Headers-into-Vulkan-Repositories/#5-update-the-known-good-files) for a list of dependencies per repository. The following list indicates the preferred known-good update order:
|
||||
1. Vulkan-Loader
|
||||
1. Vulkan-ValidationLayers
|
||||
3. Vulkan-Tools
|
||||
4. LunarG repositories when applicable
|
||||
|
||||
**Notes**:
|
||||
* Typically the Vulkan-Loader's known-good is updated first, but the Vulkan-ValidationLayers known-good can also be updated first.
|
||||
* The Vulkan-ValidationLayers GitHub CI currently contains a dependency on LunarG-VulkanTools. Occasionally Vulkan-Header updates require changes to be made to LunarG-VulkanTools before updating Vulkan-ValidationLayers known-good files (see the [update LunarG known-good section](https://github.com/KhronosGroup/Vulkan-Headers/wiki/Integrating-Vulkan-Header-Updates-into-Vulkan-Repositories#update-the-lunargvulkantools-and-lunargvulkansamples-known-good-files) below for more information).
|
||||
|
||||
### 1. Checkout and pull the `master` branch
|
||||
|
||||
Navigate to the directory of the project of interest and checkout the `master` branch. Pull in the most recent commits.
|
||||
|
||||
### 2. Generate new source files using `scripts/generate_source.py`
|
||||
|
||||
Using your favorite command prompt, navigate to the `scripts` directory and run the `generate_source.py` script. This script requires the specification of the location of the `Vulkan-Headers/registry` directory on the system. An example of how to run this script:
|
||||
```
|
||||
./generate_source.py ../../Vulkan-Headers/registry/
|
||||
```
|
||||
|
||||
#### 2-1. Propogate `genvk.py` changes
|
||||
|
||||
All Khronos repositories and LunarG/VulkanTools contain a flavor of Vulkan-Headers's `genvk.py`. If `genvk.py` in the Vulkan-Headers repository is modified, the same changes must be made to each version of the file in each repository as part of the header update.
|
||||
|
||||
#### 2-2. Vulkan-ValidationLayers sub-step: check for VUID inconsistencies
|
||||
|
||||
In Vulkan-ValidationLayers, every time the `generate_source.py` script is run a new VUID database is generated. When VUIDs are added, removed, or modified consistency testing must be performed. The `vk_validation_stats.py` script found in the ValidationLayers `scripts` directory can be used to report consistency warnings using the `-c` option.
|
||||
```
|
||||
./vk_validation_stats.py ../../Vulkan-Headers/registry/validusage.json -c
|
||||
```
|
||||
All consistency warnings must be resolved and included in the pull request for the repository's known-good update.
|
||||
|
||||
### 3. Build the project
|
||||
|
||||
Build the project, referring to the `BUILD.md` file in the directory if necessary.
|
||||
|
||||
### 4. Test the build
|
||||
|
||||
- To test the Vulkan-Loader build, run the loader tests (`run_all_tests.sh`) found in the `build/tests` directory. Information on how to build and run the tests can be found in the [Vulkan-Loader `BUILD.md`](https://github.com/KhronosGroup/Vulkan-Loader/blob/master/BUILD.md) file. **Note**: The `VK_LAYER_PATH` environment variable must be set to point at the layers found in `Vulkan-Loader/build/tests/layers` when running the loader tests.
|
||||
|
||||
- To test the Vulkan-ValidationLayers build, run the validation layers tests (`vk_layer_validation_tests`) found in the `build/tests` directory. Information on how to build and run the tests can be found in the [Vulkan-ValidationLayers `BUILD.md`](https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/master/BUILD.md) file.
|
||||
|
||||
- To test the Vulkan-Tools build, run `vkcube` and verify `vulkaninfo` produces reasonable output. More information on how to use `vulkaninfo` can be found [here](https://github.com/KhronosGroup/Vulkan-Tools/blob/master/vulkaninfo/vulkaninfo.md).
|
||||
|
||||
### 5. Update the known-good files
|
||||
|
||||
Every repository contains a `scripts/known_good.json` file which contains information about the known good commits for each dependent repository. Some repositories require an additional known-good file to be updated for Android builds and are specified below. Known-good updates require updating only the "commit" values of the relevant JSON objects. Using an existing tag for this value is preferred over using a full commit id. If a tag does not exist, typically the most recent commit on `master` is chosen for updating the known good. **Note**: Do not change commit values for repositories not listed below unless an update is absolutely required.
|
||||
|
||||
- Vulkan-Loader: Update requires specifying a new `Vulkan-Headers` commit in `scripts/known_good.json`
|
||||
|
||||
- Vulkan-ValidationLayers: Update requires specifying a new `Vulkan-Headers` commit in `scripts/known_good.json`. Additionally, new `Vulkan-Headers` and `Vulkan-Tools` commits must be specified in the `build-android/known_good.json` file.
|
||||
|
||||
- Vulkan-Tools: Update requires specifying new `Vulkan-Headers` and `Vulkan-Loader` commits in `scripts/known_good.json`. Additionally, a new `Vulkan-Headers` commit must be specified in the `vulkan-headers_revision_android` file.
|
||||
|
||||
### 6. Commit changes
|
||||
|
||||
Commit all changes (e.g., newly generated scripts, known-good files, etc.) in a single commit on a branch and push it up to the online repository. In Vulkan-ValidationLayers, VUID inconsistency resolutions can be included in a single commit with the known-good update or on the same branch in a separate commit.
|
||||
|
||||
### 7. Create a pull request in the relevant repository
|
||||
|
||||
Verify the branch with the proposed known-good commit is rebased on the tip of `master` and create a pull request in the GitHub repository. The repository owner will assign someone with push rights and specify reviewers for the PR. Prior to approval, the proposed changes will be run through internal LunarG CI testing.
|
||||
|
||||
### 8. Rebase changes onto `master`
|
||||
|
||||
Once the known-good update PR is approved, the assignee will rebase the approved commits onto the `master` branch.
|
||||
|
||||
### 9. Tag the known-good commit
|
||||
|
||||
Once approved and rebased onto `master`, the known-good update commit must be marked with a version tag. For more information on the version tag format see the "Version Tagging Scheme" section of each repository's `BUILD.md` file
|
||||
|
||||
## Update the LunarG/VulkanTools and LunarG/VulkanSamples known-good files
|
||||
|
||||
Updating the Known-good files in LunarG repositories follows the same steps as updating the known-good files in the Khronos repositories.
|
||||
|
||||
### Testing LunarG builds
|
||||
|
||||
- LunarG/VulkanTools: Build Debug and Release on Linux and Windows. Verify vktrace/replay works. Verify several of the layers built in this repo work.
|
||||
- LunarG/VulkanSamples: Build all and run a few of the Vulkan Samples. Instructions on how to build and run the LunarG Vulkan samples can be found in the repository's [`BUILD.md` file](https://github.com/LunarG/VulkanSamples/blob/master/BUILD.md).
|
||||
|
||||
### Updating LunarG known-good files
|
||||
|
||||
- LunarG/VulkanTools: Update requires specifying new `Vulkan-Headers`, `Vulkan-Loader`, `Vulkan-Tools`, and `Vulkan-ValidationLayers` commits in `scripts/known_good.json`. Additionally, the new `Vulkan-Headers` commit must be specified in the `build-android/vulkan-headers_revision_android` file and the new `Vulkan-Tools` commit must be specified in the `build-android/vulkan-tools_revision_android` file.
|
||||
- LunarG/VulkanSamples: Update requires specifying new `Vulkan-Headers` and `Vulkan-Loader` commits in `scripts/known_good.json`.
|
||||
29
README.md
29
README.md
|
|
@ -1,29 +0,0 @@
|
|||
# Vulkan-Headers
|
||||
|
||||
Vulkan header files and API registry
|
||||
|
||||
## Contributing
|
||||
|
||||
See the [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
## Building
|
||||
|
||||
See [BUILD.md](BUILD.md)
|
||||
|
||||
## SDK Support
|
||||
|
||||
Vulkan-Headers are shipped as part of the official [Vulkan-SDK](https://www.lunarg.com/vulkan-sdk/)
|
||||
|
||||
## C/C++ Package Manager Support
|
||||
|
||||
`Vulkan-Headers` are also supported by both [conan](https://conan.io/) & [vcpkg](https://learn.microsoft.com/en-us/vcpkg/).
|
||||
|
||||
## Version Tagging Scheme
|
||||
|
||||
Updates to the `Vulkan-Headers` repository which correspond to a new Vulkan
|
||||
specification release are tagged using the following format:
|
||||
`v<`_`version`_`>` (e.g., `v1.1.96`).
|
||||
|
||||
**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`).
|
||||
19
build.zig
Normal file
19
build.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const lib = b.addStaticLibrary(.{
|
||||
.name = "vulkan-headers",
|
||||
.root_source_file = .{ .path = "stub.c" },
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
inline for (.{ "vk_video", "vulkan" }) |subdir| {
|
||||
lib.installHeadersDirectory("include/" ++ subdir, subdir);
|
||||
}
|
||||
|
||||
lib.install();
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/VulkanHeadersTargets.cmake")
|
||||
|
||||
set(VULKAN_HEADERS_REGISTRY_DIRECTORY "@PACKAGE_VULKAN_HEADERS_REGISTRY_DIRECTORY@")
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/python3 -i
|
||||
#
|
||||
# Copyright 2021-2023 The Khronos Group Inc.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Generic alias for working group-specific API conventions interface.
|
||||
|
||||
# This import should be changed at the repository / working group level to
|
||||
# specify the correct API's conventions.
|
||||
|
||||
from vkconventions import VulkanConventions as APIConventions
|
||||
|
|
@ -1,511 +0,0 @@
|
|||
#!/usr/bin/python3 -i
|
||||
#
|
||||
# Copyright 2013-2023 The Khronos Group Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from generator import (GeneratorOptions,
|
||||
MissingGeneratorOptionsConventionsError,
|
||||
MissingGeneratorOptionsError, MissingRegistryError,
|
||||
OutputGenerator, noneStr, regSortFeatures, write)
|
||||
|
||||
class CGeneratorOptions(GeneratorOptions):
|
||||
"""CGeneratorOptions - subclass of GeneratorOptions.
|
||||
|
||||
Adds options used by COutputGenerator objects during C language header
|
||||
generation."""
|
||||
|
||||
def __init__(self,
|
||||
prefixText='',
|
||||
genFuncPointers=True,
|
||||
protectFile=True,
|
||||
protectFeature=True,
|
||||
protectProto=None,
|
||||
protectProtoStr=None,
|
||||
protectExtensionProto=None,
|
||||
protectExtensionProtoStr=None,
|
||||
apicall='',
|
||||
apientry='',
|
||||
apientryp='',
|
||||
indentFuncProto=True,
|
||||
indentFuncPointer=False,
|
||||
alignFuncParam=0,
|
||||
genEnumBeginEndRange=False,
|
||||
genAliasMacro=False,
|
||||
genStructExtendsComment=False,
|
||||
aliasMacro='',
|
||||
misracstyle=False,
|
||||
misracppstyle=False,
|
||||
**kwargs
|
||||
):
|
||||
"""Constructor.
|
||||
Additional parameters beyond parent class:
|
||||
|
||||
- prefixText - list of strings to prefix generated header with
|
||||
(usually a copyright statement + calling convention macros)
|
||||
- protectFile - True if multiple inclusion protection should be
|
||||
generated (based on the filename) around the entire header
|
||||
- protectFeature - True if #ifndef..#endif protection should be
|
||||
generated around a feature interface in the header file
|
||||
- genFuncPointers - True if function pointer typedefs should be
|
||||
generated
|
||||
- protectProto - If conditional protection should be generated
|
||||
around prototype declarations, set to either '#ifdef'
|
||||
to require opt-in (#ifdef protectProtoStr) or '#ifndef'
|
||||
to require opt-out (#ifndef protectProtoStr). Otherwise
|
||||
set to None.
|
||||
- protectProtoStr - #ifdef/#ifndef symbol to use around prototype
|
||||
declarations, if protectProto is set
|
||||
- protectExtensionProto - If conditional protection should be generated
|
||||
around extension prototype declarations, set to either '#ifdef'
|
||||
to require opt-in (#ifdef protectExtensionProtoStr) or '#ifndef'
|
||||
to require opt-out (#ifndef protectExtensionProtoStr). Otherwise
|
||||
set to None
|
||||
- protectExtensionProtoStr - #ifdef/#ifndef symbol to use around
|
||||
extension prototype declarations, if protectExtensionProto is set
|
||||
- apicall - string to use for the function declaration prefix,
|
||||
such as APICALL on Windows
|
||||
- apientry - string to use for the calling convention macro,
|
||||
in typedefs, such as APIENTRY
|
||||
- apientryp - string to use for the calling convention macro
|
||||
in function pointer typedefs, such as APIENTRYP
|
||||
- indentFuncProto - True if prototype declarations should put each
|
||||
parameter on a separate line
|
||||
- indentFuncPointer - True if typedefed function pointers should put each
|
||||
parameter on a separate line
|
||||
- alignFuncParam - if nonzero and parameters are being put on a
|
||||
separate line, align parameter names at the specified column
|
||||
- genEnumBeginEndRange - True if BEGIN_RANGE / END_RANGE macros should
|
||||
be generated for enumerated types
|
||||
- genAliasMacro - True if the OpenXR alias macro should be generated
|
||||
for aliased types (unclear what other circumstances this is useful)
|
||||
- genStructExtendsComment - True if comments showing the structures
|
||||
whose pNext chain a structure extends are included before its
|
||||
definition
|
||||
- aliasMacro - alias macro to inject when genAliasMacro is True
|
||||
- misracstyle - generate MISRA C-friendly headers
|
||||
- misracppstyle - generate MISRA C++-friendly headers"""
|
||||
|
||||
GeneratorOptions.__init__(self, **kwargs)
|
||||
|
||||
self.prefixText = prefixText
|
||||
"""list of strings to prefix generated header with (usually a copyright statement + calling convention macros)."""
|
||||
|
||||
self.genFuncPointers = genFuncPointers
|
||||
"""True if function pointer typedefs should be generated"""
|
||||
|
||||
self.protectFile = protectFile
|
||||
"""True if multiple inclusion protection should be generated (based on the filename) around the entire header."""
|
||||
|
||||
self.protectFeature = protectFeature
|
||||
"""True if #ifndef..#endif protection should be generated around a feature interface in the header file."""
|
||||
|
||||
self.protectProto = protectProto
|
||||
"""If conditional protection should be generated around prototype declarations, set to either '#ifdef' to require opt-in (#ifdef protectProtoStr) or '#ifndef' to require opt-out (#ifndef protectProtoStr). Otherwise set to None."""
|
||||
|
||||
self.protectProtoStr = protectProtoStr
|
||||
"""#ifdef/#ifndef symbol to use around prototype declarations, if protectProto is set"""
|
||||
|
||||
self.protectExtensionProto = protectExtensionProto
|
||||
"""If conditional protection should be generated around extension prototype declarations, set to either '#ifdef' to require opt-in (#ifdef protectExtensionProtoStr) or '#ifndef' to require opt-out (#ifndef protectExtensionProtoStr). Otherwise set to None."""
|
||||
|
||||
self.protectExtensionProtoStr = protectExtensionProtoStr
|
||||
"""#ifdef/#ifndef symbol to use around extension prototype declarations, if protectExtensionProto is set"""
|
||||
|
||||
self.apicall = apicall
|
||||
"""string to use for the function declaration prefix, such as APICALL on Windows."""
|
||||
|
||||
self.apientry = apientry
|
||||
"""string to use for the calling convention macro, in typedefs, such as APIENTRY."""
|
||||
|
||||
self.apientryp = apientryp
|
||||
"""string to use for the calling convention macro in function pointer typedefs, such as APIENTRYP."""
|
||||
|
||||
self.indentFuncProto = indentFuncProto
|
||||
"""True if prototype declarations should put each parameter on a separate line"""
|
||||
|
||||
self.indentFuncPointer = indentFuncPointer
|
||||
"""True if typedefed function pointers should put each parameter on a separate line"""
|
||||
|
||||
self.alignFuncParam = alignFuncParam
|
||||
"""if nonzero and parameters are being put on a separate line, align parameter names at the specified column"""
|
||||
|
||||
self.genEnumBeginEndRange = genEnumBeginEndRange
|
||||
"""True if BEGIN_RANGE / END_RANGE macros should be generated for enumerated types"""
|
||||
|
||||
self.genAliasMacro = genAliasMacro
|
||||
"""True if the OpenXR alias macro should be generated for aliased types (unclear what other circumstances this is useful)"""
|
||||
|
||||
self.genStructExtendsComment = genStructExtendsComment
|
||||
"""True if comments showing the structures whose pNext chain a structure extends are included before its definition"""
|
||||
|
||||
self.aliasMacro = aliasMacro
|
||||
"""alias macro to inject when genAliasMacro is True"""
|
||||
|
||||
self.misracstyle = misracstyle
|
||||
"""generate MISRA C-friendly headers"""
|
||||
|
||||
self.misracppstyle = misracppstyle
|
||||
"""generate MISRA C++-friendly headers"""
|
||||
|
||||
self.codeGenerator = True
|
||||
"""True if this generator makes compilable code"""
|
||||
|
||||
|
||||
class COutputGenerator(OutputGenerator):
|
||||
"""Generates C-language API interfaces."""
|
||||
|
||||
# This is an ordered list of sections in the header file.
|
||||
TYPE_SECTIONS = ['include', 'define', 'basetype', 'handle', 'enum',
|
||||
'group', 'bitmask', 'funcpointer', 'struct']
|
||||
ALL_SECTIONS = TYPE_SECTIONS + ['commandPointer', 'command']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
# Internal state - accumulators for different inner block text
|
||||
self.sections = {section: [] for section in self.ALL_SECTIONS}
|
||||
self.feature_not_empty = False
|
||||
self.may_alias = None
|
||||
|
||||
def beginFile(self, genOpts):
|
||||
OutputGenerator.beginFile(self, genOpts)
|
||||
if self.genOpts is None:
|
||||
raise MissingGeneratorOptionsError()
|
||||
# C-specific
|
||||
#
|
||||
# Multiple inclusion protection & C++ wrappers.
|
||||
if self.genOpts.protectFile and self.genOpts.filename:
|
||||
headerSym = re.sub(r'\.h', '_h_',
|
||||
os.path.basename(self.genOpts.filename)).upper()
|
||||
write('#ifndef', headerSym, file=self.outFile)
|
||||
write('#define', headerSym, '1', file=self.outFile)
|
||||
self.newline()
|
||||
|
||||
# User-supplied prefix text, if any (list of strings)
|
||||
if genOpts.prefixText:
|
||||
for s in genOpts.prefixText:
|
||||
write(s, file=self.outFile)
|
||||
|
||||
# C++ extern wrapper - after prefix lines so they can add includes.
|
||||
self.newline()
|
||||
write('#ifdef __cplusplus', file=self.outFile)
|
||||
write('extern "C" {', file=self.outFile)
|
||||
write('#endif', file=self.outFile)
|
||||
self.newline()
|
||||
|
||||
def endFile(self):
|
||||
# C-specific
|
||||
# Finish C++ wrapper and multiple inclusion protection
|
||||
if self.genOpts is None:
|
||||
raise MissingGeneratorOptionsError()
|
||||
self.newline()
|
||||
write('#ifdef __cplusplus', file=self.outFile)
|
||||
write('}', file=self.outFile)
|
||||
write('#endif', file=self.outFile)
|
||||
if self.genOpts.protectFile and self.genOpts.filename:
|
||||
self.newline()
|
||||
write('#endif', file=self.outFile)
|
||||
# Finish processing in superclass
|
||||
OutputGenerator.endFile(self)
|
||||
|
||||
def beginFeature(self, interface, emit):
|
||||
# Start processing in superclass
|
||||
OutputGenerator.beginFeature(self, interface, emit)
|
||||
# C-specific
|
||||
# Accumulate includes, defines, types, enums, function pointer typedefs,
|
||||
# end function prototypes separately for this feature. They are only
|
||||
# printed in endFeature().
|
||||
self.sections = {section: [] for section in self.ALL_SECTIONS}
|
||||
self.feature_not_empty = False
|
||||
|
||||
def _endProtectComment(self, protect_str, protect_directive='#ifdef'):
|
||||
if protect_directive is None or protect_str is None:
|
||||
raise RuntimeError('Should not call in here without something to protect')
|
||||
|
||||
# Do not put comments after #endif closing blocks if this is not set
|
||||
if not self.genOpts.conventions.protectProtoComment:
|
||||
return ''
|
||||
elif 'ifdef' in protect_directive:
|
||||
return f' /* {protect_str} */'
|
||||
else:
|
||||
return f' /* !{protect_str} */'
|
||||
|
||||
def endFeature(self):
|
||||
"Actually write the interface to the output file."
|
||||
# C-specific
|
||||
if self.emit:
|
||||
if self.feature_not_empty:
|
||||
if self.genOpts is None:
|
||||
raise MissingGeneratorOptionsError()
|
||||
if self.genOpts.conventions is None:
|
||||
raise MissingGeneratorOptionsConventionsError()
|
||||
is_core = self.featureName and self.featureName.startswith(self.conventions.api_prefix + 'VERSION_')
|
||||
if self.genOpts.conventions.writeFeature(self.featureExtraProtect, self.genOpts.filename):
|
||||
self.newline()
|
||||
if self.genOpts.protectFeature:
|
||||
write('#ifndef', self.featureName, file=self.outFile)
|
||||
|
||||
# If type declarations are needed by other features based on
|
||||
# this one, it may be necessary to suppress the ExtraProtect,
|
||||
# or move it below the 'for section...' loop.
|
||||
if self.featureExtraProtect is not None:
|
||||
write('#ifdef', self.featureExtraProtect, file=self.outFile)
|
||||
self.newline()
|
||||
|
||||
write('#define', self.featureName, '1', file=self.outFile)
|
||||
for section in self.TYPE_SECTIONS:
|
||||
contents = self.sections[section]
|
||||
if contents:
|
||||
write('\n'.join(contents), file=self.outFile)
|
||||
|
||||
if self.genOpts.genFuncPointers and self.sections['commandPointer']:
|
||||
write('\n'.join(self.sections['commandPointer']), file=self.outFile)
|
||||
self.newline()
|
||||
|
||||
if self.sections['command']:
|
||||
if self.genOpts.protectProto:
|
||||
write(self.genOpts.protectProto,
|
||||
self.genOpts.protectProtoStr, file=self.outFile)
|
||||
if self.genOpts.protectExtensionProto and not is_core:
|
||||
write(self.genOpts.protectExtensionProto,
|
||||
self.genOpts.protectExtensionProtoStr, file=self.outFile)
|
||||
write('\n'.join(self.sections['command']), end='', file=self.outFile)
|
||||
if self.genOpts.protectExtensionProto and not is_core:
|
||||
write('#endif' +
|
||||
self._endProtectComment(protect_directive=self.genOpts.protectExtensionProto,
|
||||
protect_str=self.genOpts.protectExtensionProtoStr),
|
||||
file=self.outFile)
|
||||
if self.genOpts.protectProto:
|
||||
write('#endif' +
|
||||
self._endProtectComment(protect_directive=self.genOpts.protectProto,
|
||||
protect_str=self.genOpts.protectProtoStr),
|
||||
file=self.outFile)
|
||||
else:
|
||||
self.newline()
|
||||
|
||||
if self.featureExtraProtect is not None:
|
||||
write('#endif' +
|
||||
self._endProtectComment(protect_str=self.featureExtraProtect),
|
||||
file=self.outFile)
|
||||
|
||||
if self.genOpts.protectFeature:
|
||||
write('#endif' +
|
||||
self._endProtectComment(protect_str=self.featureName),
|
||||
file=self.outFile)
|
||||
# Finish processing in superclass
|
||||
OutputGenerator.endFeature(self)
|
||||
|
||||
def appendSection(self, section, text):
|
||||
"Append a definition to the specified section"
|
||||
|
||||
if section is None:
|
||||
self.logMsg('error', 'Missing section in appendSection (probably a <type> element missing its \'category\' attribute. Text:', text)
|
||||
exit(1)
|
||||
|
||||
self.sections[section].append(text)
|
||||
self.feature_not_empty = True
|
||||
|
||||
def genType(self, typeinfo, name, alias):
|
||||
"Generate type."
|
||||
OutputGenerator.genType(self, typeinfo, name, alias)
|
||||
typeElem = typeinfo.elem
|
||||
|
||||
# Vulkan:
|
||||
# Determine the category of the type, and the type section to add
|
||||
# its definition to.
|
||||
# 'funcpointer' is added to the 'struct' section as a workaround for
|
||||
# internal issue #877, since structures and function pointer types
|
||||
# can have cross-dependencies.
|
||||
category = typeElem.get('category')
|
||||
if category == 'funcpointer':
|
||||
section = 'struct'
|
||||
else:
|
||||
section = category
|
||||
|
||||
if category in ('struct', 'union'):
|
||||
# If the type is a struct type, generate it using the
|
||||
# special-purpose generator.
|
||||
self.genStruct(typeinfo, name, alias)
|
||||
else:
|
||||
if self.genOpts is None:
|
||||
raise MissingGeneratorOptionsError()
|
||||
# OpenXR: this section was not under 'else:' previously, just fell through
|
||||
if alias:
|
||||
# If the type is an alias, just emit a typedef declaration
|
||||
body = 'typedef ' + alias + ' ' + name + ';\n'
|
||||
else:
|
||||
# Replace <apientry /> tags with an APIENTRY-style string
|
||||
# (from self.genOpts). Copy other text through unchanged.
|
||||
# If the resulting text is an empty string, do not emit it.
|
||||
body = noneStr(typeElem.text)
|
||||
for elem in typeElem:
|
||||
if elem.tag == 'apientry':
|
||||
body += self.genOpts.apientry + noneStr(elem.tail)
|
||||
else:
|
||||
body += noneStr(elem.text) + noneStr(elem.tail)
|
||||
if category == 'define' and self.misracppstyle():
|
||||
body = body.replace("(uint32_t)", "static_cast<uint32_t>")
|
||||
if body:
|
||||
# Add extra newline after multi-line entries.
|
||||
if '\n' in body[0:-1]:
|
||||
body += '\n'
|
||||
self.appendSection(section, body)
|
||||
|
||||
def genProtectString(self, protect_str):
|
||||
"""Generate protection string.
|
||||
|
||||
Protection strings are the strings defining the OS/Platform/Graphics
|
||||
requirements for a given API command. When generating the
|
||||
language header files, we need to make sure the items specific to a
|
||||
graphics API or OS platform are properly wrapped in #ifs."""
|
||||
protect_if_str = ''
|
||||
protect_end_str = ''
|
||||
if not protect_str:
|
||||
return (protect_if_str, protect_end_str)
|
||||
|
||||
if ',' in protect_str:
|
||||
protect_list = protect_str.split(',')
|
||||
protect_defs = ('defined(%s)' % d for d in protect_list)
|
||||
protect_def_str = ' && '.join(protect_defs)
|
||||
protect_if_str = '#if %s\n' % protect_def_str
|
||||
protect_end_str = '#endif // %s\n' % protect_def_str
|
||||
else:
|
||||
protect_if_str = '#ifdef %s\n' % protect_str
|
||||
protect_end_str = '#endif // %s\n' % protect_str
|
||||
|
||||
return (protect_if_str, protect_end_str)
|
||||
|
||||
def typeMayAlias(self, typeName):
|
||||
if not self.may_alias:
|
||||
if self.registry is None:
|
||||
raise MissingRegistryError()
|
||||
# First time we have asked if a type may alias.
|
||||
# So, populate the set of all names of types that may.
|
||||
|
||||
# Everyone with an explicit mayalias="true"
|
||||
self.may_alias = set(typeName
|
||||
for typeName, data in self.registry.typedict.items()
|
||||
if data.elem.get('mayalias') == 'true')
|
||||
|
||||
# Every type mentioned in some other type's parentstruct attribute.
|
||||
polymorphic_bases = (otherType.elem.get('parentstruct')
|
||||
for otherType in self.registry.typedict.values())
|
||||
self.may_alias.update(set(x for x in polymorphic_bases
|
||||
if x is not None))
|
||||
return typeName in self.may_alias
|
||||
|
||||
def genStruct(self, typeinfo, typeName, alias):
|
||||
"""Generate struct (e.g. C "struct" type).
|
||||
|
||||
This is a special case of the <type> tag where the contents are
|
||||
interpreted as a set of <member> tags instead of freeform C
|
||||
C type declarations. The <member> tags are just like <param>
|
||||
tags - they are a declaration of a struct or union member.
|
||||
Only simple member declarations are supported (no nested
|
||||
structs etc.)
|
||||
|
||||
If alias is not None, then this struct aliases another; just
|
||||
generate a typedef of that alias."""
|
||||
OutputGenerator.genStruct(self, typeinfo, typeName, alias)
|
||||
|
||||
if self.genOpts is None:
|
||||
raise MissingGeneratorOptionsError()
|
||||
|
||||
typeElem = typeinfo.elem
|
||||
|
||||
if alias:
|
||||
body = 'typedef ' + alias + ' ' + typeName + ';\n'
|
||||
else:
|
||||
body = ''
|
||||
(protect_begin, protect_end) = self.genProtectString(typeElem.get('protect'))
|
||||
if protect_begin:
|
||||
body += protect_begin
|
||||
|
||||
if self.genOpts.genStructExtendsComment:
|
||||
structextends = typeElem.get('structextends')
|
||||
body += '// ' + typeName + ' extends ' + structextends + '\n' if structextends else ''
|
||||
|
||||
body += 'typedef ' + typeElem.get('category')
|
||||
|
||||
# This is an OpenXR-specific alternative where aliasing refers
|
||||
# to an inheritance hierarchy of types rather than C-level type
|
||||
# aliases.
|
||||
if self.genOpts.genAliasMacro and self.typeMayAlias(typeName):
|
||||
body += ' ' + self.genOpts.aliasMacro
|
||||
|
||||
body += ' ' + typeName + ' {\n'
|
||||
|
||||
targetLen = self.getMaxCParamTypeLength(typeinfo)
|
||||
for member in typeElem.findall('.//member'):
|
||||
body += self.makeCParamDecl(member, targetLen + 4)
|
||||
body += ';\n'
|
||||
body += '} ' + typeName + ';\n'
|
||||
if protect_end:
|
||||
body += protect_end
|
||||
|
||||
self.appendSection('struct', body)
|
||||
|
||||
def genGroup(self, groupinfo, groupName, alias=None):
|
||||
"""Generate groups (e.g. C "enum" type).
|
||||
|
||||
These are concatenated together with other types.
|
||||
|
||||
If alias is not None, it is the name of another group type
|
||||
which aliases this type; just generate that alias."""
|
||||
OutputGenerator.genGroup(self, groupinfo, groupName, alias)
|
||||
groupElem = groupinfo.elem
|
||||
|
||||
# After either enumerated type or alias paths, add the declaration
|
||||
# to the appropriate section for the group being defined.
|
||||
if groupElem.get('type') == 'bitmask':
|
||||
section = 'bitmask'
|
||||
else:
|
||||
section = 'group'
|
||||
|
||||
if alias:
|
||||
# If the group name is aliased, just emit a typedef declaration
|
||||
# for the alias.
|
||||
body = 'typedef ' + alias + ' ' + groupName + ';\n'
|
||||
self.appendSection(section, body)
|
||||
else:
|
||||
if self.genOpts is None:
|
||||
raise MissingGeneratorOptionsError()
|
||||
(section, body) = self.buildEnumCDecl(self.genOpts.genEnumBeginEndRange, groupinfo, groupName)
|
||||
self.appendSection(section, '\n' + body)
|
||||
|
||||
def genEnum(self, enuminfo, name, alias):
|
||||
"""Generate the C declaration for a constant (a single <enum> value).
|
||||
|
||||
<enum> tags may specify their values in several ways, but are usually
|
||||
just integers."""
|
||||
|
||||
OutputGenerator.genEnum(self, enuminfo, name, alias)
|
||||
|
||||
body = self.buildConstantCDecl(enuminfo, name, alias)
|
||||
self.appendSection('enum', body)
|
||||
|
||||
def genCmd(self, cmdinfo, name, alias):
|
||||
"Command generation"
|
||||
OutputGenerator.genCmd(self, cmdinfo, name, alias)
|
||||
|
||||
# if alias:
|
||||
# prefix = '// ' + name + ' is an alias of command ' + alias + '\n'
|
||||
# else:
|
||||
# prefix = ''
|
||||
if self.genOpts is None:
|
||||
raise MissingGeneratorOptionsError()
|
||||
|
||||
prefix = ''
|
||||
decls = self.makeCDecls(cmdinfo.elem)
|
||||
self.appendSection('command', prefix + decls[0] + '\n')
|
||||
if self.genOpts.genFuncPointers:
|
||||
self.appendSection('commandPointer', decls[1])
|
||||
|
||||
def misracstyle(self):
|
||||
return self.genOpts.misracstyle;
|
||||
|
||||
def misracppstyle(self):
|
||||
return self.genOpts.misracppstyle;
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,818 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright 2013-2023 The Khronos Group Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import pdb
|
||||
import re
|
||||
import sys
|
||||
import copy
|
||||
import time
|
||||
import xml.etree.ElementTree as etree
|
||||
|
||||
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
|
||||
|
||||
from cgenerator import CGeneratorOptions, COutputGenerator
|
||||
|
||||
from docgenerator import DocGeneratorOptions, DocOutputGenerator
|
||||
from extensionmetadocgenerator import (ExtensionMetaDocGeneratorOptions,
|
||||
ExtensionMetaDocOutputGenerator)
|
||||
from interfacedocgenerator import InterfaceDocGenerator
|
||||
from generator import write
|
||||
from spirvcapgenerator import SpirvCapabilityOutputGenerator
|
||||
from hostsyncgenerator import HostSynchronizationOutputGenerator
|
||||
from formatsgenerator import FormatsOutputGenerator
|
||||
from pygenerator import PyOutputGenerator
|
||||
from rubygenerator import RubyOutputGenerator
|
||||
from reflib import logDiag, logWarn, logErr, setLogFile
|
||||
from reg import Registry
|
||||
from validitygenerator import ValidityOutputGenerator
|
||||
from apiconventions import APIConventions
|
||||
|
||||
# Simple timer functions
|
||||
startTime = None
|
||||
|
||||
|
||||
def startTimer(timeit):
|
||||
global startTime
|
||||
if timeit:
|
||||
startTime = time.process_time()
|
||||
|
||||
|
||||
def endTimer(timeit, msg):
|
||||
global startTime
|
||||
if timeit and startTime is not None:
|
||||
endTime = time.process_time()
|
||||
logDiag(msg, endTime - startTime)
|
||||
startTime = None
|
||||
|
||||
|
||||
def makeREstring(strings, default=None, strings_are_regex=False):
|
||||
"""Turn a list of strings into a regexp string matching exactly those strings."""
|
||||
if strings or default is None:
|
||||
if not strings_are_regex:
|
||||
strings = (re.escape(s) for s in strings)
|
||||
return '^(' + '|'.join(strings) + ')$'
|
||||
return default
|
||||
|
||||
|
||||
def makeGenOpts(args):
|
||||
"""Returns a directory of [ generator function, generator options ] indexed
|
||||
by specified short names. The generator options incorporate the following
|
||||
parameters:
|
||||
|
||||
args is an parsed argument object; see below for the fields that are used."""
|
||||
global genOpts
|
||||
genOpts = {}
|
||||
|
||||
# Default class of extensions to include, or None
|
||||
defaultExtensions = args.defaultExtensions
|
||||
|
||||
# Additional extensions to include (list of extensions)
|
||||
extensions = args.extension
|
||||
|
||||
# Extensions to remove (list of extensions)
|
||||
removeExtensions = args.removeExtensions
|
||||
|
||||
# Extensions to emit (list of extensions)
|
||||
emitExtensions = args.emitExtensions
|
||||
|
||||
# SPIR-V capabilities / features to emit (list of extensions & capabilities)
|
||||
emitSpirv = args.emitSpirv
|
||||
|
||||
# Vulkan Formats to emit
|
||||
emitFormats = args.emitFormats
|
||||
|
||||
# Features to include (list of features)
|
||||
features = args.feature
|
||||
|
||||
# Whether to disable inclusion protect in headers
|
||||
protect = args.protect
|
||||
|
||||
# Output target directory
|
||||
directory = args.directory
|
||||
|
||||
# Path to generated files, particularly apimap.py
|
||||
genpath = args.genpath
|
||||
|
||||
# Generate MISRA C-friendly headers
|
||||
misracstyle = args.misracstyle;
|
||||
|
||||
# Generate MISRA C++-friendly headers
|
||||
misracppstyle = args.misracppstyle;
|
||||
|
||||
# Descriptive names for various regexp patterns used to select
|
||||
# versions and extensions
|
||||
allFormats = allSpirv = allFeatures = allExtensions = r'.*'
|
||||
|
||||
# Turn lists of names/patterns into matching regular expressions
|
||||
addExtensionsPat = makeREstring(extensions, None)
|
||||
removeExtensionsPat = makeREstring(removeExtensions, None)
|
||||
emitExtensionsPat = makeREstring(emitExtensions, allExtensions)
|
||||
emitSpirvPat = makeREstring(emitSpirv, allSpirv)
|
||||
emitFormatsPat = makeREstring(emitFormats, allFormats)
|
||||
featuresPat = makeREstring(features, allFeatures)
|
||||
|
||||
# Copyright text prefixing all headers (list of strings).
|
||||
# The SPDX formatting below works around constraints of the 'reuse' tool
|
||||
prefixStrings = [
|
||||
'/*',
|
||||
'** Copyright 2015-2023 The Khronos Group Inc.',
|
||||
'**',
|
||||
'** SPDX-License-Identifier' + ': Apache-2.0',
|
||||
'*/',
|
||||
''
|
||||
]
|
||||
|
||||
# Text specific to Vulkan headers
|
||||
vkPrefixStrings = [
|
||||
'/*',
|
||||
'** This header is generated from the Khronos Vulkan XML API Registry.',
|
||||
'**',
|
||||
'*/',
|
||||
''
|
||||
]
|
||||
|
||||
# Defaults for generating re-inclusion protection wrappers (or not)
|
||||
protectFile = protect
|
||||
|
||||
# An API style conventions object
|
||||
conventions = APIConventions()
|
||||
|
||||
if args.apiname is not None:
|
||||
defaultAPIName = args.apiname
|
||||
else:
|
||||
defaultAPIName = conventions.xml_api_name
|
||||
|
||||
# API include files for spec and ref pages
|
||||
# Overwrites include subdirectories in spec source tree
|
||||
# The generated include files do not include the calling convention
|
||||
# macros (apientry etc.), unlike the header files.
|
||||
# Because the 1.0 core branch includes ref pages for extensions,
|
||||
# all the extension interfaces need to be generated, even though
|
||||
# none are used by the core spec itself.
|
||||
genOpts['apiinc'] = [
|
||||
DocOutputGenerator,
|
||||
DocGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'timeMarker',
|
||||
directory = directory,
|
||||
genpath = genpath,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = featuresPat,
|
||||
emitversions = featuresPat,
|
||||
defaultExtensions = None,
|
||||
addExtensions = addExtensionsPat,
|
||||
removeExtensions = removeExtensionsPat,
|
||||
emitExtensions = emitExtensionsPat,
|
||||
prefixText = prefixStrings + vkPrefixStrings,
|
||||
apicall = '',
|
||||
apientry = '',
|
||||
apientryp = '*',
|
||||
alignFuncParam = 48,
|
||||
expandEnumerants = False)
|
||||
]
|
||||
|
||||
# Python and Ruby representations of API information, used by scripts
|
||||
# that do not need to load the full XML.
|
||||
genOpts['apimap.py'] = [
|
||||
PyOutputGenerator,
|
||||
DocGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'apimap.py',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = featuresPat,
|
||||
emitversions = featuresPat,
|
||||
defaultExtensions = None,
|
||||
addExtensions = addExtensionsPat,
|
||||
removeExtensions = removeExtensionsPat,
|
||||
emitExtensions = emitExtensionsPat,
|
||||
reparentEnums = False)
|
||||
]
|
||||
|
||||
genOpts['apimap.rb'] = [
|
||||
RubyOutputGenerator,
|
||||
DocGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'apimap.rb',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = featuresPat,
|
||||
emitversions = featuresPat,
|
||||
defaultExtensions = None,
|
||||
addExtensions = addExtensionsPat,
|
||||
removeExtensions = removeExtensionsPat,
|
||||
emitExtensions = emitExtensionsPat,
|
||||
reparentEnums = False)
|
||||
]
|
||||
|
||||
|
||||
# API validity files for spec
|
||||
#
|
||||
# requireCommandAliases is set to True because we need validity files
|
||||
# for the command something is promoted to even when the promoted-to
|
||||
# feature is not included. This avoids wordy includes of validity files.
|
||||
genOpts['validinc'] = [
|
||||
ValidityOutputGenerator,
|
||||
DocGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'timeMarker',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = featuresPat,
|
||||
emitversions = featuresPat,
|
||||
defaultExtensions = None,
|
||||
addExtensions = addExtensionsPat,
|
||||
removeExtensions = removeExtensionsPat,
|
||||
emitExtensions = emitExtensionsPat,
|
||||
requireCommandAliases = True,
|
||||
)
|
||||
]
|
||||
|
||||
# API host sync table files for spec
|
||||
genOpts['hostsyncinc'] = [
|
||||
HostSynchronizationOutputGenerator,
|
||||
DocGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'timeMarker',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = featuresPat,
|
||||
emitversions = featuresPat,
|
||||
defaultExtensions = None,
|
||||
addExtensions = addExtensionsPat,
|
||||
removeExtensions = removeExtensionsPat,
|
||||
emitExtensions = emitExtensionsPat,
|
||||
reparentEnums = False)
|
||||
]
|
||||
|
||||
# Extension metainformation for spec extension appendices
|
||||
# Includes all extensions by default, but only so that the generated
|
||||
# 'promoted_extensions_*' files refer to all extensions that were
|
||||
# promoted to a core version.
|
||||
genOpts['extinc'] = [
|
||||
ExtensionMetaDocOutputGenerator,
|
||||
ExtensionMetaDocGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'timeMarker',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = featuresPat,
|
||||
emitversions = None,
|
||||
defaultExtensions = defaultExtensions,
|
||||
addExtensions = addExtensionsPat,
|
||||
removeExtensions = None,
|
||||
emitExtensions = emitExtensionsPat)
|
||||
]
|
||||
|
||||
# Version and extension interface docs for version/extension appendices
|
||||
# Includes all extensions by default.
|
||||
genOpts['interfaceinc'] = [
|
||||
InterfaceDocGenerator,
|
||||
DocGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'timeMarker',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = featuresPat,
|
||||
emitversions = featuresPat,
|
||||
defaultExtensions = None,
|
||||
addExtensions = addExtensionsPat,
|
||||
removeExtensions = removeExtensionsPat,
|
||||
emitExtensions = emitExtensionsPat,
|
||||
reparentEnums = False)
|
||||
]
|
||||
|
||||
genOpts['spirvcapinc'] = [
|
||||
SpirvCapabilityOutputGenerator,
|
||||
DocGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'timeMarker',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = featuresPat,
|
||||
emitversions = featuresPat,
|
||||
defaultExtensions = None,
|
||||
addExtensions = addExtensionsPat,
|
||||
removeExtensions = removeExtensionsPat,
|
||||
emitExtensions = emitExtensionsPat,
|
||||
emitSpirv = emitSpirvPat,
|
||||
reparentEnums = False)
|
||||
]
|
||||
|
||||
# Used to generate various format chapter tables
|
||||
genOpts['formatsinc'] = [
|
||||
FormatsOutputGenerator,
|
||||
DocGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'timeMarker',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = featuresPat,
|
||||
emitversions = featuresPat,
|
||||
defaultExtensions = None,
|
||||
addExtensions = addExtensionsPat,
|
||||
removeExtensions = removeExtensionsPat,
|
||||
emitExtensions = emitExtensionsPat,
|
||||
emitFormats = emitFormatsPat,
|
||||
reparentEnums = False)
|
||||
]
|
||||
|
||||
# Platform extensions, in their own header files
|
||||
# Each element of the platforms[] array defines information for
|
||||
# generating a single platform:
|
||||
# [0] is the generated header file name
|
||||
# [1] is the set of platform extensions to generate
|
||||
# [2] is additional extensions whose interfaces should be considered,
|
||||
# but suppressed in the output, to avoid duplicate definitions of
|
||||
# dependent types like VkDisplayKHR and VkSurfaceKHR which come from
|
||||
# non-platform extensions.
|
||||
|
||||
# Track all platform extensions, for exclusion from vulkan_core.h
|
||||
allPlatformExtensions = []
|
||||
|
||||
# Extensions suppressed for all WSI platforms (WSI extensions required
|
||||
# by all platforms)
|
||||
commonSuppressExtensions = [ 'VK_KHR_display', 'VK_KHR_swapchain' ]
|
||||
|
||||
# Extensions required and suppressed for beta "platform". This can
|
||||
# probably eventually be derived from the requires= attributes of
|
||||
# the extension blocks.
|
||||
betaRequireExtensions = [
|
||||
'VK_KHR_portability_subset',
|
||||
'VK_KHR_video_encode_queue',
|
||||
'VK_EXT_video_encode_h264',
|
||||
'VK_EXT_video_encode_h265',
|
||||
'VK_NV_displacement_micromap',
|
||||
]
|
||||
|
||||
betaSuppressExtensions = [
|
||||
'VK_KHR_video_queue',
|
||||
'VK_EXT_opacity_micromap',
|
||||
]
|
||||
|
||||
platforms = [
|
||||
[ 'vulkan_android.h', [ 'VK_KHR_android_surface',
|
||||
'VK_ANDROID_external_memory_android_hardware_buffer'
|
||||
], commonSuppressExtensions +
|
||||
[ 'VK_KHR_format_feature_flags2',
|
||||
] ],
|
||||
[ 'vulkan_fuchsia.h', [ 'VK_FUCHSIA_imagepipe_surface',
|
||||
'VK_FUCHSIA_external_memory',
|
||||
'VK_FUCHSIA_external_semaphore',
|
||||
'VK_FUCHSIA_buffer_collection' ], commonSuppressExtensions ],
|
||||
[ 'vulkan_ggp.h', [ 'VK_GGP_stream_descriptor_surface',
|
||||
'VK_GGP_frame_token' ], commonSuppressExtensions ],
|
||||
[ 'vulkan_ios.h', [ 'VK_MVK_ios_surface' ], commonSuppressExtensions ],
|
||||
[ 'vulkan_macos.h', [ 'VK_MVK_macos_surface' ], commonSuppressExtensions ],
|
||||
[ 'vulkan_vi.h', [ 'VK_NN_vi_surface' ], commonSuppressExtensions ],
|
||||
[ 'vulkan_wayland.h', [ 'VK_KHR_wayland_surface' ], commonSuppressExtensions ],
|
||||
[ 'vulkan_win32.h', [ 'VK_.*_win32(|_.*)', 'VK_.*_winrt(|_.*)', 'VK_EXT_full_screen_exclusive' ],
|
||||
commonSuppressExtensions +
|
||||
[ 'VK_KHR_external_semaphore',
|
||||
'VK_KHR_external_memory_capabilities',
|
||||
'VK_KHR_external_fence',
|
||||
'VK_KHR_external_fence_capabilities',
|
||||
'VK_KHR_get_surface_capabilities2',
|
||||
'VK_NV_external_memory_capabilities',
|
||||
] ],
|
||||
[ 'vulkan_xcb.h', [ 'VK_KHR_xcb_surface' ], commonSuppressExtensions ],
|
||||
[ 'vulkan_xlib.h', [ 'VK_KHR_xlib_surface' ], commonSuppressExtensions ],
|
||||
[ 'vulkan_directfb.h', [ 'VK_EXT_directfb_surface' ], commonSuppressExtensions ],
|
||||
[ 'vulkan_xlib_xrandr.h', [ 'VK_EXT_acquire_xlib_display' ], commonSuppressExtensions ],
|
||||
[ 'vulkan_metal.h', [ 'VK_EXT_metal_surface',
|
||||
'VK_EXT_metal_objects' ], commonSuppressExtensions ],
|
||||
[ 'vulkan_screen.h', [ 'VK_QNX_screen_surface' ], commonSuppressExtensions ],
|
||||
[ 'vulkan_beta.h', betaRequireExtensions, betaSuppressExtensions ],
|
||||
]
|
||||
|
||||
for platform in platforms:
|
||||
headername = platform[0]
|
||||
|
||||
allPlatformExtensions += platform[1]
|
||||
|
||||
addPlatformExtensionsRE = makeREstring(
|
||||
platform[1] + platform[2], strings_are_regex=True)
|
||||
emitPlatformExtensionsRE = makeREstring(
|
||||
platform[1], strings_are_regex=True)
|
||||
|
||||
opts = CGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = headername,
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = featuresPat,
|
||||
emitversions = None,
|
||||
defaultExtensions = None,
|
||||
addExtensions = addPlatformExtensionsRE,
|
||||
removeExtensions = None,
|
||||
emitExtensions = emitPlatformExtensionsRE,
|
||||
prefixText = prefixStrings + vkPrefixStrings,
|
||||
genFuncPointers = True,
|
||||
protectFile = protectFile,
|
||||
protectFeature = False,
|
||||
protectProto = '#ifndef',
|
||||
protectProtoStr = 'VK_NO_PROTOTYPES',
|
||||
apicall = 'VKAPI_ATTR ',
|
||||
apientry = 'VKAPI_CALL ',
|
||||
apientryp = 'VKAPI_PTR *',
|
||||
alignFuncParam = 48,
|
||||
misracstyle = misracstyle,
|
||||
misracppstyle = misracppstyle)
|
||||
|
||||
genOpts[headername] = [ COutputGenerator, opts ]
|
||||
|
||||
# Header for core API + extensions.
|
||||
# To generate just the core API,
|
||||
# change to 'defaultExtensions = None' below.
|
||||
#
|
||||
# By default this adds all enabled, non-platform extensions.
|
||||
# It removes all platform extensions (from the platform headers options
|
||||
# constructed above) as well as any explicitly specified removals.
|
||||
|
||||
removeExtensionsPat = makeREstring(
|
||||
allPlatformExtensions + removeExtensions, None, strings_are_regex=True)
|
||||
|
||||
genOpts['vulkan_core.h'] = [
|
||||
COutputGenerator,
|
||||
CGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'vulkan_core.h',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = featuresPat,
|
||||
emitversions = featuresPat,
|
||||
defaultExtensions = defaultExtensions,
|
||||
addExtensions = addExtensionsPat,
|
||||
removeExtensions = removeExtensionsPat,
|
||||
emitExtensions = emitExtensionsPat,
|
||||
prefixText = prefixStrings + vkPrefixStrings,
|
||||
genFuncPointers = True,
|
||||
protectFile = protectFile,
|
||||
protectFeature = False,
|
||||
protectProto = '#ifndef',
|
||||
protectProtoStr = 'VK_NO_PROTOTYPES',
|
||||
apicall = 'VKAPI_ATTR ',
|
||||
apientry = 'VKAPI_CALL ',
|
||||
apientryp = 'VKAPI_PTR *',
|
||||
alignFuncParam = 48,
|
||||
misracstyle = misracstyle,
|
||||
misracppstyle = misracppstyle)
|
||||
]
|
||||
|
||||
# Unused - vulkan10.h target.
|
||||
# It is possible to generate a header with just the Vulkan 1.0 +
|
||||
# extension interfaces defined, but since the promoted KHR extensions
|
||||
# are now defined in terms of the 1.1 interfaces, such a header is very
|
||||
# similar to vulkan_core.h.
|
||||
genOpts['vulkan10.h'] = [
|
||||
COutputGenerator,
|
||||
CGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'vulkan10.h',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = 'VK_VERSION_1_0',
|
||||
emitversions = 'VK_VERSION_1_0',
|
||||
defaultExtensions = None,
|
||||
addExtensions = None,
|
||||
removeExtensions = None,
|
||||
emitExtensions = None,
|
||||
prefixText = prefixStrings + vkPrefixStrings,
|
||||
genFuncPointers = True,
|
||||
protectFile = protectFile,
|
||||
protectFeature = False,
|
||||
protectProto = '#ifndef',
|
||||
protectProtoStr = 'VK_NO_PROTOTYPES',
|
||||
apicall = 'VKAPI_ATTR ',
|
||||
apientry = 'VKAPI_CALL ',
|
||||
apientryp = 'VKAPI_PTR *',
|
||||
alignFuncParam = 48,
|
||||
misracstyle = misracstyle,
|
||||
misracppstyle = misracppstyle)
|
||||
]
|
||||
|
||||
# Video header target - combines all video extension dependencies into a
|
||||
# single header, at present.
|
||||
genOpts['vk_video.h'] = [
|
||||
COutputGenerator,
|
||||
CGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'vk_video.h',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = 'vulkan',
|
||||
profile = None,
|
||||
versions = None,
|
||||
emitversions = None,
|
||||
defaultExtensions = defaultExtensions,
|
||||
addExtensions = addExtensionsPat,
|
||||
removeExtensions = removeExtensionsPat,
|
||||
emitExtensions = emitExtensionsPat,
|
||||
prefixText = prefixStrings + vkPrefixStrings,
|
||||
genFuncPointers = True,
|
||||
protectFile = protectFile,
|
||||
protectFeature = False,
|
||||
protectProto = '#ifndef',
|
||||
protectProtoStr = 'VK_NO_PROTOTYPES',
|
||||
apicall = '',
|
||||
apientry = '',
|
||||
apientryp = '',
|
||||
alignFuncParam = 48,
|
||||
misracstyle = misracstyle,
|
||||
misracppstyle = misracppstyle)
|
||||
]
|
||||
|
||||
# Video extension 'Std' interfaces, each in its own header files
|
||||
# These are not Vulkan extensions, or a part of the Vulkan API at all,
|
||||
# but are treated in a similar fashion for generation purposes.
|
||||
#
|
||||
# Each element of the videoStd[] array is an extension name defining an
|
||||
# interface, and is also the basis for the generated header file name.
|
||||
|
||||
videoStd = [
|
||||
'vulkan_video_codecs_common',
|
||||
'vulkan_video_codec_h264std',
|
||||
'vulkan_video_codec_h264std_decode',
|
||||
'vulkan_video_codec_h264std_encode',
|
||||
'vulkan_video_codec_h265std',
|
||||
'vulkan_video_codec_h265std_decode',
|
||||
'vulkan_video_codec_h265std_encode',
|
||||
]
|
||||
|
||||
addExtensionRE = makeREstring(videoStd)
|
||||
for codec in videoStd:
|
||||
headername = f'{codec}.h'
|
||||
|
||||
# Consider all of the codecs 'extensions', but only emit this one
|
||||
emitExtensionRE = makeREstring([codec])
|
||||
|
||||
opts = CGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = headername,
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = None,
|
||||
emitversions = None,
|
||||
defaultExtensions = None,
|
||||
addExtensions = addExtensionRE,
|
||||
removeExtensions = None,
|
||||
emitExtensions = emitExtensionRE,
|
||||
prefixText = prefixStrings + vkPrefixStrings,
|
||||
genFuncPointers = False,
|
||||
protectFile = protectFile,
|
||||
protectFeature = False,
|
||||
alignFuncParam = 48,
|
||||
)
|
||||
|
||||
genOpts[headername] = [ COutputGenerator, opts ]
|
||||
|
||||
# Unused - vulkan11.h target.
|
||||
# It is possible to generate a header with just the Vulkan 1.0 +
|
||||
# extension interfaces defined, but since the promoted KHR extensions
|
||||
# are now defined in terms of the 1.1 interfaces, such a header is very
|
||||
# similar to vulkan_core.h.
|
||||
genOpts['vulkan11.h'] = [
|
||||
COutputGenerator,
|
||||
CGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'vulkan11.h',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = '^VK_VERSION_1_[01]$',
|
||||
emitversions = '^VK_VERSION_1_[01]$',
|
||||
defaultExtensions = None,
|
||||
addExtensions = None,
|
||||
removeExtensions = None,
|
||||
emitExtensions = None,
|
||||
prefixText = prefixStrings + vkPrefixStrings,
|
||||
genFuncPointers = True,
|
||||
protectFile = protectFile,
|
||||
protectFeature = False,
|
||||
protectProto = '#ifndef',
|
||||
protectProtoStr = 'VK_NO_PROTOTYPES',
|
||||
apicall = 'VKAPI_ATTR ',
|
||||
apientry = 'VKAPI_CALL ',
|
||||
apientryp = 'VKAPI_PTR *',
|
||||
alignFuncParam = 48,
|
||||
misracstyle = misracstyle,
|
||||
misracppstyle = misracppstyle)
|
||||
]
|
||||
|
||||
genOpts['alias.h'] = [
|
||||
COutputGenerator,
|
||||
CGeneratorOptions(
|
||||
conventions = conventions,
|
||||
filename = 'alias.h',
|
||||
directory = directory,
|
||||
genpath = None,
|
||||
apiname = defaultAPIName,
|
||||
profile = None,
|
||||
versions = featuresPat,
|
||||
emitversions = featuresPat,
|
||||
defaultExtensions = defaultExtensions,
|
||||
addExtensions = None,
|
||||
removeExtensions = removeExtensionsPat,
|
||||
emitExtensions = emitExtensionsPat,
|
||||
prefixText = None,
|
||||
genFuncPointers = False,
|
||||
protectFile = False,
|
||||
protectFeature = False,
|
||||
protectProto = '',
|
||||
protectProtoStr = '',
|
||||
apicall = '',
|
||||
apientry = '',
|
||||
apientryp = '',
|
||||
alignFuncParam = 36)
|
||||
]
|
||||
|
||||
|
||||
def genTarget(args):
|
||||
"""Create an API generator and corresponding generator options based on
|
||||
the requested target and command line options.
|
||||
|
||||
This is encapsulated in a function so it can be profiled and/or timed.
|
||||
The args parameter is an parsed argument object containing the following
|
||||
fields that are used:
|
||||
|
||||
- target - target to generate
|
||||
- directory - directory to generate it in
|
||||
- protect - True if re-inclusion wrappers should be created
|
||||
- extensions - list of additional extensions to include in generated interfaces"""
|
||||
|
||||
# Create generator options with parameters specified on command line
|
||||
makeGenOpts(args)
|
||||
|
||||
# Select a generator matching the requested target
|
||||
if args.target in genOpts:
|
||||
createGenerator = genOpts[args.target][0]
|
||||
options = genOpts[args.target][1]
|
||||
|
||||
logDiag('* Building', options.filename)
|
||||
logDiag('* options.versions =', options.versions)
|
||||
logDiag('* options.emitversions =', options.emitversions)
|
||||
logDiag('* options.defaultExtensions =', options.defaultExtensions)
|
||||
logDiag('* options.addExtensions =', options.addExtensions)
|
||||
logDiag('* options.removeExtensions =', options.removeExtensions)
|
||||
logDiag('* options.emitExtensions =', options.emitExtensions)
|
||||
logDiag('* options.emitSpirv =', options.emitSpirv)
|
||||
logDiag('* options.emitFormats =', options.emitFormats)
|
||||
|
||||
gen = createGenerator(errFile=errWarn,
|
||||
warnFile=errWarn,
|
||||
diagFile=diag)
|
||||
return (gen, options)
|
||||
else:
|
||||
logErr('No generator options for unknown target:', args.target)
|
||||
return None
|
||||
|
||||
|
||||
# -feature name
|
||||
# -extension name
|
||||
# For both, "name" may be a single name, or a space-separated list
|
||||
# of names, or a regular expression.
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('-apiname', action='store',
|
||||
default=None,
|
||||
help='Specify API to generate (defaults to repository-specific conventions object value)')
|
||||
parser.add_argument('-defaultExtensions', action='store',
|
||||
default=APIConventions().xml_api_name,
|
||||
help='Specify a single class of extensions to add to targets')
|
||||
parser.add_argument('-extension', action='append',
|
||||
default=[],
|
||||
help='Specify an extension or extensions to add to targets')
|
||||
parser.add_argument('-removeExtensions', action='append',
|
||||
default=[],
|
||||
help='Specify an extension or extensions to remove from targets')
|
||||
parser.add_argument('-emitExtensions', action='append',
|
||||
default=[],
|
||||
help='Specify an extension or extensions to emit in targets')
|
||||
parser.add_argument('-emitSpirv', action='append',
|
||||
default=[],
|
||||
help='Specify a SPIR-V extension or capability to emit in targets')
|
||||
parser.add_argument('-emitFormats', action='append',
|
||||
default=[],
|
||||
help='Specify Vulkan Formats to emit in targets')
|
||||
parser.add_argument('-feature', action='append',
|
||||
default=[],
|
||||
help='Specify a core API feature name or names to add to targets')
|
||||
parser.add_argument('-debug', action='store_true',
|
||||
help='Enable debugging')
|
||||
parser.add_argument('-dump', action='store_true',
|
||||
help='Enable dump to stderr')
|
||||
parser.add_argument('-diagfile', action='store',
|
||||
default=None,
|
||||
help='Write diagnostics to specified file')
|
||||
parser.add_argument('-errfile', action='store',
|
||||
default=None,
|
||||
help='Write errors and warnings to specified file instead of stderr')
|
||||
parser.add_argument('-noprotect', dest='protect', action='store_false',
|
||||
help='Disable inclusion protection in output headers')
|
||||
parser.add_argument('-profile', action='store_true',
|
||||
help='Enable profiling')
|
||||
parser.add_argument('-registry', action='store',
|
||||
default='vk.xml',
|
||||
help='Use specified registry file instead of vk.xml')
|
||||
parser.add_argument('-time', action='store_true',
|
||||
help='Enable timing')
|
||||
parser.add_argument('-genpath', action='store', default='gen',
|
||||
help='Path to generated files')
|
||||
parser.add_argument('-o', action='store', dest='directory',
|
||||
default='.',
|
||||
help='Create target and related files in specified directory')
|
||||
parser.add_argument('target', metavar='target', nargs='?',
|
||||
help='Specify target')
|
||||
parser.add_argument('-quiet', action='store_true', default=True,
|
||||
help='Suppress script output during normal execution.')
|
||||
parser.add_argument('-verbose', action='store_false', dest='quiet', default=True,
|
||||
help='Enable script output during normal execution.')
|
||||
parser.add_argument('-misracstyle', dest='misracstyle', action='store_true',
|
||||
help='generate MISRA C-friendly headers')
|
||||
parser.add_argument('-misracppstyle', dest='misracppstyle', action='store_true',
|
||||
help='generate MISRA C++-friendly headers')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# This splits arguments which are space-separated lists
|
||||
args.feature = [name for arg in args.feature for name in arg.split()]
|
||||
args.extension = [name for arg in args.extension for name in arg.split()]
|
||||
|
||||
# create error/warning & diagnostic files
|
||||
if args.errfile:
|
||||
errWarn = open(args.errfile, 'w', encoding='utf-8')
|
||||
else:
|
||||
errWarn = sys.stderr
|
||||
|
||||
if args.diagfile:
|
||||
diag = open(args.diagfile, 'w', encoding='utf-8')
|
||||
else:
|
||||
diag = None
|
||||
|
||||
if args.time:
|
||||
# Log diagnostics and warnings
|
||||
setLogFile(setDiag = True, setWarn = True, filename = '-')
|
||||
|
||||
# Create the API generator & generator options
|
||||
(gen, options) = genTarget(args)
|
||||
|
||||
# Create the registry object with the specified generator and generator
|
||||
# options. The options are set before XML loading as they may affect it.
|
||||
reg = Registry(gen, options)
|
||||
|
||||
# Parse the specified registry XML into an ElementTree object
|
||||
startTimer(args.time)
|
||||
tree = etree.parse(args.registry)
|
||||
endTimer(args.time, '* Time to make ElementTree =')
|
||||
|
||||
# Load the XML tree into the registry object
|
||||
startTimer(args.time)
|
||||
reg.loadElementTree(tree)
|
||||
endTimer(args.time, '* Time to parse ElementTree =')
|
||||
|
||||
if args.dump:
|
||||
logDiag('* Dumping registry to regdump.txt')
|
||||
reg.dumpReg(filehandle=open('regdump.txt', 'w', encoding='utf-8'))
|
||||
|
||||
# Finally, use the output generator to create the requested target
|
||||
if args.debug:
|
||||
pdb.run('reg.apiGen()')
|
||||
else:
|
||||
startTimer(args.time)
|
||||
reg.apiGen()
|
||||
endTimer(args.time, '* Time to generate ' + options.filename + ' =')
|
||||
|
||||
if not args.quiet:
|
||||
logDiag('* Generated', options.filename)
|
||||
|
|
@ -1,354 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
# Copyright 2022-2023 The Khronos Group Inc.
|
||||
# Copyright 2003-2019 Paul McGuire
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# apirequirements.py - parse 'depends' expressions in API XML
|
||||
# Supported methods:
|
||||
# dependency - the expression string
|
||||
#
|
||||
# evaluateDependency(dependency, isSupported) evaluates the expression,
|
||||
# returning a boolean result. isSupported takes an extension or version name
|
||||
# string and returns a boolean.
|
||||
#
|
||||
# dependencyLanguage(dependency) returns an English string equivalent
|
||||
# to the expression, suitable for header file comments.
|
||||
#
|
||||
# dependencyNames(dependency) returns a set of the extension and
|
||||
# version names in the expression.
|
||||
#
|
||||
# dependencyMarkup(dependency) returns a string containing asciidoctor
|
||||
# markup for English equivalent to the expression, suitable for extension
|
||||
# appendices.
|
||||
#
|
||||
# All may throw a ParseException if the expression cannot be parsed or is
|
||||
# not completely consumed by parsing.
|
||||
|
||||
# Supported expressions at present:
|
||||
# - extension names
|
||||
# - '+' as AND connector
|
||||
# - ',' as OR connector
|
||||
# - parenthesization for grouping
|
||||
|
||||
# Based on https://github.com/pyparsing/pyparsing/blob/master/examples/fourFn.py
|
||||
|
||||
from pyparsing import (
|
||||
Literal,
|
||||
Word,
|
||||
Group,
|
||||
Forward,
|
||||
alphas,
|
||||
alphanums,
|
||||
Regex,
|
||||
ParseException,
|
||||
CaselessKeyword,
|
||||
Suppress,
|
||||
delimitedList,
|
||||
infixNotation,
|
||||
)
|
||||
import math
|
||||
import operator
|
||||
import pyparsing as pp
|
||||
import re
|
||||
|
||||
def nameMarkup(name):
|
||||
"""Returns asciidoc markup to generate a link to an API version or
|
||||
extension anchor.
|
||||
|
||||
- name - version or extension name"""
|
||||
|
||||
# Could use ApiConventions.is_api_version_name, but that does not split
|
||||
# out the major/minor version numbers.
|
||||
match = re.search("[A-Z]+_VERSION_([0-9]+)_([0-9]+)", name)
|
||||
if match is not None:
|
||||
major = match.group(1)
|
||||
minor = match.group(2)
|
||||
version = major + '.' + minor
|
||||
return f'<<versions-{major}.{minor}, Version {version}>>'
|
||||
else:
|
||||
return 'apiext:' + name
|
||||
|
||||
exprStack = []
|
||||
|
||||
def push_first(toks):
|
||||
"""Push a token on the global stack
|
||||
|
||||
- toks - first element is the token to push"""
|
||||
|
||||
exprStack.append(toks[0])
|
||||
|
||||
# An identifier (version or extension name)
|
||||
dependencyIdent = Word(alphanums + '_')
|
||||
|
||||
# Infix expression for depends expressions
|
||||
dependencyExpr = pp.infixNotation(dependencyIdent,
|
||||
[ (pp.oneOf(', +'), 2, pp.opAssoc.LEFT), ])
|
||||
|
||||
# BNF grammar for depends expressions
|
||||
_bnf = None
|
||||
def dependencyBNF():
|
||||
"""
|
||||
boolop :: '+' | ','
|
||||
extname :: Char(alphas)
|
||||
atom :: extname | '(' expr ')'
|
||||
expr :: atom [ boolop atom ]*
|
||||
"""
|
||||
global _bnf
|
||||
if _bnf is None:
|
||||
and_, or_ = map(Literal, '+,')
|
||||
lpar, rpar = map(Suppress, '()')
|
||||
boolop = and_ | or_
|
||||
|
||||
expr = Forward()
|
||||
expr_list = delimitedList(Group(expr))
|
||||
atom = (
|
||||
boolop[...]
|
||||
+ (
|
||||
(dependencyIdent).setParseAction(push_first)
|
||||
| Group(lpar + expr + rpar)
|
||||
)
|
||||
)
|
||||
|
||||
expr <<= atom + (boolop + atom).setParseAction(push_first)[...]
|
||||
_bnf = expr
|
||||
return _bnf
|
||||
|
||||
|
||||
# map operator symbols to corresponding arithmetic operations
|
||||
_opn = {
|
||||
'+': operator.and_,
|
||||
',': operator.or_,
|
||||
}
|
||||
|
||||
# map operator symbols to corresponding words
|
||||
_opname = {
|
||||
'+': 'and',
|
||||
',': 'or',
|
||||
}
|
||||
|
||||
def evaluateStack(stack, isSupported):
|
||||
"""Evaluate an expression stack, returning a boolean result.
|
||||
|
||||
- stack - the stack
|
||||
- isSupported - function taking a version or extension name string and
|
||||
returning True or False if that name is supported or not."""
|
||||
|
||||
op, num_args = stack.pop(), 0
|
||||
if isinstance(op, tuple):
|
||||
op, num_args = op
|
||||
|
||||
if op in '+,':
|
||||
# Note: operands are pushed onto the stack in reverse order
|
||||
op2 = evaluateStack(stack, isSupported)
|
||||
op1 = evaluateStack(stack, isSupported)
|
||||
return _opn[op](op1, op2)
|
||||
elif op[0].isalpha():
|
||||
return isSupported(op)
|
||||
else:
|
||||
raise Exception(f'invalid op: {op}')
|
||||
|
||||
def evaluateDependency(dependency, isSupported):
|
||||
"""Evaluate a dependency expression, returning a boolean result.
|
||||
|
||||
- dependency - the expression
|
||||
- isSupported - function taking a version or extension name string and
|
||||
returning True or False if that name is supported or not."""
|
||||
|
||||
global exprStack
|
||||
exprStack = []
|
||||
results = dependencyBNF().parseString(dependency, parseAll=True)
|
||||
val = evaluateStack(exprStack[:], isSupported)
|
||||
return val
|
||||
|
||||
def evalDependencyLanguage(stack, specmacros):
|
||||
"""Evaluate an expression stack, returning an English equivalent
|
||||
|
||||
- stack - the stack
|
||||
- specmacros - if True, prepare the language for spec inclusion"""
|
||||
|
||||
op, num_args = stack.pop(), 0
|
||||
if isinstance(op, tuple):
|
||||
op, num_args = op
|
||||
if op in '+,':
|
||||
# Could parenthesize, not needed yet
|
||||
rhs = evalDependencyLanguage(stack, specmacros)
|
||||
return evalDependencyLanguage(stack, specmacros) + f' {_opname[op]} ' + rhs
|
||||
elif op[0].isalpha():
|
||||
# This is an extension or feature name
|
||||
if specmacros:
|
||||
return nameMarkup(op)
|
||||
else:
|
||||
return op
|
||||
else:
|
||||
raise Exception(f'invalid op: {op}')
|
||||
|
||||
def dependencyLanguage(dependency, specmacros = False):
|
||||
"""Return an API dependency expression translated to a form suitable for
|
||||
asciidoctor conditionals or header file comments.
|
||||
|
||||
- dependency - the expression
|
||||
- specmacros - if False, return a string that can be used as an
|
||||
asciidoctor conditional.
|
||||
If True, return a string suitable for spec inclusion with macros and
|
||||
xrefs included."""
|
||||
|
||||
global exprStack
|
||||
exprStack = []
|
||||
results = dependencyBNF().parseString(dependency, parseAll=True)
|
||||
return evalDependencyLanguage(exprStack, specmacros)
|
||||
|
||||
def evalDependencyNames(stack):
|
||||
"""Evaluate an expression stack, returning the set of extension and
|
||||
feature names used in the expression.
|
||||
|
||||
- stack - the stack"""
|
||||
|
||||
op, num_args = stack.pop(), 0
|
||||
if isinstance(op, tuple):
|
||||
op, num_args = op
|
||||
if op in '+,':
|
||||
# Do not evaluate the operation. We only care about the names.
|
||||
return evalDependencyNames(stack) | evalDependencyNames(stack)
|
||||
elif op[0].isalpha():
|
||||
return { op }
|
||||
else:
|
||||
raise Exception(f'invalid op: {op}')
|
||||
|
||||
def dependencyNames(dependency):
|
||||
"""Return a set of the extension and version names in an API dependency
|
||||
expression. Used when determining transitive dependencies for spec
|
||||
generation with specific extensions included.
|
||||
|
||||
- dependency - the expression"""
|
||||
|
||||
global exprStack
|
||||
exprStack = []
|
||||
results = dependencyBNF().parseString(dependency, parseAll=True)
|
||||
# print(f'names(): stack = {exprStack}')
|
||||
return evalDependencyNames(exprStack)
|
||||
|
||||
def markupTraverse(expr, level = 0, root = True):
|
||||
"""Recursively process a dependency in infix form, transforming it into
|
||||
asciidoctor markup with expression nesting indicated by indentation
|
||||
level.
|
||||
|
||||
- expr - expression to process
|
||||
- level - indentation level to render expression at
|
||||
- root - True only on initial call"""
|
||||
|
||||
if level > 0:
|
||||
prefix = '{nbsp}{nbsp}' * level * 2 + ' '
|
||||
else:
|
||||
prefix = ''
|
||||
str = ''
|
||||
|
||||
for elem in expr:
|
||||
if isinstance(elem, pp.ParseResults):
|
||||
if not root:
|
||||
nextlevel = level + 1
|
||||
else:
|
||||
# Do not indent the outer expression
|
||||
nextlevel = level
|
||||
|
||||
str = str + markupTraverse(elem, level = nextlevel, root = False)
|
||||
elif elem in ('+', ','):
|
||||
str = str + f'{prefix}{_opname[elem]} +\n'
|
||||
else:
|
||||
str = str + f'{prefix}{nameMarkup(elem)} +\n'
|
||||
|
||||
return str
|
||||
|
||||
def dependencyMarkup(dependency):
|
||||
"""Return asciidoctor markup for a human-readable equivalent of an API
|
||||
dependency expression, suitable for use in extension appendix
|
||||
metadata.
|
||||
|
||||
- dependency - the expression"""
|
||||
|
||||
parsed = dependencyExpr.parseString(dependency)
|
||||
return markupTraverse(parsed)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
termdict = {
|
||||
'VK_VERSION_1_1' : True,
|
||||
'false' : False,
|
||||
'true' : True,
|
||||
}
|
||||
termSupported = lambda name: name in termdict and termdict[name]
|
||||
|
||||
def test(dependency, expected):
|
||||
val = False
|
||||
try:
|
||||
val = evaluateDependency(dependency, termSupported)
|
||||
except ParseException as pe:
|
||||
print(dependency, f'failed parse: {dependency}')
|
||||
except Exception as e:
|
||||
print(dependency, f'failed eval: {dependency}')
|
||||
|
||||
if val == expected:
|
||||
print(f'{dependency} = {val} (as expected)')
|
||||
else:
|
||||
print(f'{dependency} ERROR: {val} != {expected}')
|
||||
|
||||
# Verify expressions are evaluated left-to-right
|
||||
|
||||
test('false,false+false', False)
|
||||
test('false,false+true', False)
|
||||
test('false,true+false', False)
|
||||
test('false,true+true', True)
|
||||
test('true,false+false', False)
|
||||
test('true,false+true', True)
|
||||
test('true,true+false', False)
|
||||
test('true,true+true', True)
|
||||
|
||||
test('false,(false+false)', False)
|
||||
test('false,(false+true)', False)
|
||||
test('false,(true+false)', False)
|
||||
test('false,(true+true)', True)
|
||||
test('true,(false+false)', True)
|
||||
test('true,(false+true)', True)
|
||||
test('true,(true+false)', True)
|
||||
test('true,(true+true)', True)
|
||||
|
||||
|
||||
test('false+false,false', False)
|
||||
test('false+false,true', True)
|
||||
test('false+true,false', False)
|
||||
test('false+true,true', True)
|
||||
test('true+false,false', False)
|
||||
test('true+false,true', True)
|
||||
test('true+true,false', True)
|
||||
test('true+true,true', True)
|
||||
|
||||
test('false+(false,false)', False)
|
||||
test('false+(false,true)', False)
|
||||
test('false+(true,false)', False)
|
||||
test('false+(true,true)', False)
|
||||
test('true+(false,false)', False)
|
||||
test('true+(false,true)', True)
|
||||
test('true+(true,false)', True)
|
||||
test('true+(true,true)', True)
|
||||
|
||||
|
||||
#test('VK_VERSION_1_1+(false,true)', True)
|
||||
#test('true', True)
|
||||
#test('(true)', True)
|
||||
#test('false,false', False)
|
||||
#test('false,true', True)
|
||||
#test('false+true', False)
|
||||
#test('true+true', True)
|
||||
|
||||
# Check formatting
|
||||
for dependency in [
|
||||
#'true',
|
||||
#'true+true+false',
|
||||
'true+(true+false),(false,true)',
|
||||
'true+((true+false),(false,true))',
|
||||
#'VK_VERSION_1_1+(true,false)',
|
||||
]:
|
||||
print(f'expr = {dependency}\n{dependencyMarkup(dependency)}')
|
||||
print(f' language = {dependencyLanguage(dependency)}')
|
||||
print(f' names = {dependencyNames(dependency)}')
|
||||
print(f' value = {evaluateDependency(dependency, termSupported)}')
|
||||
|
|
@ -1,381 +0,0 @@
|
|||
{
|
||||
"$schema": "https://schema.khronos.org/vulkan/profiles-0.8.1-204.json#",
|
||||
"capabilities": {
|
||||
"vulkan10requirements": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceFeatures": {
|
||||
"robustBufferAccess": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan10requirements_roadmap2022": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceFeatures": {
|
||||
"fullDrawIndexUint32": true,
|
||||
"imageCubeArray": true,
|
||||
"independentBlend": true,
|
||||
"sampleRateShading": true,
|
||||
"drawIndirectFirstInstance": true,
|
||||
"depthClamp": true,
|
||||
"depthBiasClamp": true,
|
||||
"samplerAnisotropy": true,
|
||||
"occlusionQueryPrecise": true,
|
||||
"fragmentStoresAndAtomics": true,
|
||||
"shaderStorageImageExtendedFormats": true,
|
||||
"shaderUniformBufferArrayDynamicIndexing": true,
|
||||
"shaderSampledImageArrayDynamicIndexing": true,
|
||||
"shaderStorageBufferArrayDynamicIndexing": true,
|
||||
"shaderStorageImageArrayDynamicIndexing": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceProperties": {
|
||||
"limits": {
|
||||
"maxImageDimension1D": 8192,
|
||||
"maxImageDimension2D": 8192,
|
||||
"maxImageDimensionCube": 8192,
|
||||
"maxImageArrayLayers": 2048,
|
||||
"maxUniformBufferRange": 65536,
|
||||
"bufferImageGranularity": 4096,
|
||||
"maxPerStageDescriptorSamplers": 64,
|
||||
"maxPerStageDescriptorUniformBuffers": 15,
|
||||
"maxPerStageDescriptorStorageBuffers": 30,
|
||||
"maxPerStageDescriptorSampledImages": 200,
|
||||
"maxPerStageDescriptorStorageImages": 16,
|
||||
"maxPerStageResources": 200,
|
||||
"maxDescriptorSetSamplers": 576,
|
||||
"maxDescriptorSetUniformBuffers": 90,
|
||||
"maxDescriptorSetStorageBuffers": 96,
|
||||
"maxDescriptorSetSampledImages": 1800,
|
||||
"maxDescriptorSetStorageImages": 144,
|
||||
"maxFragmentCombinedOutputResources": 16,
|
||||
"maxComputeWorkGroupInvocations": 256,
|
||||
"maxComputeWorkGroupSize": [ 256, 256, 64 ],
|
||||
"subTexelPrecisionBits": 8,
|
||||
"mipmapPrecisionBits": 6,
|
||||
"maxSamplerLodBias": 14,
|
||||
"standardSampleLocations": true,
|
||||
"maxColorAttachments": 7
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan10optionals_roadmap2022": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceFeatures": {
|
||||
"largePoints": true,
|
||||
"wideLines": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceProperties": {
|
||||
"limits": {
|
||||
"pointSizeGranularity": 0.125,
|
||||
"lineWidthGranularity": 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan11requirements": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan11Features": {
|
||||
"multiview": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceVulkan11Properties": {
|
||||
"maxMultiviewViewCount": 6,
|
||||
"maxMultiviewInstanceIndex": 134217727
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan11requirements_roadmap2022": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan11Features": {
|
||||
"samplerYcbcrConversion": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceVulkan11Properties": {
|
||||
"subgroupSize": 4,
|
||||
"subgroupSupportedStages": [ "VK_SHADER_STAGE_COMPUTE_BIT", "VK_SHADER_STAGE_FRAGMENT_BIT" ],
|
||||
"subgroupSupportedOperations": [ "VK_SUBGROUP_FEATURE_BASIC_BIT", "VK_SUBGROUP_FEATURE_VOTE_BIT", "VK_SUBGROUP_FEATURE_ARITHMETIC_BIT", "VK_SUBGROUP_FEATURE_BALLOT_BIT", "VK_SUBGROUP_FEATURE_SHUFFLE_BIT", "VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT", "VK_SUBGROUP_FEATURE_QUAD_BIT" ]
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan12requirements": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan12Features": {
|
||||
"uniformBufferStandardLayout": true,
|
||||
"subgroupBroadcastDynamicId": true,
|
||||
"imagelessFramebuffer": true,
|
||||
"separateDepthStencilLayouts": true,
|
||||
"hostQueryReset": true,
|
||||
"timelineSemaphore": true,
|
||||
"shaderSubgroupExtendedTypes": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceVulkan12Properties": {
|
||||
"maxTimelineSemaphoreValueDifference": 2147483647
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan12requirements_roadmap2022": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan12Features": {
|
||||
"samplerMirrorClampToEdge": true,
|
||||
"descriptorIndexing": true,
|
||||
"shaderUniformTexelBufferArrayDynamicIndexing": true,
|
||||
"shaderStorageTexelBufferArrayDynamicIndexing": true,
|
||||
"shaderUniformBufferArrayNonUniformIndexing": true,
|
||||
"shaderSampledImageArrayNonUniformIndexing": true,
|
||||
"shaderStorageBufferArrayNonUniformIndexing": true,
|
||||
"shaderStorageImageArrayNonUniformIndexing": true,
|
||||
"shaderUniformTexelBufferArrayNonUniformIndexing": true,
|
||||
"shaderStorageTexelBufferArrayNonUniformIndexing": true,
|
||||
"descriptorBindingSampledImageUpdateAfterBind": true,
|
||||
"descriptorBindingStorageImageUpdateAfterBind": true,
|
||||
"descriptorBindingStorageBufferUpdateAfterBind": true,
|
||||
"descriptorBindingUniformTexelBufferUpdateAfterBind": true,
|
||||
"descriptorBindingStorageTexelBufferUpdateAfterBind": true,
|
||||
"descriptorBindingUpdateUnusedWhilePending": true,
|
||||
"descriptorBindingPartiallyBound": true,
|
||||
"descriptorBindingVariableDescriptorCount": true,
|
||||
"runtimeDescriptorArray": true,
|
||||
"scalarBlockLayout": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceVulkan12Properties": {
|
||||
"shaderSignedZeroInfNanPreserveFloat16": true,
|
||||
"shaderSignedZeroInfNanPreserveFloat32": true,
|
||||
"maxPerStageDescriptorUpdateAfterBindSamplers": 500000,
|
||||
"maxPerStageDescriptorUpdateAfterBindUniformBuffers": 12,
|
||||
"maxPerStageDescriptorUpdateAfterBindStorageBuffers": 500000,
|
||||
"maxPerStageDescriptorUpdateAfterBindSampledImages": 500000,
|
||||
"maxPerStageDescriptorUpdateAfterBindStorageImages": 500000,
|
||||
"maxPerStageDescriptorUpdateAfterBindInputAttachments": 7,
|
||||
"maxPerStageUpdateAfterBindResources": 500000,
|
||||
"maxDescriptorSetUpdateAfterBindSamplers": 500000,
|
||||
"maxDescriptorSetUpdateAfterBindUniformBuffers": 72,
|
||||
"maxDescriptorSetUpdateAfterBindUniformBuffersDynamic": 8,
|
||||
"maxDescriptorSetUpdateAfterBindStorageBuffers": 500000,
|
||||
"maxDescriptorSetUpdateAfterBindStorageBuffersDynamic": 4,
|
||||
"maxDescriptorSetUpdateAfterBindSampledImages": 500000,
|
||||
"maxDescriptorSetUpdateAfterBindStorageImages": 500000,
|
||||
"maxDescriptorSetUpdateAfterBindInputAttachments": 7
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan13requirements": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan12Features": {
|
||||
"vulkanMemoryModel": true,
|
||||
"vulkanMemoryModelDeviceScope": true,
|
||||
"bufferDeviceAddress": true
|
||||
},
|
||||
"VkPhysicalDeviceVulkan13Features": {
|
||||
"robustImageAccess": true,
|
||||
"shaderTerminateInvocation": true,
|
||||
"shaderZeroInitializeWorkgroupMemory": true,
|
||||
"synchronization2": true,
|
||||
"shaderIntegerDotProduct": true,
|
||||
"maintenance4": true,
|
||||
"pipelineCreationCacheControl": true,
|
||||
"subgroupSizeControl": true,
|
||||
"computeFullSubgroups": true,
|
||||
"shaderDemoteToHelperInvocation": true,
|
||||
"inlineUniformBlock": true,
|
||||
"dynamicRendering": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceVulkan13Properties": {
|
||||
"maxBufferSize": 1073741824,
|
||||
"maxInlineUniformBlockSize": 256,
|
||||
"maxPerStageDescriptorInlineUniformBlocks": 4,
|
||||
"maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks": 4,
|
||||
"maxDescriptorSetInlineUniformBlocks": 4,
|
||||
"maxDescriptorSetUpdateAfterBindInlineUniformBlocks": 4,
|
||||
"maxInlineUniformTotalSize": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan13requirements_1_2": {
|
||||
"extensions": {
|
||||
"VK_EXT_image_robustness": 1,
|
||||
"VK_KHR_shader_non_semantic_info": 1,
|
||||
"VK_KHR_shader_terminate_invocation": 1,
|
||||
"VK_KHR_format_feature_flags2": 1,
|
||||
"VK_KHR_zero_initialize_workgroup_memory": 1,
|
||||
"VK_KHR_synchronization2": 1,
|
||||
"VK_KHR_shader_integer_dot_product": 1,
|
||||
"VK_KHR_maintenance4": 1,
|
||||
"VK_EXT_4444_formats": 1,
|
||||
"VK_EXT_extended_dynamic_state": 1,
|
||||
"VK_EXT_extended_dynamic_state2": 1,
|
||||
"VK_EXT_pipeline_creation_cache_control": 1,
|
||||
"VK_EXT_subgroup_size_control": 1,
|
||||
"VK_EXT_shader_demote_to_helper_invocation": 1,
|
||||
"VK_EXT_inline_uniform_block": 1,
|
||||
"VK_EXT_pipeline_creation_feedback": 1,
|
||||
"VK_EXT_texel_buffer_alignment": 1,
|
||||
"VK_EXT_ycbcr_2plane_444_formats": 1,
|
||||
"VK_EXT_texture_compression_astc_hdr": 1,
|
||||
"VK_EXT_tooling_info": 1,
|
||||
"VK_EXT_private_data": 1,
|
||||
"VK_KHR_dynamic_rendering": 1
|
||||
},
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan12Features": {
|
||||
"vulkanMemoryModel": true,
|
||||
"vulkanMemoryModelDeviceScope": true,
|
||||
"vulkanMemoryModelAvailabilityVisibilityChains": true,
|
||||
"bufferDeviceAddress": true
|
||||
},
|
||||
"VkPhysicalDeviceImageRobustnessFeaturesEXT": {
|
||||
"robustImageAccess": true
|
||||
},
|
||||
"VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR": {
|
||||
"shaderTerminateInvocation": true
|
||||
},
|
||||
"VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR": {
|
||||
"shaderZeroInitializeWorkgroupMemory": true
|
||||
},
|
||||
"VkPhysicalDeviceSynchronization2FeaturesKHR": {
|
||||
"synchronization2": true
|
||||
},
|
||||
"VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR": {
|
||||
"shaderIntegerDotProduct": true
|
||||
},
|
||||
"VkPhysicalDeviceMaintenance4FeaturesKHR": {
|
||||
"maintenance4": true
|
||||
},
|
||||
"VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT": {
|
||||
"pipelineCreationCacheControl": true
|
||||
},
|
||||
"VkPhysicalDeviceSubgroupSizeControlFeaturesEXT": {
|
||||
"subgroupSizeControl": true,
|
||||
"computeFullSubgroups": true
|
||||
},
|
||||
"VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT": {
|
||||
"shaderDemoteToHelperInvocation": true
|
||||
},
|
||||
"VkPhysicalDeviceInlineUniformBlockFeaturesEXT": {
|
||||
"inlineUniformBlock": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceMaintenance4PropertiesKHR": {
|
||||
"maxBufferSize": 1073741824
|
||||
},
|
||||
"VkPhysicalDeviceInlineUniformBlockPropertiesEXT": {
|
||||
"maxInlineUniformBlockSize": 256,
|
||||
"maxPerStageDescriptorInlineUniformBlocks": 4,
|
||||
"maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks": 4,
|
||||
"maxDescriptorSetInlineUniformBlocks": 4,
|
||||
"maxDescriptorSetUpdateAfterBindInlineUniformBlocks": 4
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan13requirements_roadmap2022": {
|
||||
"extensions": {
|
||||
"VK_KHR_global_priority": 1
|
||||
},
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan13Features": {
|
||||
"descriptorBindingInlineUniformBlockUpdateAfterBind": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan13requirements_roadmap2022_1_2": {
|
||||
"extensions": {
|
||||
"VK_EXT_global_priority": 1,
|
||||
"VK_EXT_inline_uniform_block": 1
|
||||
},
|
||||
"features": {
|
||||
"VkPhysicalDeviceInlineUniformBlockFeaturesEXT": {
|
||||
"descriptorBindingInlineUniformBlockUpdateAfterBind": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"VP_KHR_roadmap_2022": {
|
||||
"version": 1,
|
||||
"api-version": "1.3.204",
|
||||
"label": "Khronos Vulkan Roadmap 2022 profile",
|
||||
"description": "This roadmap profile is intended to be supported by newer devices shipping in 2022 across mainstream smartphone, tablet, laptops, console and desktop devices.",
|
||||
"contributors": {
|
||||
"Tobias Hector": {
|
||||
"company": "AMD",
|
||||
"email": "tobias.hector@amd.com",
|
||||
"contact": true
|
||||
},
|
||||
"Christophe Riccio": {
|
||||
"company": "LunarG",
|
||||
"email": "christophe@lunarg.com",
|
||||
"contact": true
|
||||
}
|
||||
},
|
||||
"history": [
|
||||
{
|
||||
"revision": 7,
|
||||
"date": "2022-11-16",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Fix wideLines and largePoints that are optionals"
|
||||
},
|
||||
{
|
||||
"revision": 6,
|
||||
"date": "2022-11-02",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Fix roadmap 2022 maxInlineUniformTotalSize limit, 256 instead of 4"
|
||||
},
|
||||
{
|
||||
"revision": 5,
|
||||
"date": "2022-05-02",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Add missing dynamicRendering that is a Vulkan 1.3 requirement"
|
||||
},
|
||||
{
|
||||
"revision": 4,
|
||||
"date": "2022-03-08",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Refactor requirements per Vulkan API version"
|
||||
},
|
||||
{
|
||||
"revision": 3,
|
||||
"date": "2022-03-08",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Fix Vulkan 1.3.204 API version requirement"
|
||||
},
|
||||
{
|
||||
"revision": 2,
|
||||
"date": "2022-01-03",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Rebase against Vulkan 1.3.203 revision"
|
||||
},
|
||||
{
|
||||
"revision": 1,
|
||||
"date": "2021-12-08",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Initial revision"
|
||||
}
|
||||
],
|
||||
"capabilities": [
|
||||
"vulkan10requirements",
|
||||
"vulkan10requirements_roadmap2022",
|
||||
"vulkan11requirements",
|
||||
"vulkan11requirements_roadmap2022",
|
||||
"vulkan12requirements",
|
||||
"vulkan12requirements_roadmap2022",
|
||||
"vulkan13requirements",
|
||||
"vulkan13requirements_roadmap2022"
|
||||
],
|
||||
"optionals": [
|
||||
"vulkan10optionals_roadmap2022"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
1573
registry/reg.py
1573
registry/reg.py
File diff suppressed because it is too large
Load diff
|
|
@ -1,454 +0,0 @@
|
|||
#!/usr/bin/python3 -i
|
||||
#
|
||||
# Copyright 2013-2023 The Khronos Group Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Base class for working-group-specific style conventions,
|
||||
# used in generation.
|
||||
|
||||
from enum import Enum
|
||||
import abc
|
||||
import re
|
||||
|
||||
# Type categories that respond "False" to isStructAlwaysValid
|
||||
# basetype is home to typedefs like ..Bool32
|
||||
CATEGORIES_REQUIRING_VALIDATION = set(('handle',
|
||||
'enum',
|
||||
'bitmask',
|
||||
'basetype',
|
||||
None))
|
||||
|
||||
# These are basic C types pulled in via openxr_platform_defines.h
|
||||
TYPES_KNOWN_ALWAYS_VALID = set(('char',
|
||||
'float',
|
||||
'int8_t', 'uint8_t',
|
||||
'int16_t', 'uint16_t',
|
||||
'int32_t', 'uint32_t',
|
||||
'int64_t', 'uint64_t',
|
||||
'size_t',
|
||||
'intptr_t', 'uintptr_t',
|
||||
'int',
|
||||
))
|
||||
|
||||
# Split an extension name into vendor ID and name portions
|
||||
EXT_NAME_DECOMPOSE_RE = re.compile(r'[A-Z]+_(?P<vendor>[A-Z]+)_(?P<name>[\w_]+)')
|
||||
|
||||
# Match an API version name.
|
||||
# This could be refined further for specific APIs.
|
||||
API_VERSION_NAME_RE = re.compile(r'[A-Z]+_VERSION_[0-9]')
|
||||
|
||||
|
||||
class ProseListFormats(Enum):
|
||||
"""A connective, possibly with a quantifier."""
|
||||
AND = 0
|
||||
EACH_AND = 1
|
||||
OR = 2
|
||||
ANY_OR = 3
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, s):
|
||||
if s == 'or':
|
||||
return cls.OR
|
||||
if s == 'and':
|
||||
return cls.AND
|
||||
raise RuntimeError("Unrecognized string connective: " + s)
|
||||
|
||||
@property
|
||||
def connective(self):
|
||||
if self in (ProseListFormats.OR, ProseListFormats.ANY_OR):
|
||||
return 'or'
|
||||
return 'and'
|
||||
|
||||
def quantifier(self, n):
|
||||
"""Return the desired quantifier for a list of a given length."""
|
||||
if self == ProseListFormats.ANY_OR:
|
||||
if n > 1:
|
||||
return 'any of '
|
||||
elif self == ProseListFormats.EACH_AND:
|
||||
if n > 2:
|
||||
return 'each of '
|
||||
if n == 2:
|
||||
return 'both of '
|
||||
return ''
|
||||
|
||||
|
||||
class ConventionsBase(abc.ABC):
|
||||
"""WG-specific conventions."""
|
||||
|
||||
def __init__(self):
|
||||
self._command_prefix = None
|
||||
self._type_prefix = None
|
||||
|
||||
def formatExtension(self, name):
|
||||
"""Mark up an extension name as a link the spec."""
|
||||
return '`<<{}>>`'.format(name)
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def null(self):
|
||||
"""Preferred spelling of NULL."""
|
||||
raise NotImplementedError
|
||||
|
||||
def makeProseList(self, elements, fmt=ProseListFormats.AND, with_verb=False, *args, **kwargs):
|
||||
"""Make a (comma-separated) list for use in prose.
|
||||
|
||||
Adds a connective (by default, 'and')
|
||||
before the last element if there are more than 1.
|
||||
|
||||
Adds the right one of "is" or "are" to the end if with_verb is true.
|
||||
|
||||
Optionally adds a quantifier (like 'any') before a list of 2 or more,
|
||||
if specified by fmt.
|
||||
|
||||
Override with a different method or different call to
|
||||
_implMakeProseList if you want to add a comma for two elements,
|
||||
or not use a serial comma.
|
||||
"""
|
||||
return self._implMakeProseList(elements, fmt, with_verb, *args, **kwargs)
|
||||
|
||||
@property
|
||||
def struct_macro(self):
|
||||
"""Get the appropriate format macro for a structure.
|
||||
|
||||
May override.
|
||||
"""
|
||||
return 'slink:'
|
||||
|
||||
@property
|
||||
def external_macro(self):
|
||||
"""Get the appropriate format macro for an external type like uint32_t.
|
||||
|
||||
May override.
|
||||
"""
|
||||
return 'code:'
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def structtype_member_name(self):
|
||||
"""Return name of the structure type member.
|
||||
|
||||
Must implement.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def nextpointer_member_name(self):
|
||||
"""Return name of the structure pointer chain member.
|
||||
|
||||
Must implement.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def xml_api_name(self):
|
||||
"""Return the name used in the default API XML registry for the default API"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@abc.abstractmethod
|
||||
def generate_structure_type_from_name(self, structname):
|
||||
"""Generate a structure type name, like XR_TYPE_CREATE_INSTANCE_INFO.
|
||||
|
||||
Must implement.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def makeStructName(self, name):
|
||||
"""Prepend the appropriate format macro for a structure to a structure type name.
|
||||
|
||||
Uses struct_macro, so just override that if you want to change behavior.
|
||||
"""
|
||||
return self.struct_macro + name
|
||||
|
||||
def makeExternalTypeName(self, name):
|
||||
"""Prepend the appropriate format macro for an external type like uint32_t to a type name.
|
||||
|
||||
Uses external_macro, so just override that if you want to change behavior.
|
||||
"""
|
||||
return self.external_macro + name
|
||||
|
||||
def _implMakeProseList(self, elements, fmt, with_verb, comma_for_two_elts=False, serial_comma=True):
|
||||
"""Internal-use implementation to make a (comma-separated) list for use in prose.
|
||||
|
||||
Adds a connective (by default, 'and')
|
||||
before the last element if there are more than 1,
|
||||
and only includes commas if there are more than 2
|
||||
(if comma_for_two_elts is False).
|
||||
|
||||
Adds the right one of "is" or "are" to the end if with_verb is true.
|
||||
|
||||
Optionally adds a quantifier (like 'any') before a list of 2 or more,
|
||||
if specified by fmt.
|
||||
|
||||
Do not edit these defaults, override self.makeProseList().
|
||||
"""
|
||||
assert(serial_comma) # did not implement what we did not need
|
||||
if isinstance(fmt, str):
|
||||
fmt = ProseListFormats.from_string(fmt)
|
||||
|
||||
my_elts = list(elements)
|
||||
if len(my_elts) > 1:
|
||||
my_elts[-1] = '{} {}'.format(fmt.connective, my_elts[-1])
|
||||
|
||||
if not comma_for_two_elts and len(my_elts) <= 2:
|
||||
prose = ' '.join(my_elts)
|
||||
else:
|
||||
prose = ', '.join(my_elts)
|
||||
|
||||
quantifier = fmt.quantifier(len(my_elts))
|
||||
|
||||
parts = [quantifier, prose]
|
||||
|
||||
if with_verb:
|
||||
if len(my_elts) > 1:
|
||||
parts.append(' are')
|
||||
else:
|
||||
parts.append(' is')
|
||||
return ''.join(parts)
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def file_suffix(self):
|
||||
"""Return suffix of generated Asciidoctor files"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
def api_name(self, spectype=None):
|
||||
"""Return API or specification name for citations in ref pages.
|
||||
|
||||
spectype is the spec this refpage is for.
|
||||
'api' (the default value) is the main API Specification.
|
||||
If an unrecognized spectype is given, returns None.
|
||||
|
||||
Must implement."""
|
||||
raise NotImplementedError
|
||||
|
||||
def should_insert_may_alias_macro(self, genOpts):
|
||||
"""Return true if we should insert a "may alias" macro in this file.
|
||||
|
||||
Only used by OpenXR right now."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def command_prefix(self):
|
||||
"""Return the expected prefix of commands/functions.
|
||||
|
||||
Implemented in terms of api_prefix."""
|
||||
if not self._command_prefix:
|
||||
self._command_prefix = self.api_prefix[:].replace('_', '').lower()
|
||||
return self._command_prefix
|
||||
|
||||
@property
|
||||
def type_prefix(self):
|
||||
"""Return the expected prefix of type names.
|
||||
|
||||
Implemented in terms of command_prefix (and in turn, api_prefix)."""
|
||||
if not self._type_prefix:
|
||||
self._type_prefix = ''.join(
|
||||
(self.command_prefix[0:1].upper(), self.command_prefix[1:]))
|
||||
return self._type_prefix
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def api_prefix(self):
|
||||
"""Return API token prefix.
|
||||
|
||||
Typically two uppercase letters followed by an underscore.
|
||||
|
||||
Must implement."""
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def api_version_prefix(self):
|
||||
"""Return API core version token prefix.
|
||||
|
||||
Implemented in terms of api_prefix.
|
||||
|
||||
May override."""
|
||||
return self.api_prefix + 'VERSION_'
|
||||
|
||||
@property
|
||||
def KHR_prefix(self):
|
||||
"""Return extension name prefix for KHR extensions.
|
||||
|
||||
Implemented in terms of api_prefix.
|
||||
|
||||
May override."""
|
||||
return self.api_prefix + 'KHR_'
|
||||
|
||||
@property
|
||||
def EXT_prefix(self):
|
||||
"""Return extension name prefix for EXT extensions.
|
||||
|
||||
Implemented in terms of api_prefix.
|
||||
|
||||
May override."""
|
||||
return self.api_prefix + 'EXT_'
|
||||
|
||||
def writeFeature(self, featureExtraProtect, filename):
|
||||
"""Return True if OutputGenerator.endFeature should write this feature.
|
||||
|
||||
Defaults to always True.
|
||||
Used in COutputGenerator.
|
||||
|
||||
May override."""
|
||||
return True
|
||||
|
||||
def requires_error_validation(self, return_type):
|
||||
"""Return True if the return_type element is an API result code
|
||||
requiring error validation.
|
||||
|
||||
Defaults to always False.
|
||||
|
||||
May override."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def required_errors(self):
|
||||
"""Return a list of required error codes for validation.
|
||||
|
||||
Defaults to an empty list.
|
||||
|
||||
May override."""
|
||||
return []
|
||||
|
||||
def is_voidpointer_alias(self, tag, text, tail):
|
||||
"""Return True if the declaration components (tag,text,tail) of an
|
||||
element represents a void * type.
|
||||
|
||||
Defaults to a reasonable implementation.
|
||||
|
||||
May override."""
|
||||
return tag == 'type' and text == 'void' and tail.startswith('*')
|
||||
|
||||
def make_voidpointer_alias(self, tail):
|
||||
"""Reformat a void * declaration to include the API alias macro.
|
||||
|
||||
Defaults to a no-op.
|
||||
|
||||
Must override if you actually want to use this feature in your project."""
|
||||
return tail
|
||||
|
||||
def category_requires_validation(self, category):
|
||||
"""Return True if the given type 'category' always requires validation.
|
||||
|
||||
Defaults to a reasonable implementation.
|
||||
|
||||
May override."""
|
||||
return category in CATEGORIES_REQUIRING_VALIDATION
|
||||
|
||||
def type_always_valid(self, typename):
|
||||
"""Return True if the given type name is always valid (never requires validation).
|
||||
|
||||
This is for things like integers.
|
||||
|
||||
Defaults to a reasonable implementation.
|
||||
|
||||
May override."""
|
||||
return typename in TYPES_KNOWN_ALWAYS_VALID
|
||||
|
||||
@property
|
||||
def should_skip_checking_codes(self):
|
||||
"""Return True if more than the basic validation of return codes should
|
||||
be skipped for a command."""
|
||||
|
||||
return False
|
||||
|
||||
@property
|
||||
def generate_index_terms(self):
|
||||
"""Return True if asiidoctor index terms should be generated as part
|
||||
of an API interface from the docgenerator."""
|
||||
|
||||
return False
|
||||
|
||||
@property
|
||||
def generate_enum_table(self):
|
||||
"""Return True if asciidoctor tables describing enumerants in a
|
||||
group should be generated as part of group generation."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def generate_max_enum_in_docs(self):
|
||||
"""Return True if MAX_ENUM tokens should be generated in
|
||||
documentation includes."""
|
||||
return False
|
||||
|
||||
@abc.abstractmethod
|
||||
def extension_file_path(self, name):
|
||||
"""Return file path to an extension appendix relative to a directory
|
||||
containing all such appendices.
|
||||
- name - extension name
|
||||
|
||||
Must implement."""
|
||||
raise NotImplementedError
|
||||
|
||||
def extension_include_string(self, name):
|
||||
"""Return format string for include:: line for an extension appendix
|
||||
file.
|
||||
- name - extension name"""
|
||||
|
||||
return 'include::{{appendices}}/{}[]'.format(
|
||||
self.extension_file_path(name))
|
||||
|
||||
@property
|
||||
def provisional_extension_warning(self):
|
||||
"""Return True if a warning should be included in extension
|
||||
appendices for provisional extensions."""
|
||||
return True
|
||||
|
||||
@property
|
||||
def generated_include_path(self):
|
||||
"""Return path relative to the generated reference pages, to the
|
||||
generated API include files."""
|
||||
|
||||
return '{generated}'
|
||||
|
||||
@property
|
||||
def include_extension_appendix_in_refpage(self):
|
||||
"""Return True if generating extension refpages by embedding
|
||||
extension appendix content (default), False otherwise
|
||||
(OpenXR)."""
|
||||
|
||||
return True
|
||||
|
||||
def valid_flag_bit(self, bitpos):
|
||||
"""Return True if bitpos is an allowed numeric bit position for
|
||||
an API flag.
|
||||
|
||||
Behavior depends on the data type used for flags (which may be 32
|
||||
or 64 bits), and may depend on assumptions about compiler
|
||||
handling of sign bits in enumerated types, as well."""
|
||||
return True
|
||||
|
||||
@property
|
||||
def duplicate_aliased_structs(self):
|
||||
"""
|
||||
Should aliased structs have the original struct definition listed in the
|
||||
generated docs snippet?
|
||||
"""
|
||||
return False
|
||||
|
||||
@property
|
||||
def protectProtoComment(self):
|
||||
"""Return True if generated #endif should have a comment matching
|
||||
the protection symbol used in the opening #ifdef/#ifndef."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def extra_refpage_headers(self):
|
||||
"""Return any extra headers (preceding the title) for generated
|
||||
reference pages."""
|
||||
return ''
|
||||
|
||||
@property
|
||||
def extra_refpage_body(self):
|
||||
"""Return any extra text (following the title) for generated
|
||||
reference pages."""
|
||||
return ''
|
||||
|
||||
def is_api_version_name(self, name):
|
||||
"""Return True if name is an API version name."""
|
||||
|
||||
return API_VERSION_NAME_RE.match(name) is not None
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
"""Utility functions not closely tied to other spec_tools types."""
|
||||
# Copyright (c) 2018-2019 Collabora, Ltd.
|
||||
# Copyright 2013-2023 The Khronos Group Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
|
||||
def getElemName(elem, default=None):
|
||||
"""Get the name associated with an element, either a name child or name attribute."""
|
||||
name_elem = elem.find('name')
|
||||
if name_elem is not None:
|
||||
return name_elem.text
|
||||
# Fallback if there is no child.
|
||||
return elem.get('name', default)
|
||||
|
||||
|
||||
def getElemType(elem, default=None):
|
||||
"""Get the type associated with an element, either a type child or type attribute."""
|
||||
type_elem = elem.find('type')
|
||||
if type_elem is not None:
|
||||
return type_elem.text
|
||||
# Fallback if there is no child.
|
||||
return elem.get('type', default)
|
||||
|
||||
|
||||
def findFirstWithPredicate(collection, pred):
|
||||
"""Return the first element that satisfies the predicate, or None if none exist.
|
||||
|
||||
NOTE: Some places where this is used might be better served by changing to a dictionary.
|
||||
"""
|
||||
for elt in collection:
|
||||
if pred(elt):
|
||||
return elt
|
||||
return None
|
||||
|
||||
|
||||
def findNamedElem(elems, name):
|
||||
"""Traverse a collection of elements with 'name' nodes or attributes, looking for and returning one with the right name.
|
||||
|
||||
NOTE: Many places where this is used might be better served by changing to a dictionary.
|
||||
"""
|
||||
return findFirstWithPredicate(elems, lambda elem: getElemName(elem) == name)
|
||||
|
||||
|
||||
def findTypedElem(elems, typename):
|
||||
"""Traverse a collection of elements with 'type' nodes or attributes, looking for and returning one with the right typename.
|
||||
|
||||
NOTE: Many places where this is used might be better served by changing to a dictionary.
|
||||
"""
|
||||
return findFirstWithPredicate(elems, lambda elem: getElemType(elem) == typename)
|
||||
|
||||
|
||||
def findNamedObject(collection, name):
|
||||
"""Traverse a collection of elements with 'name' attributes, looking for and returning one with the right name.
|
||||
|
||||
NOTE: Many places where this is used might be better served by changing to a dictionary.
|
||||
"""
|
||||
return findFirstWithPredicate(collection, lambda elt: elt.name == name)
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright 2023 The Khronos Group Inc.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import argparse
|
||||
import xml.etree.ElementTree as etree
|
||||
from reg import stripNonmatchingAPIs
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(prog='stripAPI',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
Filters out elements with non-matching explicit 'api' attributes from API XML.
|
||||
To remove Vulkan SC-only elements from the combined API XML:
|
||||
python3 scripts/stripAPI.py -input xml/vk.xml -output vulkan-only.xml -keepAPI vulkan
|
||||
To remove Vulkan-only elements:
|
||||
python3 scripts/stripAPI.py -input xml/vk.xml -output vulkansc-only.xml -keepAPI vulkansc
|
||||
If you are parsing the XML yourself but using the xml.etree package, the
|
||||
equivalent runtime code is:
|
||||
import reg
|
||||
reg.stripNonmatchingAPIs(tree.getroot(), keepAPI, actuallyDelete=True)
|
||||
where 'tree' is an ElementTree created from the XML file using
|
||||
etree.parse(filename)''')
|
||||
|
||||
parser.add_argument('-input', action='store',
|
||||
required=True,
|
||||
help='Specify input registry XML')
|
||||
parser.add_argument('-output', action='store',
|
||||
required=True,
|
||||
help='Specify output registry XML')
|
||||
parser.add_argument('-keepAPI', action='store',
|
||||
default=None,
|
||||
help='Specify API name whose \'api\' tags are kept')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
tree = etree.parse(args.input)
|
||||
if args.keepAPI is not None:
|
||||
stripNonmatchingAPIs(tree.getroot(), args.keepAPI, actuallyDelete = True)
|
||||
tree.write(args.output)
|
||||
|
||||
84730
registry/validusage.json
84730
registry/validusage.json
File diff suppressed because one or more lines are too long
1194
registry/video.xml
1194
registry/video.xml
File diff suppressed because it is too large
Load diff
24180
registry/vk.xml
24180
registry/vk.xml
File diff suppressed because it is too large
Load diff
|
|
@ -1,279 +0,0 @@
|
|||
#!/usr/bin/python3 -i
|
||||
#
|
||||
# Copyright 2013-2023 The Khronos Group Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Working-group-specific style conventions,
|
||||
# used in generation.
|
||||
|
||||
import re
|
||||
import os
|
||||
|
||||
from spec_tools.conventions import ConventionsBase
|
||||
|
||||
# Modified from default implementation - see category_requires_validation() below
|
||||
CATEGORIES_REQUIRING_VALIDATION = set(('handle', 'enum', 'bitmask'))
|
||||
|
||||
# Tokenize into "words" for structure types, approximately per spec "Implicit Valid Usage" section 2.7.2
|
||||
# This first set is for things we recognize explicitly as words,
|
||||
# as exceptions to the general regex.
|
||||
# Ideally these would be listed in the spec as exceptions, as OpenXR does.
|
||||
SPECIAL_WORDS = set((
|
||||
'16Bit', # VkPhysicalDevice16BitStorageFeatures
|
||||
'2D', # VkPhysicalDeviceImage2DViewOf3DFeaturesEXT
|
||||
'3D', # VkPhysicalDeviceImage2DViewOf3DFeaturesEXT
|
||||
'8Bit', # VkPhysicalDevice8BitStorageFeaturesKHR
|
||||
'AABB', # VkGeometryAABBNV
|
||||
'ASTC', # VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT
|
||||
'D3D12', # VkD3D12FenceSubmitInfoKHR
|
||||
'Float16', # VkPhysicalDeviceShaderFloat16Int8FeaturesKHR
|
||||
'ImagePipe', # VkImagePipeSurfaceCreateInfoFUCHSIA
|
||||
'Int64', # VkPhysicalDeviceShaderAtomicInt64FeaturesKHR
|
||||
'Int8', # VkPhysicalDeviceShaderFloat16Int8FeaturesKHR
|
||||
'MacOS', # VkMacOSSurfaceCreateInfoMVK
|
||||
'RGBA10X6', # VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT
|
||||
'Uint8', # VkPhysicalDeviceIndexTypeUint8FeaturesEXT
|
||||
'Win32', # VkWin32SurfaceCreateInfoKHR
|
||||
))
|
||||
# A regex to match any of the SPECIAL_WORDS
|
||||
EXCEPTION_PATTERN = r'(?P<exception>{})'.format(
|
||||
'|'.join('(%s)' % re.escape(w) for w in SPECIAL_WORDS))
|
||||
MAIN_RE = re.compile(
|
||||
# the negative lookahead is to prevent the all-caps pattern from being too greedy.
|
||||
r'({}|([0-9]+)|([A-Z][a-z]+)|([A-Z][A-Z]*(?![a-z])))'.format(EXCEPTION_PATTERN))
|
||||
|
||||
|
||||
class VulkanConventions(ConventionsBase):
|
||||
@property
|
||||
def null(self):
|
||||
"""Preferred spelling of NULL."""
|
||||
return '`NULL`'
|
||||
|
||||
def formatExtension(self, name):
|
||||
"""Mark up an extension name as a link the spec."""
|
||||
return '`apiext:{}`'.format(name)
|
||||
|
||||
@property
|
||||
def struct_macro(self):
|
||||
"""Get the appropriate format macro for a structure.
|
||||
|
||||
Primarily affects generated valid usage statements.
|
||||
"""
|
||||
|
||||
return 'slink:'
|
||||
|
||||
@property
|
||||
def constFlagBits(self):
|
||||
"""Returns True if static const flag bits should be generated, False if an enumerated type should be generated."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def structtype_member_name(self):
|
||||
"""Return name of the structure type member"""
|
||||
return 'sType'
|
||||
|
||||
@property
|
||||
def nextpointer_member_name(self):
|
||||
"""Return name of the structure pointer chain member"""
|
||||
return 'pNext'
|
||||
|
||||
@property
|
||||
def valid_pointer_prefix(self):
|
||||
"""Return prefix to pointers which must themselves be valid"""
|
||||
return 'valid'
|
||||
|
||||
def is_structure_type_member(self, paramtype, paramname):
|
||||
"""Determine if member type and name match the structure type member."""
|
||||
return paramtype == 'VkStructureType' and paramname == self.structtype_member_name
|
||||
|
||||
def is_nextpointer_member(self, paramtype, paramname):
|
||||
"""Determine if member type and name match the next pointer chain member."""
|
||||
return paramtype == 'void' and paramname == self.nextpointer_member_name
|
||||
|
||||
def generate_structure_type_from_name(self, structname):
|
||||
"""Generate a structure type name, like VK_STRUCTURE_TYPE_CREATE_INSTANCE_INFO"""
|
||||
|
||||
structure_type_parts = []
|
||||
# Tokenize into "words"
|
||||
for elem in MAIN_RE.findall(structname):
|
||||
word = elem[0]
|
||||
if word == 'Vk':
|
||||
structure_type_parts.append('VK_STRUCTURE_TYPE')
|
||||
else:
|
||||
structure_type_parts.append(word.upper())
|
||||
name = '_'.join(structure_type_parts)
|
||||
|
||||
# The simple-minded rules need modification for some structure names
|
||||
subpats = [
|
||||
[ r'_H_(26[45])_', r'_H\1_' ],
|
||||
[ r'_VULKAN_([0-9])([0-9])_', r'_VULKAN_\1_\2_' ],
|
||||
[ r'_DIRECT_FB_', r'_DIRECTFB_' ],
|
||||
[ r'_VULKAN_SC_10', r'_VULKAN_SC_1_0' ],
|
||||
|
||||
]
|
||||
|
||||
for subpat in subpats:
|
||||
name = re.sub(subpat[0], subpat[1], name)
|
||||
return name
|
||||
|
||||
@property
|
||||
def warning_comment(self):
|
||||
"""Return warning comment to be placed in header of generated Asciidoctor files"""
|
||||
return '// WARNING: DO NOT MODIFY! This file is automatically generated from the vk.xml registry'
|
||||
|
||||
@property
|
||||
def file_suffix(self):
|
||||
"""Return suffix of generated Asciidoctor files"""
|
||||
return '.adoc'
|
||||
|
||||
def api_name(self, spectype='api'):
|
||||
"""Return API or specification name for citations in ref pages.ref
|
||||
pages should link to for
|
||||
|
||||
spectype is the spec this refpage is for: 'api' is the Vulkan API
|
||||
Specification. Defaults to 'api'. If an unrecognized spectype is
|
||||
given, returns None.
|
||||
"""
|
||||
if spectype == 'api' or spectype is None:
|
||||
return 'Vulkan'
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def api_prefix(self):
|
||||
"""Return API token prefix"""
|
||||
return 'VK_'
|
||||
|
||||
@property
|
||||
def write_contacts(self):
|
||||
"""Return whether contact list should be written to extension appendices"""
|
||||
return True
|
||||
|
||||
@property
|
||||
def write_refpage_include(self):
|
||||
"""Return whether refpage include should be written to extension appendices"""
|
||||
return True
|
||||
|
||||
@property
|
||||
def member_used_for_unique_vuid(self):
|
||||
"""Return the member name used in the VUID-...-...-unique ID."""
|
||||
return self.structtype_member_name
|
||||
|
||||
def is_externsync_command(self, protoname):
|
||||
"""Returns True if the protoname element is an API command requiring
|
||||
external synchronization
|
||||
"""
|
||||
return protoname is not None and 'vkCmd' in protoname
|
||||
|
||||
def is_api_name(self, name):
|
||||
"""Returns True if name is in the reserved API namespace.
|
||||
For Vulkan, these are names with a case-insensitive 'vk' prefix, or
|
||||
a 'PFN_vk' function pointer type prefix.
|
||||
"""
|
||||
return name[0:2].lower() == 'vk' or name[0:6] == 'PFN_vk'
|
||||
|
||||
def specURL(self, spectype='api'):
|
||||
"""Return public registry URL which ref pages should link to for the
|
||||
current all-extensions HTML specification, so xrefs in the
|
||||
asciidoc source that are not to ref pages can link into it
|
||||
instead. N.b. this may need to change on a per-refpage basis if
|
||||
there are multiple documents involved.
|
||||
"""
|
||||
return 'https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html'
|
||||
|
||||
@property
|
||||
def xml_api_name(self):
|
||||
"""Return the name used in the default API XML registry for the default API"""
|
||||
return 'vulkan'
|
||||
|
||||
@property
|
||||
def registry_path(self):
|
||||
"""Return relpath to the default API XML registry in this project."""
|
||||
return 'xml/vk.xml'
|
||||
|
||||
@property
|
||||
def specification_path(self):
|
||||
"""Return relpath to the Asciidoctor specification sources in this project."""
|
||||
return '{generated}/meta'
|
||||
|
||||
@property
|
||||
def special_use_section_anchor(self):
|
||||
"""Return asciidoctor anchor name in the API Specification of the
|
||||
section describing extension special uses in detail."""
|
||||
return 'extendingvulkan-compatibility-specialuse'
|
||||
|
||||
@property
|
||||
def extension_index_prefixes(self):
|
||||
"""Return a list of extension prefixes used to group extension refpages."""
|
||||
return ['VK_KHR', 'VK_EXT', 'VK']
|
||||
|
||||
@property
|
||||
def unified_flag_refpages(self):
|
||||
"""Return True if Flags/FlagBits refpages are unified, False if
|
||||
they are separate.
|
||||
"""
|
||||
return False
|
||||
|
||||
@property
|
||||
def spec_reflow_path(self):
|
||||
"""Return the path to the spec source folder to reflow"""
|
||||
return os.getcwd()
|
||||
|
||||
@property
|
||||
def spec_no_reflow_dirs(self):
|
||||
"""Return a set of directories not to automatically descend into
|
||||
when reflowing spec text
|
||||
"""
|
||||
return ('scripts', 'style')
|
||||
|
||||
@property
|
||||
def zero(self):
|
||||
return '`0`'
|
||||
|
||||
def category_requires_validation(self, category):
|
||||
"""Return True if the given type 'category' always requires validation.
|
||||
|
||||
Overridden because Vulkan does not require "valid" text for basetype
|
||||
in the spec right now."""
|
||||
return category in CATEGORIES_REQUIRING_VALIDATION
|
||||
|
||||
@property
|
||||
def should_skip_checking_codes(self):
|
||||
"""Return True if more than the basic validation of return codes should
|
||||
be skipped for a command.
|
||||
|
||||
Vulkan mostly relies on the validation layers rather than API
|
||||
builtin error checking, so these checks are not appropriate.
|
||||
|
||||
For example, passing in a VkFormat parameter will not potentially
|
||||
generate a VK_ERROR_FORMAT_NOT_SUPPORTED code."""
|
||||
|
||||
return True
|
||||
|
||||
def extension_file_path(self, name):
|
||||
"""Return file path to an extension appendix relative to a directory
|
||||
containing all such appendices.
|
||||
- name - extension name"""
|
||||
|
||||
return f'{name}{self.file_suffix}'
|
||||
|
||||
def valid_flag_bit(self, bitpos):
|
||||
"""Return True if bitpos is an allowed numeric bit position for
|
||||
an API flag bit.
|
||||
|
||||
Vulkan uses 32 bit Vk*Flags types, and assumes C compilers may
|
||||
cause Vk*FlagBits values with bit 31 set to result in a 64 bit
|
||||
enumerated type, so disallows such flags."""
|
||||
return bitpos >= 0 and bitpos < 31
|
||||
|
||||
@property
|
||||
def extra_refpage_headers(self):
|
||||
"""Return any extra text to add to refpage headers."""
|
||||
return 'include::{config}/attribs.adoc[]'
|
||||
|
||||
@property
|
||||
def extra_refpage_body(self):
|
||||
"""Return any extra text (following the title) for generated
|
||||
reference pages."""
|
||||
return 'include::{generated}/specattribs.adoc[]'
|
||||
2
stub.c
Normal file
2
stub.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// This file exists for the Zig build sytem to work.
|
||||
// In order to "build" this library, there need to be some objects to link.
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
# ~~~
|
||||
# Copyright (c) 2022-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.
|
||||
# ~~~
|
||||
|
||||
# Test the non-API headers provided by this repo
|
||||
# NOTE: For us testing just means that these header files compile
|
||||
# with reasonable warnings.
|
||||
|
||||
message(STATUS "${PROJECT_NAME} = ${PROJECT_VERSION}")
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
|
||||
if(${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
|
||||
add_compile_options(
|
||||
-Wpedantic
|
||||
-Wall
|
||||
-Wextra
|
||||
-Werror
|
||||
)
|
||||
endif()
|
||||
|
||||
# vk_icd.h
|
||||
add_executable(vk_icd vk_icd.c)
|
||||
target_link_libraries(vk_icd PRIVATE Vulkan::Headers)
|
||||
|
||||
# vk_layer.h
|
||||
add_library(vk_layer MODULE vk_layer.c)
|
||||
target_link_libraries(vk_layer PRIVATE Vulkan::Headers)
|
||||
|
||||
if (NOT TARGET Vulkan-Headers)
|
||||
message(FATAL_ERROR "Backcompat for Vulkan-Headers target broken!")
|
||||
endif()
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.14.2)
|
||||
|
||||
project(TEST_VULKAN_HEADERS_FIND_PACKAGE_SUPPORT LANGUAGES C)
|
||||
|
||||
find_package(VulkanHeaders REQUIRED CONFIG)
|
||||
|
||||
if (NOT TARGET Vulkan::Headers)
|
||||
message(FATAL_ERROR "Vulkan::Headers target not defined")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED VULKAN_HEADERS_REGISTRY_DIRECTORY)
|
||||
message(FATAL_ERROR "VULKAN_HEADERS_REGISTRY_DIRECTORY not defined!")
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS "${VULKAN_HEADERS_REGISTRY_DIRECTORY}/vk.xml")
|
||||
message(FATAL_ERROR "VULKAN_HEADERS_REGISTRY_DIRECTORY not valid!")
|
||||
endif()
|
||||
message(STATUS "VULKAN_HEADERS_REGISTRY_DIRECTORY = ${VULKAN_HEADERS_REGISTRY_DIRECTORY}")
|
||||
|
||||
if (NOT DEFINED VulkanHeaders_VERSION)
|
||||
message(FATAL_ERROR "VulkanHeaders_VERSION not defined!")
|
||||
endif()
|
||||
message(STATUS "VulkanHeaders_VERSION = ${VulkanHeaders_VERSION}")
|
||||
|
||||
add_library(foobar STATIC)
|
||||
|
||||
target_link_libraries(foobar PRIVATE Vulkan::Headers)
|
||||
|
||||
target_sources(foobar PRIVATE
|
||||
../vk_icd.c
|
||||
../vk_layer.c
|
||||
)
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#include "vulkan/vk_icd.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#include "vulkan/vk_layer.h"
|
||||
|
||||
int foobar()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue