diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..18df7d33b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+CMakeCache.txt
+CMakeLists.txt.user
+*CMakeFiles/
+*Makefile
+*cmake_install.cmake
+*libopenxr_monado.so
+CMakeDoxyfile.in
+CMakeDoxygenDefaults.cmake
+doc/Doxyfile
+doc/html/
+doc/latex/
+openxr_monado-dev.json
+openxr_monado.json
+src/xrt/compositor/shaders/*.vert.h
+src/xrt/compositor/shaders/*.frag.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 000000000..7ce1d41a3
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,58 @@
+# Copyright 2018-2019, Collabora, Ltd.
+# SPDX-License-Identifier: BSL-1.0
+
+cmake_minimum_required(VERSION 3.10.0)
+project(XRT VERSION 0.1.0)
+
+# CMake 3.11 introduced CMP0072 - Prefer GLVND
+if(POLICY CMP0072)
+ cmake_policy(SET CMP0072 NEW)
+endif()
+
+option(BUILD_TESTS "Build compile and runtime tests" ON)
+option(OPENXR_USE_LOADER "Application uses loader" ON)
+
+
+###
+# Dependencies
+###
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+include(CMakeDependentOption)
+include(SPIR-V)
+
+find_package(Eigen3 REQUIRED)
+find_package(Vulkan REQUIRED)
+find_package(OpenGL)
+find_package(HIDAPI)
+
+# Push into a FindOpenHMD.cmake file.
+find_package(PkgConfig)
+pkg_check_modules(OPENHMD openhmd)
+
+
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ find_package(X11)
+ find_package(Wayland)
+ pkg_check_modules(XCB xcb xcb-randr)
+endif()
+
+cmake_dependent_option(BUILD_WITH_OPENHMD "Enable OpenHMD driver" ON "OPENHMD_FOUND" OFF)
+cmake_dependent_option(BUILD_WITH_WAYLAND "Enable Wayland support" ON "WAYLAND_FOUND" OFF)
+cmake_dependent_option(BUILD_WITH_XLIB "Enable xlib support" ON "X11_FOUND" OFF)
+cmake_dependent_option(BUILD_WITH_OPENGL "Enable OpenGL Graphics API support?" ON "OPENGL_FOUND" OFF)
+
+
+###
+# Flags
+###
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic -Wall -Wextra -Wno-unused-parameter")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter")
+
+
+###
+# Decend into madness.
+###
+
+add_subdirectory(src)
+add_subdirectory(doc)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..d9e2c543a
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,82 @@
+# Contribution Guidelines
+
+There are plenty of valid reasons why someone might not be able
+to follow all of the guidelines in this section, and that's OK,
+especially for new contributors or those new to open source entirely.
+Just let us know and we'll figure out a way to help you get involved successfully.
+
+> Important note: Unlike the guidelines here, the Code of Conduct,
+> available at ,
+> is **not** optional,
+> and applies in its entirety to anyone involved in the project,
+> for the safety and comfort of all.
+> See the README for associated contacts.
+
+## Pull/Merge Requests
+
+- If you're considering starting work on a large change that you'd like to contribute,
+ it is recommended to first open an issue before you start,
+ to begin a discussion and help smooth the acceptance of your contribution.
+
+- If you are able, please make sure to run clang-format
+ (ideally version 7 or newer) before each commit,
+ so that you only commit things that are cleanly styled.
+ Consistent, machine-performed formatting improves readability and makes it easier for others to contribute.
+ It also makes it easier to review changes.
+ If you can't run clang-format, just mention this fact in your request and we'd be happy to help,
+ either in a single "Clean up formatting." commit on top of your work,
+ or by "re-writing history" (with your permission and leaving your commit authorship intact),
+ revising each commit to apply formatting.
+
+- Avoid including whitespace or other formatting changes to unrelated code when committing.
+ The `git add -p` command or the "stage selected lines/hunks" feature of various Git GUIs are
+ great ways of making sure you only stage and commit the changes that you mean to.
+ Relatedly, `git commit -v` (if you commit from the command line) can be a great help
+ in making sure you aren't committing things you don't mean to,
+ by showing the diff you're committing in your commit message editor.
+ (This can even be set system-wide in `git config --global commit.verbose true`
+ if you find it as life-changing as many others have - thanks
+ [@emilyst](https://twitter.com/emilyst/status/1039205453010362368).)
+
+- If you can, before submitting a pull/merge request, try building with clang-tidy enabled,
+ and if you touched any code that has or should have documentation,
+ build and check the documentation and see if it looks OK.
+
+- We work to keep the code free of warnings -
+ please help by making sure your changes build cleanly (and pass all tests).
+ When on compilers that take warning flags like gcc and clang do,
+ the build system automatically turns on quite a few of them.
+ If a warning stumps you, just mention it in the request so we can figure it out together.
+
+### Issues
+
+Constructive issues are a valued form of contribution.
+Please try to include any relevant information
+(whether it is a request for improvement or a bug report).
+We'll try to respond promptly,
+but there is no guarantee or warranty (as noted in the license),
+absent any externally-arranged consulting or support contract.
+
+Since this is a runtime/implementation of an API used by other applications,
+bug reports should include:
+
+- details about your build environment
+ - architecture
+ - compiler
+ - compiler version
+ - build flags (defines, configuration/feature flags)
+- associated application code
+ - for logic/execution errors, a new (failing) test case is ideal,
+ otherwise a description of expected and actual behavior
+ - if you cannot disclose your code, or even if you can,
+ an "artificial", minimally-sized example can be very valuable.
+
+---
+
+## Copyright and License for this CONTRIBUTING.md file
+
+For this file only:
+
+> Copyright 2018-2019 Collabora, Ltd.
+>
+> SPDX-License-Identifier: CC-BY-4.0
diff --git a/README.md b/README.md
index 1ba75d55c..6bac7aabd 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,208 @@
# Monado - XR Runtime (XRT)
+
+Monado is an open source XR runtime delivering immersive experiences such as VR
+and AR on on mobile, PC/desktop, and any other device
+(because gosh darn people
+come up with a lot of weird hardware).
+Monado aims to be a complete and conforming implementation
+of the OpenXR API made by Khronos.
+The project currently is being developed for GNU/Linux
+and aims to support other operating systems in the near future.
+"Monado" has no specific meaning and is just a name.
+
+## Monado source tree
+
+* `src/xrt/include` - headers that define the internal interfaces of Monado.
+* `src/xrt/compositor` - code for doing distortion and driving the display hardware of a device.
+* `src/xrt/auxiliary` - utilies and other larger components.
+* `src/xrt/drivers` - hardware drivers.
+* `src/xrt/state_trackers/oxr` - OpenXR API implementation.
+* `src/xrt/targets` - glue code and build logic to produce final binaries.
+* `src/external` - a small collection of external code and headers.
+
+## Getting Started
+
+Dependencies include:
+
+* [CMake][] 3.10 or newer
+* [OpenHMD](https://openhmd.net) (found using pkg-config)
+* Vulkan headers
+* Eigen3
+* glslang
+
+Optional (but recommended) dependencies:
+
+* OpenGL headers for OpenGL graphics support
+* libxcb and xcb-xrandr development packages
+
+Truly optional dependencies:
+
+* Doxygen
+* Wayland development packages
+* Xlib development pages
+* libhidapi (for the HDK driver)
+
+Tested distributions that are fully compatible,
+on Intel and AMD graphics:
+
+* Ubuntu 18.10 (18.04 does not work)
+* Debian 10 `buster`
+ (currently the "testing" release -
+ current stable Stretch does not have new enough packages)
+
+These distributions include recent-enough versions of all the
+software to use direct mode,
+without using any external, third-party, or backported
+package sources.
+
+See also [Status of DRM leases](https://haagch.frickel.club/#!drmlease.md)
+for more details on specific packages, versions, and commits.
+
+Build process is similar to other CMake builds,
+so something like the following will build it.
+
+Go into the source directory, create a build directory,
+and change into it.
+
+ mkdir build
+ cd build
+
+Then, invoke [CMake to generate a project][cmake-generate].
+Feel free to change the build type or generator ("Ninja" is fast and parallel) as you see fit.
+
+ cmake .. -DCMAKE_BUILD_TYPE=Debug -G "Unix Makefiles"
+
+If you plan to install the runtime,
+append something like `-DCMAKE_INSTALL_PREFIX=~/.local`
+to specify the root of the install directory.
+(The default install prefix is `/usr/local`.)
+
+To build, [the generic CMake build commands][cmake-build] below will work on all systems,
+though you can manually invoke your build tool (`make`, `ninja`, etc.) if you prefer.
+The first command builds the runtime and docs,
+and the second, which is optional, installs the runtime under `${CMAKE_INSTALL_PREFIX}`.
+
+ cmake --build .
+ cmake --build . --target install
+
+Alternately, if using Make, the following will build the runtime and docs, then install.
+Replace `make` with `ninja` if you used the Ninja generator.
+
+ make
+ make install
+
+Documentation can be browsed by opening `docs/html/index.html` in the build directory in a web browser.
+
+## Getting started using OpenXR with Monado
+
+This implements the [OpenXR](https://khronos.org/openxr) API,
+so to do anything with it, you'll need an application
+that uses OpenXR, along with the OpenXR loader.
+The OpenXR loader is a glue library that connects OpenXR applications to OpenXR runtimes such as Monado
+It determines which runtime to use by reading config file default `/usr/local/share/openxr/0/active_runtime.json`
+and processes environment variables such as `XR_RUNTIME_JSON=/usr/share/openxr/0/openxr_monado.json`.
+It can also insert OpenXR API Layers without the application or the runtime having to do it.
+
+You can use the `hello_xr` sample provided with the
+OpenXR loader and API layers.
+
+The OpenXR loader can be pointed to a runtime json file in a nonstandard location with the environment variable `XR_RUNTIME_JSON`. Example:
+
+ XR_RUNTIME_JSON=~/monado/build/xrt_oopenxr_monado_dev.json ./openxr-example
+
+For this reason this runtime creates two manifest files within the build directory:
+
+* `openxr_monado.json` uses a relative path to the runtime, and is intended to be installed with `make install`.
+* `openxr_monado_dev.json` uses an absolute path to the runtime in its build directory,
+ and is intended to be used for development without installing the runtime.
+
+If Monado has been installed through a distribution package
+and provides the "active runtime" file /usr/local/share/openxr/0/active_runtime.json,
+then the loader will automatically use Monado when starting any OpenXR application.
+
+If Monado has been compiled in a custom directory like ~/monado/build,
+the OpenXR loader can be pointed to the runtime when starting an OpenXR application
+by setting the environment variable XR_RUNTIME_JSON to the `openxr_monado_dev.json` manifest
+that was generated by the build: see above.
+
+Note that the loader can always find and load the runtime
+if the path to the runtime library given in the json manifest is an absolute path,
+but if a relative path like `libopenxr_monado.so.0` is given,
+then `LD_LIBRARY_PATH` must include the directory that contains `libopenxr_monado.so.0`.
+The absolute path in `openxr_monado_dev.json` takes care of this for you.
+
+## Direct mode
+
+Our direct mode code requires a connected HMD to have the `non-desktop` xrandr
+property set to 1.
+Only the most common HMDs have the needed quirks added to the linux kernel.
+Just keep on reading for more info on how to work around that.
+
+If you know that your HMD lacks the quirk you can run this command **before** or
+after connecting the HMD and it will have it. Where `HDMI-A-0` is the xrandr
+output name where you plug the HMD in.
+
+```bash
+xrandr --output HDMI-A-0 --prop --set non-desktop 1
+```
+
+You can verify that it stuck with the command.
+
+```bash
+xrand --prop
+```
+
+## Coding style and formatting
+
+[clang-format][] is used,
+and a `.clang-format` config file is present in the repo
+to allow your editor to use them.
+
+To manually apply clang-format to every non-external source file in the tree,
+run this command in the source dir with a `sh`-compatible shell
+(Git for Windows git-bash should be OK):
+
+ scripts/format-project.sh
+
+You can optionally put something like `CLANG_FORMAT=clang-format-7` before that command
+if your clang-format binary isn't named `clang-format`.
+Note that you'll typically prefer to use something like `git clang-format`
+to just re-format your changes, in case version differences in tools result in overall format changes.
+
+[clang-format]: https://releases.llvm.org/7.0.0/tools/clang/docs/ClangFormat.html
+[cmake-build]: https://cmake.org/cmake/help/v3.12/manual/cmake.1.html#build-tool-mode
+[cmake-generate]: https://cmake.org/cmake/help/v3.12/manual/cmake.1.html
+[CMake]: https://cmake.org
+
+## Contributing, Code of Conduct
+
+See `CONTRIBUTING.md` for details of contribution guidelines.
+
+Please note that this project is released with a Contributor Code of Conduct.
+By participating in this project you agree to abide by its terms.
+
+We follow the standard freedesktop.org code of conduct,
+available at ,
+which is based on the [Contributor Covenant](https://www.contributor-covenant.org).
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting:
+
+* First-line project contacts:
+ * Jakob Bornecrantz
+ * Ryan Pavlik
+* freedesktop.org contacts: see most recent list at
+
+## Copyright and License for this README.md file
+
+For this file only:
+
+> Copyright 2018-2019 Collabora, Ltd.
+> Code of Conduct section: excerpt adapted from the [Contributor Covenant][https://www.contributor-covenant.org], version 1.4.1,
+> available at ,
+> and from the freedesktop.org-specific version of that code,
+> available at
+>
+>
+> SPDX-License-Identifier: CC-BY-4.0
diff --git a/cmake/FindHIDAPI.cmake b/cmake/FindHIDAPI.cmake
new file mode 100644
index 000000000..646f90026
--- /dev/null
+++ b/cmake/FindHIDAPI.cmake
@@ -0,0 +1,46 @@
+# - try to find HIDAPI library
+# from http://www.signal11.us/oss/hidapi/
+#
+# Cache Variables: (probably not for direct use in your scripts)
+# HIDAPI_INCLUDE_DIR
+# HIDAPI_LIBRARY
+#
+# Non-cache variables you might use in your CMakeLists.txt:
+# HIDAPI_FOUND
+# HIDAPI_INCLUDE_DIRS
+# HIDAPI_LIBRARIES
+#
+# Requires these CMake modules:
+# FindPackageHandleStandardArgs (known included with CMake >=2.6.2)
+#
+# Original Author:
+# 2009-2010 Ryan Pavlik
+# http://academic.cleardefinition.com
+# Iowa State University HCI Graduate Program/VRAC
+#
+# Copyright Iowa State University 2009-2010.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+find_library(HIDAPI_LIBRARY
+ NAMES hidapi hidapi-libusb)
+
+find_path(HIDAPI_INCLUDE_DIR
+ NAMES hidapi.h
+ PATH_SUFFIXES
+ hidapi)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(HIDAPI
+ DEFAULT_MSG
+ HIDAPI_LIBRARY
+ HIDAPI_INCLUDE_DIR)
+
+if(HIDAPI_FOUND)
+ set(HIDAPI_LIBRARIES "${HIDAPI_LIBRARY}")
+
+ set(HIDAPI_INCLUDE_DIRS "${HIDAPI_INCLUDE_DIR}")
+endif()
+
+mark_as_advanced(HIDAPI_INCLUDE_DIR HIDAPI_LIBRARY)
diff --git a/cmake/FindWayland.cmake b/cmake/FindWayland.cmake
new file mode 100644
index 000000000..f93218b87
--- /dev/null
+++ b/cmake/FindWayland.cmake
@@ -0,0 +1,66 @@
+# Try to find Wayland on a Unix system
+#
+# This will define:
+#
+# WAYLAND_FOUND - True if Wayland is found
+# WAYLAND_LIBRARIES - Link these to use Wayland
+# WAYLAND_INCLUDE_DIR - Include directory for Wayland
+# WAYLAND_DEFINITIONS - Compiler flags for using Wayland
+#
+# In addition the following more fine grained variables will be defined:
+#
+# WAYLAND_CLIENT_FOUND WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES
+# WAYLAND_SERVER_FOUND WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES
+# WAYLAND_EGL_FOUND WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES
+#
+# Copyright (c) 2013 Martin Gräßlin
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+IF (NOT WIN32)
+ IF (WAYLAND_INCLUDE_DIR AND WAYLAND_LIBRARIES)
+ # In the cache already
+ SET(WAYLAND_FIND_QUIETLY TRUE)
+ ENDIF ()
+
+ # Use pkg-config to get the directories and then use these values
+ # in the FIND_PATH() and FIND_LIBRARY() calls
+ FIND_PACKAGE(PkgConfig)
+ PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor)
+
+ SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS})
+
+ FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
+ FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
+ FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
+ FIND_PATH(WAYLAND_CURSOR_INCLUDE_DIR NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
+
+ FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
+ FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
+ FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
+ FIND_LIBRARY(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
+
+ set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR} ${WAYLAND_CURSOR_INCLUDE_DIR})
+
+ set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES})
+
+ list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR)
+
+ include(FindPackageHandleStandardArgs)
+
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT DEFAULT_MSG WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER DEFAULT_MSG WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL DEFAULT_MSG WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CURSOR DEFAULT_MSG WAYLAND_CURSOR_LIBRARIES WAYLAND_CURSOR_INCLUDE_DIR)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIR)
+
+ MARK_AS_ADVANCED(
+ WAYLAND_INCLUDE_DIR WAYLAND_LIBRARIES
+ WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES
+ WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES
+ WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES
+ WAYLAND_CURSOR_INCLUDE_DIR WAYLAND_CURSOR_LIBRARIES
+ )
+
+ENDIF ()
diff --git a/cmake/SPIR-V.cmake b/cmake/SPIR-V.cmake
new file mode 100644
index 000000000..13218725e
--- /dev/null
+++ b/cmake/SPIR-V.cmake
@@ -0,0 +1,38 @@
+# Copyright 2019, Collabora, Ltd.
+# SPDX-License-Identifier: BSL-1.0
+
+find_program(GLSLANGVALIDATOR_COMMAND
+ glslangValidator)
+if(NOT GLSLANGVALIDATOR_COMMAND)
+ message(FATAL_ERROR "glslangValidator required - source maintained at https://github.com/KhronosGroup/glslang")
+endif()
+
+#
+# Generate a SPIR-V header file, with the given var name. Returns the header.
+#
+function(spirv_shader ret GLSL VAR)
+ set(HEADER "${CMAKE_CURRENT_BINARY_DIR}/${GLSL}.h")
+ set(GLSL "${CMAKE_CURRENT_SOURCE_DIR}/${GLSL}")
+
+ add_custom_command(
+ OUTPUT ${HEADER}
+ COMMAND ${GLSLANGVALIDATOR_COMMAND} -V ${GLSL} --vn ${VAR} -o ${HEADER}
+ DEPENDS ${GLSL})
+
+
+ set(${ret} "${HEADER}" PARENT_SCOPE)
+endfunction(spirv_shader)
+
+#
+# Generate SPIR-V header files from the arguments. Returns a list of headers.
+#
+function(spirv_shaders ret)
+
+ foreach(GLSL ${ARGN})
+ string(MAKE_C_IDENTIFIER ${GLSL} IDENTIFIER)
+ spirv_shader(HEADER ${GLSL} ${IDENTIFIER})
+ list(APPEND HEADERS ${HEADER})
+ endforeach()
+
+ set(${ret} "${HEADERS}" PARENT_SCOPE)
+endfunction(spirv_shaders)
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
new file mode 100644
index 000000000..d0e87f707
--- /dev/null
+++ b/doc/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Copyright 2018-2019, Collabora, Ltd.
+# SPDX-License-Identifier: BSL-1.0
+
+# check if Doxygen is installed
+find_package(Doxygen)
+cmake_dependent_option(BUILD_DOC "Build documentation" ON "DOXYGEN_FOUND" OFF)
+cmake_dependent_option(BUILD_DOC_WARN_UNDOCUMENTED "Warn on undocumented entities when building documentation" OFF "DOXYGEN_FOUND" OFF)
+cmake_dependent_option(BUILD_DOC_EXTRACT_ALL "Extract all entities for documentation, not just documented ones (conflicts with BUILD_DOCS_WARN_UNDOCUMENTED)" ON "DOXYGEN_FOUND; NOT BUILD_DOCS_WARN_UNDOCUMENTED" OFF)
+
+if(BUILD_DOC)
+ if(BUILD_DOC_WARN_UNDOCUMENTED)
+ set(DOXYGEN_WARN_UNDOCUMENTED YES)
+ else()
+ set(DOXYGEN_WARN_UNDOCUMENTED NO)
+ endif()
+ if(BUILD_DOC_EXTRACT_ALL)
+ set(DOXYGEN_EXTRACT_ALL YES)
+ else()
+ set(DOXYGEN_EXTRACT_ALL NO)
+ endif()
+
+ # set input and output files
+ set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
+ set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
+
+ # request to configure the file
+ configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
+
+ # note the option ALL which allows to build the docs together with the application
+ add_custom_target(doc_doxygen ALL
+ COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Generating API documentation with Doxygen"
+ VERBATIM
+ )
+endif()
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
new file mode 100644
index 000000000..dae08661d
--- /dev/null
+++ b/doc/Doxyfile.in
@@ -0,0 +1,2541 @@
+## Changed properties goes on the top.
+
+QUIET = YES
+PROJECT_NAME = "OpenXR Runtime"
+OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/
+INPUT = \
+ @CMAKE_CURRENT_SOURCE_DIR@/../README.md \
+ @CMAKE_CURRENT_SOURCE_DIR@/../src/xrt \
+ @CMAKE_CURRENT_SOURCE_DIR@
+
+USE_MDFILE_AS_MAINPAGE = @CMAKE_CURRENT_SOURCE_DIR@/../README.md
+
+RECURSIVE = YES
+EXCLUDE = @CMAKE_CURRENT_SOURCE_DIR@/../src/xrt/generated
+STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@/src/xrt \
+ @CMAKE_CURRENT_SOURCE_DIR@
+
+
+PREDEFINED = VK_USE_PLATFORM_XCB_KHR \
+ VK_USE_PLATFORM_WAYLAND_KHR \
+ VK_USE_PLATFORM_XLIB_XRANDR_EXT \
+ XR_EXT_debug_utils \
+ XR_USE_GRAPHICS_API_OPENGL \
+ XR_USE_GRAPHICS_API_VULKAN \
+ XR_USE_PLATFORM_XLIB \
+ XR_USE_TIMESPEC \
+ XRT_DOXYGEN
+
+ALIASES += TODO=todo
+ALIASES += ep{1}="\1 . \xrefitem entrypoints \"OpenXR Entry Point\" \"OpenXR Entry Points\" \1"
+ALIASES += obj{1}="\xrefitem objects \"OpenXR Object\" \"OpenXR Objects\" \1"
+
+SHOW_GROUPED_MEMB_INC = YES
+STRIP_CODE_COMMENTS = NO
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+ALWAYS_DETAILED_SEC = YES
+
+
+WARN_IF_UNDOCUMENTED = @DOXYGEN_WARN_UNDOCUMENTED@
+EXTRACT_ALL = @DOXYGEN_EXTRACT_ALL@
+
+# Doxyfile 1.8.13
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+#PROJECT_NAME = "My Project"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+#OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+#ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+#STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH = src/xrt/auxiliary \
+ src/xrt/compositor \
+ src/xrt/drivers \
+ src/xrt/include \
+ src/xrt/state_trackers \
+ src/xrt/targets
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is yogur file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+#ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = YES
+
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 0.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS = 0
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+#SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+#FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if ... \endif and \cond
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+#QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+# WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+#INPUT =
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.idl \
+ *.ddl \
+ *.odl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.cs \
+ *.d \
+ *.php \
+ *.php4 \
+ *.php5 \
+ *.phtml \
+ *.inc \
+ *.m \
+ *.markdown \
+ *.md \
+ *.mm \
+ *.dox \
+ *.py \
+ *.pyw \
+ *.f90 \
+ *.f95 \
+ *.f03 \
+ *.f08 \
+ *.f \
+ *.for \
+ *.tcl \
+ *.vhd \
+ *.vhdl \
+ *.ucf \
+ *.qsf
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+# RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+# EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+#
+#
+# where is the value of the INPUT_FILTER tag, and is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+# USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+#STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+#REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+#REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse-libclang=ON option for CMake.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use + S
+# (what the is depends on the OS and browser, but it is typically
+# , /, or both). Inside the search box use the to jump into the search results window, the results can be navigated
+# using the . Press to select an item or to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing +. Also here use the
+# to select a filter and or to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE =
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+#PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: YES.
+
+HAVE_DOT = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
+# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
+# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH =
+
+# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
+# configuration file for plantuml.
+
+PLANTUML_CFG_FILE =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP = YES
diff --git a/doc/roadmap.md b/doc/roadmap.md
new file mode 100644
index 000000000..009b451de
--- /dev/null
+++ b/doc/roadmap.md
@@ -0,0 +1,35 @@
+# Roadmap
+
+## Short term
+
+ * **aux/util**: Add mutex and threading wrappers.
+ * **aux/math**: Add kalman filter math black box.
+ * **aux/log**: Add a common logging framework that can be used to pipe messages
+ up into **st/oxr** from things like drivers and the compositor.
+ * **aux/log**: Make it possible to batch up longer messages into a single call,
+ useful for printing the entire mode list in a single go.
+ * **cmake**: Make a proper FindXCB.cmake file.
+ * **comp**: Do timing based of the display refresh-rate and display time.
+ * **comp**: Extend to support rotated views/displays. Should we just rotate the
+ display for the 3Glasses or make it a per-view thing?
+ * **comp**: See-through support for Vive headset.
+ * **st/oxr**: Locking, maybe we just have a single lock for the session.
+ We will need to figure out how to do wait properly.
+ * **st/oxr**: Make wait frame actually wait for the display time.
+ * **st/oxr**: Improve space functions.
+ * **st/oxr**: Add path functions.
+ * **st/oxr**: Add just enough of the action functions to not return errors.
+
+## Long term
+
+ * **aux/beacon**: Complete and integrate Lighthouse tracking code.
+ * **comp**: Moving the compositor into it's own process.
+ * **comp**: Support quads layers.
+ * **comp**: Support other extensions layers.
+ * **doc**: Group Related code.
+ * **doc**: Lots of documentation for runtime.
+ * **drivers**: Port rest of OpenHMD drivers to our runtime.
+ * **st/oxr**: Complete action functions.
+ * **progs**: Settings and management daemon.
+ * **progs**: Systray status indicator for user to interact with daemon.
+ * **progs**: Room-scale setup program.
diff --git a/scripts/format-project.sh b/scripts/format-project.sh
new file mode 100755
index 000000000..878197a15
--- /dev/null
+++ b/scripts/format-project.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Copyright 2018-2019, Collabora, Ltd.
+# Copyright 2016, Sensics, Inc.
+# SPDX-License-Identifier: Apache-2.0
+
+if [ ! "$CLANG_FORMAT" ]; then
+ for exe in clang-format-8 clang-format-7 clang-format-6.0 clang-format; do
+ if which $exe >/dev/null 2>&1; then
+ CLANG_FORMAT=$exe
+ break
+ fi
+ done
+fi
+if [ ! "$CLANG_FORMAT" ]; then
+ echo "Can't find clang-format - please set CLANG_FORMAT to a command or path" >&2
+ exit 1
+fi
+
+runClangFormatOnDir() {
+ find "$1" \( -name "*.c" -o -name "*.cpp" -o -name "*.h" \)| \
+ grep -v "\.boilerplate" | \
+ xargs ${CLANG_FORMAT} -style=file -i
+}
+
+(
+cd $(dirname $0)/../src/xrt
+runClangFormatOnDir .
+)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 000000000..7524309df
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,4 @@
+# Copyright 2019, Collabora, Ltd.
+# SPDX-License-Identifier: BSL-1.0
+
+add_subdirectory(xrt)
diff --git a/src/external/glad/gl.c b/src/external/glad/gl.c
new file mode 100644
index 000000000..bb8437b4b
--- /dev/null
+++ b/src/external/glad/gl.c
@@ -0,0 +1,1654 @@
+#include
+#include
+#include
+#include
+
+#ifndef GLAD_IMPL_UTIL_C_
+#define GLAD_IMPL_UTIL_C_
+
+#ifdef _MSC_VER
+#define GLAD_IMPL_UTIL_SSCANF sscanf_s
+#else
+#define GLAD_IMPL_UTIL_SSCANF sscanf
+#endif
+
+#endif /* GLAD_IMPL_UTIL_C_ */
+
+
+int GLAD_GL_VERSION_1_0 = 0;
+int GLAD_GL_VERSION_1_1 = 0;
+int GLAD_GL_VERSION_1_2 = 0;
+int GLAD_GL_VERSION_1_3 = 0;
+int GLAD_GL_VERSION_1_4 = 0;
+int GLAD_GL_VERSION_1_5 = 0;
+int GLAD_GL_VERSION_2_0 = 0;
+int GLAD_GL_VERSION_2_1 = 0;
+int GLAD_GL_VERSION_3_0 = 0;
+int GLAD_GL_VERSION_3_1 = 0;
+int GLAD_GL_VERSION_3_2 = 0;
+int GLAD_GL_VERSION_3_3 = 0;
+int GLAD_GL_VERSION_4_0 = 0;
+int GLAD_GL_VERSION_4_1 = 0;
+int GLAD_GL_VERSION_4_2 = 0;
+int GLAD_GL_VERSION_4_3 = 0;
+int GLAD_GL_VERSION_4_4 = 0;
+int GLAD_GL_VERSION_4_5 = 0;
+int GLAD_GL_EXT_memory_object = 0;
+int GLAD_GL_EXT_memory_object_fd = 0;
+
+
+
+PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram = NULL;
+PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL;
+PFNGLATTACHSHADERPROC glad_glAttachShader = NULL;
+PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL;
+PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL;
+PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed = NULL;
+PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL;
+PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL;
+PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL;
+PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL;
+PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL;
+PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase = NULL;
+PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange = NULL;
+PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL;
+PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL;
+PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL;
+PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture = NULL;
+PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures = NULL;
+PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline = NULL;
+PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL;
+PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL;
+PFNGLBINDSAMPLERSPROC glad_glBindSamplers = NULL;
+PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL;
+PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit = NULL;
+PFNGLBINDTEXTURESPROC glad_glBindTextures = NULL;
+PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL;
+PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL;
+PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer = NULL;
+PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers = NULL;
+PFNGLBLENDCOLORPROC glad_glBlendColor = NULL;
+PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL;
+PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL;
+PFNGLBLENDEQUATIONSEPARATEIPROC glad_glBlendEquationSeparatei = NULL;
+PFNGLBLENDEQUATIONIPROC glad_glBlendEquationi = NULL;
+PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL;
+PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL;
+PFNGLBLENDFUNCSEPARATEIPROC glad_glBlendFuncSeparatei = NULL;
+PFNGLBLENDFUNCIPROC glad_glBlendFunci = NULL;
+PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL;
+PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer = NULL;
+PFNGLBUFFERDATAPROC glad_glBufferData = NULL;
+PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL;
+PFNGLBUFFERSTORAGEMEMEXTPROC glad_glBufferStorageMemEXT = NULL;
+PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL;
+PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL;
+PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus = NULL;
+PFNGLCLAMPCOLORPROC glad_glClampColor = NULL;
+PFNGLCLEARPROC glad_glClear = NULL;
+PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData = NULL;
+PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData = NULL;
+PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL;
+PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL;
+PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL;
+PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL;
+PFNGLCLEARCOLORPROC glad_glClearColor = NULL;
+PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL;
+PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL;
+PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData = NULL;
+PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv = NULL;
+PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL;
+PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage = NULL;
+PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage = NULL;
+PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL;
+PFNGLCLIPCONTROLPROC glad_glClipControl = NULL;
+PFNGLCOLORMASKPROC glad_glColorMask = NULL;
+PFNGLCOLORMASKIPROC glad_glColorMaski = NULL;
+PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL;
+PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL;
+PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL;
+PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D = NULL;
+PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL;
+PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData = NULL;
+PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData = NULL;
+PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL;
+PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL;
+PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL;
+PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL;
+PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D = NULL;
+PFNGLCREATEBUFFERSPROC glad_glCreateBuffers = NULL;
+PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers = NULL;
+PFNGLCREATEMEMORYOBJECTSEXTPROC glad_glCreateMemoryObjectsEXT = NULL;
+PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL;
+PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines = NULL;
+PFNGLCREATEQUERIESPROC glad_glCreateQueries = NULL;
+PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers = NULL;
+PFNGLCREATESAMPLERSPROC glad_glCreateSamplers = NULL;
+PFNGLCREATESHADERPROC glad_glCreateShader = NULL;
+PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv = NULL;
+PFNGLCREATETEXTURESPROC glad_glCreateTextures = NULL;
+PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks = NULL;
+PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays = NULL;
+PFNGLCULLFACEPROC glad_glCullFace = NULL;
+PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback = NULL;
+PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl = NULL;
+PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert = NULL;
+PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL;
+PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL;
+PFNGLDELETEMEMORYOBJECTSEXTPROC glad_glDeleteMemoryObjectsEXT = NULL;
+PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL;
+PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines = NULL;
+PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL;
+PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL;
+PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL;
+PFNGLDELETESHADERPROC glad_glDeleteShader = NULL;
+PFNGLDELETESYNCPROC glad_glDeleteSync = NULL;
+PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL;
+PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL;
+PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL;
+PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL;
+PFNGLDEPTHMASKPROC glad_glDepthMask = NULL;
+PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL;
+PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL;
+PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL;
+PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL;
+PFNGLDETACHSHADERPROC glad_glDetachShader = NULL;
+PFNGLDISABLEPROC glad_glDisable = NULL;
+PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib = NULL;
+PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL;
+PFNGLDISABLEIPROC glad_glDisablei = NULL;
+PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute = NULL;
+PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect = NULL;
+PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL;
+PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL;
+PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL;
+PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance = NULL;
+PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL;
+PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL;
+PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL;
+PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL;
+PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect = NULL;
+PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL;
+PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL;
+PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced = NULL;
+PFNGLENABLEPROC glad_glEnable = NULL;
+PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib = NULL;
+PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL;
+PFNGLENABLEIPROC glad_glEnablei = NULL;
+PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL;
+PFNGLENDQUERYPROC glad_glEndQuery = NULL;
+PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed = NULL;
+PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL;
+PFNGLFENCESYNCPROC glad_glFenceSync = NULL;
+PFNGLFINISHPROC glad_glFinish = NULL;
+PFNGLFLUSHPROC glad_glFlush = NULL;
+PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL;
+PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange = NULL;
+PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri = NULL;
+PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL;
+PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL;
+PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL;
+PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL;
+PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL;
+PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL;
+PFNGLFRONTFACEPROC glad_glFrontFace = NULL;
+PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL;
+PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL;
+PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines = NULL;
+PFNGLGENQUERIESPROC glad_glGenQueries = NULL;
+PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL;
+PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL;
+PFNGLGENTEXTURESPROC glad_glGenTextures = NULL;
+PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL;
+PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL;
+PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL;
+PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap = NULL;
+PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv = NULL;
+PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL;
+PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName = NULL;
+PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName = NULL;
+PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv = NULL;
+PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL;
+PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL;
+PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL;
+PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL;
+PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL;
+PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL;
+PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL;
+PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL;
+PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL;
+PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL;
+PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL;
+PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL;
+PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL;
+PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL;
+PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage = NULL;
+PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage = NULL;
+PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog = NULL;
+PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v = NULL;
+PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL;
+PFNGLGETERRORPROC glad_glGetError = NULL;
+PFNGLGETFLOATI_VPROC glad_glGetFloati_v = NULL;
+PFNGLGETFLOATVPROC glad_glGetFloatv = NULL;
+PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL;
+PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL;
+PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL;
+PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv = NULL;
+PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus = NULL;
+PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL;
+PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL;
+PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL;
+PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL;
+PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v = NULL;
+PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL;
+PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glad_glGetMemoryObjectParameterivEXT = NULL;
+PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv = NULL;
+PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv = NULL;
+PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData = NULL;
+PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv = NULL;
+PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv = NULL;
+PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv = NULL;
+PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel = NULL;
+PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel = NULL;
+PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL;
+PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL;
+PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL;
+PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = NULL;
+PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog = NULL;
+PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv = NULL;
+PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex = NULL;
+PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation = NULL;
+PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex = NULL;
+PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName = NULL;
+PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv = NULL;
+PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv = NULL;
+PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL;
+PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v = NULL;
+PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv = NULL;
+PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v = NULL;
+PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv = NULL;
+PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv = NULL;
+PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL;
+PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL;
+PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL;
+PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL;
+PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL;
+PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL;
+PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL;
+PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL;
+PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL;
+PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL;
+PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL;
+PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL;
+PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL;
+PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL;
+PFNGLGETSTRINGPROC glad_glGetString = NULL;
+PFNGLGETSTRINGIPROC glad_glGetStringi = NULL;
+PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex = NULL;
+PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation = NULL;
+PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL;
+PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL;
+PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL;
+PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL;
+PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL;
+PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL;
+PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL;
+PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL;
+PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage = NULL;
+PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv = NULL;
+PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv = NULL;
+PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv = NULL;
+PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv = NULL;
+PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv = NULL;
+PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv = NULL;
+PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage = NULL;
+PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL;
+PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v = NULL;
+PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v = NULL;
+PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv = NULL;
+PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL;
+PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL;
+PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL;
+PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv = NULL;
+PFNGLGETUNIFORMDVPROC glad_glGetUniformdv = NULL;
+PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL;
+PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL;
+PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL;
+PFNGLGETUNSIGNEDBYTEI_VEXTPROC glad_glGetUnsignedBytei_vEXT = NULL;
+PFNGLGETUNSIGNEDBYTEVEXTPROC glad_glGetUnsignedBytevEXT = NULL;
+PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv = NULL;
+PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv = NULL;
+PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv = NULL;
+PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL;
+PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL;
+PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv = NULL;
+PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL;
+PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL;
+PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL;
+PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL;
+PFNGLGETNCOMPRESSEDTEXIMAGEPROC glad_glGetnCompressedTexImage = NULL;
+PFNGLGETNTEXIMAGEPROC glad_glGetnTexImage = NULL;
+PFNGLGETNUNIFORMDVPROC glad_glGetnUniformdv = NULL;
+PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv = NULL;
+PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv = NULL;
+PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv = NULL;
+PFNGLHINTPROC glad_glHint = NULL;
+PFNGLIMPORTMEMORYFDEXTPROC glad_glImportMemoryFdEXT = NULL;
+PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData = NULL;
+PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData = NULL;
+PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL;
+PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData = NULL;
+PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData = NULL;
+PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL;
+PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage = NULL;
+PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage = NULL;
+PFNGLISBUFFERPROC glad_glIsBuffer = NULL;
+PFNGLISENABLEDPROC glad_glIsEnabled = NULL;
+PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL;
+PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL;
+PFNGLISMEMORYOBJECTEXTPROC glad_glIsMemoryObjectEXT = NULL;
+PFNGLISPROGRAMPROC glad_glIsProgram = NULL;
+PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline = NULL;
+PFNGLISQUERYPROC glad_glIsQuery = NULL;
+PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL;
+PFNGLISSAMPLERPROC glad_glIsSampler = NULL;
+PFNGLISSHADERPROC glad_glIsShader = NULL;
+PFNGLISSYNCPROC glad_glIsSync = NULL;
+PFNGLISTEXTUREPROC glad_glIsTexture = NULL;
+PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL;
+PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL;
+PFNGLLINEWIDTHPROC glad_glLineWidth = NULL;
+PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL;
+PFNGLLOGICOPPROC glad_glLogicOp = NULL;
+PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL;
+PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL;
+PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer = NULL;
+PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange = NULL;
+PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier = NULL;
+PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion = NULL;
+PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glad_glMemoryObjectParameterivEXT = NULL;
+PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading = NULL;
+PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL;
+PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect = NULL;
+PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL;
+PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect = NULL;
+PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData = NULL;
+PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage = NULL;
+PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glad_glNamedBufferStorageMemEXT = NULL;
+PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData = NULL;
+PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer = NULL;
+PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers = NULL;
+PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri = NULL;
+PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer = NULL;
+PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample = NULL;
+PFNGLOBJECTLABELPROC glad_glObjectLabel = NULL;
+PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel = NULL;
+PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv = NULL;
+PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri = NULL;
+PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL;
+PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL;
+PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL;
+PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL;
+PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL;
+PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL;
+PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL;
+PFNGLPOINTSIZEPROC glad_glPointSize = NULL;
+PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL;
+PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL;
+PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup = NULL;
+PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL;
+PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL;
+PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL;
+PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d = NULL;
+PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv = NULL;
+PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f = NULL;
+PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv = NULL;
+PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i = NULL;
+PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv = NULL;
+PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui = NULL;
+PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv = NULL;
+PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d = NULL;
+PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv = NULL;
+PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f = NULL;
+PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv = NULL;
+PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i = NULL;
+PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv = NULL;
+PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui = NULL;
+PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv = NULL;
+PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d = NULL;
+PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv = NULL;
+PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f = NULL;
+PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv = NULL;
+PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i = NULL;
+PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv = NULL;
+PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui = NULL;
+PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv = NULL;
+PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d = NULL;
+PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv = NULL;
+PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f = NULL;
+PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv = NULL;
+PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i = NULL;
+PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv = NULL;
+PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui = NULL;
+PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv = NULL;
+PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL;
+PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup = NULL;
+PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL;
+PFNGLREADBUFFERPROC glad_glReadBuffer = NULL;
+PFNGLREADPIXELSPROC glad_glReadPixels = NULL;
+PFNGLREADNPIXELSPROC glad_glReadnPixels = NULL;
+PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL;
+PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL;
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL;
+PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL;
+PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL;
+PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL;
+PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL;
+PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL;
+PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL;
+PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL;
+PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL;
+PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL;
+PFNGLSCISSORPROC glad_glScissor = NULL;
+PFNGLSCISSORARRAYVPROC glad_glScissorArrayv = NULL;
+PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed = NULL;
+PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv = NULL;
+PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL;
+PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL;
+PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding = NULL;
+PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL;
+PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL;
+PFNGLSTENCILMASKPROC glad_glStencilMask = NULL;
+PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL;
+PFNGLSTENCILOPPROC glad_glStencilOp = NULL;
+PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL;
+PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL;
+PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange = NULL;
+PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL;
+PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL;
+PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL;
+PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL;
+PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL;
+PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL;
+PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL;
+PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL;
+PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL;
+PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL;
+PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL;
+PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D = NULL;
+PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL;
+PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample = NULL;
+PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL;
+PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample = NULL;
+PFNGLTEXSTORAGEMEM1DEXTPROC glad_glTexStorageMem1DEXT = NULL;
+PFNGLTEXSTORAGEMEM2DEXTPROC glad_glTexStorageMem2DEXT = NULL;
+PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTexStorageMem2DMultisampleEXT = NULL;
+PFNGLTEXSTORAGEMEM3DEXTPROC glad_glTexStorageMem3DEXT = NULL;
+PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTexStorageMem3DMultisampleEXT = NULL;
+PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL;
+PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL;
+PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL;
+PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier = NULL;
+PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer = NULL;
+PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange = NULL;
+PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv = NULL;
+PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv = NULL;
+PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf = NULL;
+PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv = NULL;
+PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri = NULL;
+PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv = NULL;
+PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D = NULL;
+PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D = NULL;
+PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample = NULL;
+PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D = NULL;
+PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample = NULL;
+PFNGLTEXTURESTORAGEMEM1DEXTPROC glad_glTextureStorageMem1DEXT = NULL;
+PFNGLTEXTURESTORAGEMEM2DEXTPROC glad_glTextureStorageMem2DEXT = NULL;
+PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTextureStorageMem2DMultisampleEXT = NULL;
+PFNGLTEXTURESTORAGEMEM3DEXTPROC glad_glTextureStorageMem3DEXT = NULL;
+PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTextureStorageMem3DMultisampleEXT = NULL;
+PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D = NULL;
+PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D = NULL;
+PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D = NULL;
+PFNGLTEXTUREVIEWPROC glad_glTextureView = NULL;
+PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase = NULL;
+PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL;
+PFNGLUNIFORM1DPROC glad_glUniform1d = NULL;
+PFNGLUNIFORM1DVPROC glad_glUniform1dv = NULL;
+PFNGLUNIFORM1FPROC glad_glUniform1f = NULL;
+PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL;
+PFNGLUNIFORM1IPROC glad_glUniform1i = NULL;
+PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL;
+PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL;
+PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL;
+PFNGLUNIFORM2DPROC glad_glUniform2d = NULL;
+PFNGLUNIFORM2DVPROC glad_glUniform2dv = NULL;
+PFNGLUNIFORM2FPROC glad_glUniform2f = NULL;
+PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL;
+PFNGLUNIFORM2IPROC glad_glUniform2i = NULL;
+PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL;
+PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL;
+PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL;
+PFNGLUNIFORM3DPROC glad_glUniform3d = NULL;
+PFNGLUNIFORM3DVPROC glad_glUniform3dv = NULL;
+PFNGLUNIFORM3FPROC glad_glUniform3f = NULL;
+PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL;
+PFNGLUNIFORM3IPROC glad_glUniform3i = NULL;
+PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL;
+PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL;
+PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL;
+PFNGLUNIFORM4DPROC glad_glUniform4d = NULL;
+PFNGLUNIFORM4DVPROC glad_glUniform4dv = NULL;
+PFNGLUNIFORM4FPROC glad_glUniform4f = NULL;
+PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL;
+PFNGLUNIFORM4IPROC glad_glUniform4i = NULL;
+PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL;
+PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL;
+PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL;
+PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL;
+PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv = NULL;
+PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL;
+PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv = NULL;
+PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL;
+PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv = NULL;
+PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL;
+PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv = NULL;
+PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL;
+PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv = NULL;
+PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL;
+PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv = NULL;
+PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL;
+PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv = NULL;
+PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL;
+PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv = NULL;
+PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL;
+PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv = NULL;
+PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL;
+PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv = NULL;
+PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL;
+PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer = NULL;
+PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL;
+PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages = NULL;
+PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL;
+PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline = NULL;
+PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding = NULL;
+PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat = NULL;
+PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat = NULL;
+PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat = NULL;
+PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor = NULL;
+PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer = NULL;
+PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer = NULL;
+PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers = NULL;
+PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL;
+PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL;
+PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL;
+PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL;
+PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL;
+PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL;
+PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL;
+PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL;
+PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL;
+PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL;
+PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL;
+PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL;
+PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL;
+PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL;
+PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL;
+PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL;
+PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL;
+PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL;
+PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL;
+PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL;
+PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL;
+PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL;
+PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL;
+PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL;
+PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL;
+PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL;
+PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL;
+PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL;
+PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL;
+PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL;
+PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL;
+PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL;
+PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL;
+PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL;
+PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL;
+PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL;
+PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding = NULL;
+PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL;
+PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat = NULL;
+PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL;
+PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL;
+PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL;
+PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL;
+PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL;
+PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL;
+PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL;
+PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL;
+PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL;
+PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL;
+PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL;
+PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL;
+PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL;
+PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL;
+PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL;
+PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL;
+PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL;
+PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL;
+PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL;
+PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL;
+PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat = NULL;
+PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL;
+PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d = NULL;
+PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv = NULL;
+PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d = NULL;
+PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv = NULL;
+PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d = NULL;
+PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv = NULL;
+PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d = NULL;
+PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv = NULL;
+PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat = NULL;
+PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer = NULL;
+PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL;
+PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL;
+PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL;
+PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL;
+PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL;
+PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL;
+PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL;
+PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL;
+PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL;
+PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor = NULL;
+PFNGLVIEWPORTPROC glad_glViewport = NULL;
+PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL;
+PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL;
+PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL;
+PFNGLWAITSYNCPROC glad_glWaitSync = NULL;
+
+
+static void glad_gl_load_GL_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_1_0) return;
+ glBlendFunc = (PFNGLBLENDFUNCPROC) load("glBlendFunc", userptr);
+ glClear = (PFNGLCLEARPROC) load("glClear", userptr);
+ glClearColor = (PFNGLCLEARCOLORPROC) load("glClearColor", userptr);
+ glClearDepth = (PFNGLCLEARDEPTHPROC) load("glClearDepth", userptr);
+ glClearStencil = (PFNGLCLEARSTENCILPROC) load("glClearStencil", userptr);
+ glColorMask = (PFNGLCOLORMASKPROC) load("glColorMask", userptr);
+ glCullFace = (PFNGLCULLFACEPROC) load("glCullFace", userptr);
+ glDepthFunc = (PFNGLDEPTHFUNCPROC) load("glDepthFunc", userptr);
+ glDepthMask = (PFNGLDEPTHMASKPROC) load("glDepthMask", userptr);
+ glDepthRange = (PFNGLDEPTHRANGEPROC) load("glDepthRange", userptr);
+ glDisable = (PFNGLDISABLEPROC) load("glDisable", userptr);
+ glDrawBuffer = (PFNGLDRAWBUFFERPROC) load("glDrawBuffer", userptr);
+ glEnable = (PFNGLENABLEPROC) load("glEnable", userptr);
+ glFinish = (PFNGLFINISHPROC) load("glFinish", userptr);
+ glFlush = (PFNGLFLUSHPROC) load("glFlush", userptr);
+ glFrontFace = (PFNGLFRONTFACEPROC) load("glFrontFace", userptr);
+ glGetBooleanv = (PFNGLGETBOOLEANVPROC) load("glGetBooleanv", userptr);
+ glGetDoublev = (PFNGLGETDOUBLEVPROC) load("glGetDoublev", userptr);
+ glGetError = (PFNGLGETERRORPROC) load("glGetError", userptr);
+ glGetFloatv = (PFNGLGETFLOATVPROC) load("glGetFloatv", userptr);
+ glGetIntegerv = (PFNGLGETINTEGERVPROC) load("glGetIntegerv", userptr);
+ glGetString = (PFNGLGETSTRINGPROC) load("glGetString", userptr);
+ glGetTexImage = (PFNGLGETTEXIMAGEPROC) load("glGetTexImage", userptr);
+ glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load("glGetTexLevelParameterfv", userptr);
+ glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load("glGetTexLevelParameteriv", userptr);
+ glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load("glGetTexParameterfv", userptr);
+ glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load("glGetTexParameteriv", userptr);
+ glHint = (PFNGLHINTPROC) load("glHint", userptr);
+ glIsEnabled = (PFNGLISENABLEDPROC) load("glIsEnabled", userptr);
+ glLineWidth = (PFNGLLINEWIDTHPROC) load("glLineWidth", userptr);
+ glLogicOp = (PFNGLLOGICOPPROC) load("glLogicOp", userptr);
+ glPixelStoref = (PFNGLPIXELSTOREFPROC) load("glPixelStoref", userptr);
+ glPixelStorei = (PFNGLPIXELSTOREIPROC) load("glPixelStorei", userptr);
+ glPointSize = (PFNGLPOINTSIZEPROC) load("glPointSize", userptr);
+ glPolygonMode = (PFNGLPOLYGONMODEPROC) load("glPolygonMode", userptr);
+ glReadBuffer = (PFNGLREADBUFFERPROC) load("glReadBuffer", userptr);
+ glReadPixels = (PFNGLREADPIXELSPROC) load("glReadPixels", userptr);
+ glScissor = (PFNGLSCISSORPROC) load("glScissor", userptr);
+ glStencilFunc = (PFNGLSTENCILFUNCPROC) load("glStencilFunc", userptr);
+ glStencilMask = (PFNGLSTENCILMASKPROC) load("glStencilMask", userptr);
+ glStencilOp = (PFNGLSTENCILOPPROC) load("glStencilOp", userptr);
+ glTexImage1D = (PFNGLTEXIMAGE1DPROC) load("glTexImage1D", userptr);
+ glTexImage2D = (PFNGLTEXIMAGE2DPROC) load("glTexImage2D", userptr);
+ glTexParameterf = (PFNGLTEXPARAMETERFPROC) load("glTexParameterf", userptr);
+ glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load("glTexParameterfv", userptr);
+ glTexParameteri = (PFNGLTEXPARAMETERIPROC) load("glTexParameteri", userptr);
+ glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load("glTexParameteriv", userptr);
+ glViewport = (PFNGLVIEWPORTPROC) load("glViewport", userptr);
+}
+static void glad_gl_load_GL_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_1_1) return;
+ glBindTexture = (PFNGLBINDTEXTUREPROC) load("glBindTexture", userptr);
+ glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) load("glCopyTexImage1D", userptr);
+ glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load("glCopyTexImage2D", userptr);
+ glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) load("glCopyTexSubImage1D", userptr);
+ glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load("glCopyTexSubImage2D", userptr);
+ glDeleteTextures = (PFNGLDELETETEXTURESPROC) load("glDeleteTextures", userptr);
+ glDrawArrays = (PFNGLDRAWARRAYSPROC) load("glDrawArrays", userptr);
+ glDrawElements = (PFNGLDRAWELEMENTSPROC) load("glDrawElements", userptr);
+ glGenTextures = (PFNGLGENTEXTURESPROC) load("glGenTextures", userptr);
+ glGetPointerv = (PFNGLGETPOINTERVPROC) load("glGetPointerv", userptr);
+ glIsTexture = (PFNGLISTEXTUREPROC) load("glIsTexture", userptr);
+ glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load("glPolygonOffset", userptr);
+ glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) load("glTexSubImage1D", userptr);
+ glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load("glTexSubImage2D", userptr);
+}
+static void glad_gl_load_GL_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_1_2) return;
+ glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load("glCopyTexSubImage3D", userptr);
+ glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load("glDrawRangeElements", userptr);
+ glTexImage3D = (PFNGLTEXIMAGE3DPROC) load("glTexImage3D", userptr);
+ glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load("glTexSubImage3D", userptr);
+}
+static void glad_gl_load_GL_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_1_3) return;
+ glActiveTexture = (PFNGLACTIVETEXTUREPROC) load("glActiveTexture", userptr);
+ glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) load("glCompressedTexImage1D", userptr);
+ glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load("glCompressedTexImage2D", userptr);
+ glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load("glCompressedTexImage3D", userptr);
+ glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) load("glCompressedTexSubImage1D", userptr);
+ glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load("glCompressedTexSubImage2D", userptr);
+ glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load("glCompressedTexSubImage3D", userptr);
+ glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) load("glGetCompressedTexImage", userptr);
+ glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load("glSampleCoverage", userptr);
+}
+static void glad_gl_load_GL_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_1_4) return;
+ glBlendColor = (PFNGLBLENDCOLORPROC) load("glBlendColor", userptr);
+ glBlendEquation = (PFNGLBLENDEQUATIONPROC) load("glBlendEquation", userptr);
+ glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load("glBlendFuncSeparate", userptr);
+ glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) load("glMultiDrawArrays", userptr);
+ glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) load("glMultiDrawElements", userptr);
+ glPointParameterf = (PFNGLPOINTPARAMETERFPROC) load("glPointParameterf", userptr);
+ glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC) load("glPointParameterfv", userptr);
+ glPointParameteri = (PFNGLPOINTPARAMETERIPROC) load("glPointParameteri", userptr);
+ glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC) load("glPointParameteriv", userptr);
+}
+static void glad_gl_load_GL_VERSION_1_5( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_1_5) return;
+ glBeginQuery = (PFNGLBEGINQUERYPROC) load("glBeginQuery", userptr);
+ glBindBuffer = (PFNGLBINDBUFFERPROC) load("glBindBuffer", userptr);
+ glBufferData = (PFNGLBUFFERDATAPROC) load("glBufferData", userptr);
+ glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load("glBufferSubData", userptr);
+ glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load("glDeleteBuffers", userptr);
+ glDeleteQueries = (PFNGLDELETEQUERIESPROC) load("glDeleteQueries", userptr);
+ glEndQuery = (PFNGLENDQUERYPROC) load("glEndQuery", userptr);
+ glGenBuffers = (PFNGLGENBUFFERSPROC) load("glGenBuffers", userptr);
+ glGenQueries = (PFNGLGENQUERIESPROC) load("glGenQueries", userptr);
+ glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load("glGetBufferParameteriv", userptr);
+ glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load("glGetBufferPointerv", userptr);
+ glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) load("glGetBufferSubData", userptr);
+ glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) load("glGetQueryObjectiv", userptr);
+ glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load("glGetQueryObjectuiv", userptr);
+ glGetQueryiv = (PFNGLGETQUERYIVPROC) load("glGetQueryiv", userptr);
+ glIsBuffer = (PFNGLISBUFFERPROC) load("glIsBuffer", userptr);
+ glIsQuery = (PFNGLISQUERYPROC) load("glIsQuery", userptr);
+ glMapBuffer = (PFNGLMAPBUFFERPROC) load("glMapBuffer", userptr);
+ glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load("glUnmapBuffer", userptr);
+}
+static void glad_gl_load_GL_VERSION_2_0( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_2_0) return;
+ glAttachShader = (PFNGLATTACHSHADERPROC) load("glAttachShader", userptr);
+ glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load("glBindAttribLocation", userptr);
+ glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load("glBlendEquationSeparate", userptr);
+ glCompileShader = (PFNGLCOMPILESHADERPROC) load("glCompileShader", userptr);
+ glCreateProgram = (PFNGLCREATEPROGRAMPROC) load("glCreateProgram", userptr);
+ glCreateShader = (PFNGLCREATESHADERPROC) load("glCreateShader", userptr);
+ glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load("glDeleteProgram", userptr);
+ glDeleteShader = (PFNGLDELETESHADERPROC) load("glDeleteShader", userptr);
+ glDetachShader = (PFNGLDETACHSHADERPROC) load("glDetachShader", userptr);
+ glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load("glDisableVertexAttribArray", userptr);
+ glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load("glDrawBuffers", userptr);
+ glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load("glEnableVertexAttribArray", userptr);
+ glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load("glGetActiveAttrib", userptr);
+ glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load("glGetActiveUniform", userptr);
+ glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load("glGetAttachedShaders", userptr);
+ glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load("glGetAttribLocation", userptr);
+ glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load("glGetProgramInfoLog", userptr);
+ glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load("glGetProgramiv", userptr);
+ glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load("glGetShaderInfoLog", userptr);
+ glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load("glGetShaderSource", userptr);
+ glGetShaderiv = (PFNGLGETSHADERIVPROC) load("glGetShaderiv", userptr);
+ glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load("glGetUniformLocation", userptr);
+ glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load("glGetUniformfv", userptr);
+ glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load("glGetUniformiv", userptr);
+ glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load("glGetVertexAttribPointerv", userptr);
+ glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) load("glGetVertexAttribdv", userptr);
+ glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load("glGetVertexAttribfv", userptr);
+ glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load("glGetVertexAttribiv", userptr);
+ glIsProgram = (PFNGLISPROGRAMPROC) load("glIsProgram", userptr);
+ glIsShader = (PFNGLISSHADERPROC) load("glIsShader", userptr);
+ glLinkProgram = (PFNGLLINKPROGRAMPROC) load("glLinkProgram", userptr);
+ glShaderSource = (PFNGLSHADERSOURCEPROC) load("glShaderSource", userptr);
+ glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load("glStencilFuncSeparate", userptr);
+ glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load("glStencilMaskSeparate", userptr);
+ glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load("glStencilOpSeparate", userptr);
+ glUniform1f = (PFNGLUNIFORM1FPROC) load("glUniform1f", userptr);
+ glUniform1fv = (PFNGLUNIFORM1FVPROC) load("glUniform1fv", userptr);
+ glUniform1i = (PFNGLUNIFORM1IPROC) load("glUniform1i", userptr);
+ glUniform1iv = (PFNGLUNIFORM1IVPROC) load("glUniform1iv", userptr);
+ glUniform2f = (PFNGLUNIFORM2FPROC) load("glUniform2f", userptr);
+ glUniform2fv = (PFNGLUNIFORM2FVPROC) load("glUniform2fv", userptr);
+ glUniform2i = (PFNGLUNIFORM2IPROC) load("glUniform2i", userptr);
+ glUniform2iv = (PFNGLUNIFORM2IVPROC) load("glUniform2iv", userptr);
+ glUniform3f = (PFNGLUNIFORM3FPROC) load("glUniform3f", userptr);
+ glUniform3fv = (PFNGLUNIFORM3FVPROC) load("glUniform3fv", userptr);
+ glUniform3i = (PFNGLUNIFORM3IPROC) load("glUniform3i", userptr);
+ glUniform3iv = (PFNGLUNIFORM3IVPROC) load("glUniform3iv", userptr);
+ glUniform4f = (PFNGLUNIFORM4FPROC) load("glUniform4f", userptr);
+ glUniform4fv = (PFNGLUNIFORM4FVPROC) load("glUniform4fv", userptr);
+ glUniform4i = (PFNGLUNIFORM4IPROC) load("glUniform4i", userptr);
+ glUniform4iv = (PFNGLUNIFORM4IVPROC) load("glUniform4iv", userptr);
+ glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load("glUniformMatrix2fv", userptr);
+ glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load("glUniformMatrix3fv", userptr);
+ glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load("glUniformMatrix4fv", userptr);
+ glUseProgram = (PFNGLUSEPROGRAMPROC) load("glUseProgram", userptr);
+ glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load("glValidateProgram", userptr);
+ glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) load("glVertexAttrib1d", userptr);
+ glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) load("glVertexAttrib1dv", userptr);
+ glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load("glVertexAttrib1f", userptr);
+ glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load("glVertexAttrib1fv", userptr);
+ glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) load("glVertexAttrib1s", userptr);
+ glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) load("glVertexAttrib1sv", userptr);
+ glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) load("glVertexAttrib2d", userptr);
+ glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) load("glVertexAttrib2dv", userptr);
+ glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load("glVertexAttrib2f", userptr);
+ glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load("glVertexAttrib2fv", userptr);
+ glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) load("glVertexAttrib2s", userptr);
+ glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) load("glVertexAttrib2sv", userptr);
+ glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) load("glVertexAttrib3d", userptr);
+ glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) load("glVertexAttrib3dv", userptr);
+ glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load("glVertexAttrib3f", userptr);
+ glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load("glVertexAttrib3fv", userptr);
+ glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) load("glVertexAttrib3s", userptr);
+ glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) load("glVertexAttrib3sv", userptr);
+ glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) load("glVertexAttrib4Nbv", userptr);
+ glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) load("glVertexAttrib4Niv", userptr);
+ glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) load("glVertexAttrib4Nsv", userptr);
+ glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) load("glVertexAttrib4Nub", userptr);
+ glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) load("glVertexAttrib4Nubv", userptr);
+ glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) load("glVertexAttrib4Nuiv", userptr);
+ glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) load("glVertexAttrib4Nusv", userptr);
+ glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) load("glVertexAttrib4bv", userptr);
+ glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) load("glVertexAttrib4d", userptr);
+ glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) load("glVertexAttrib4dv", userptr);
+ glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load("glVertexAttrib4f", userptr);
+ glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load("glVertexAttrib4fv", userptr);
+ glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) load("glVertexAttrib4iv", userptr);
+ glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) load("glVertexAttrib4s", userptr);
+ glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) load("glVertexAttrib4sv", userptr);
+ glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) load("glVertexAttrib4ubv", userptr);
+ glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) load("glVertexAttrib4uiv", userptr);
+ glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) load("glVertexAttrib4usv", userptr);
+ glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load("glVertexAttribPointer", userptr);
+}
+static void glad_gl_load_GL_VERSION_2_1( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_2_1) return;
+ glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load("glUniformMatrix2x3fv", userptr);
+ glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load("glUniformMatrix2x4fv", userptr);
+ glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load("glUniformMatrix3x2fv", userptr);
+ glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load("glUniformMatrix3x4fv", userptr);
+ glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load("glUniformMatrix4x2fv", userptr);
+ glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load("glUniformMatrix4x3fv", userptr);
+}
+static void glad_gl_load_GL_VERSION_3_0( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_3_0) return;
+ glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) load("glBeginConditionalRender", userptr);
+ glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load("glBeginTransformFeedback", userptr);
+ glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load("glBindBufferBase", userptr);
+ glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load("glBindBufferRange", userptr);
+ glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) load("glBindFragDataLocation", userptr);
+ glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load("glBindFramebuffer", userptr);
+ glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load("glBindRenderbuffer", userptr);
+ glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load("glBindVertexArray", userptr);
+ glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load("glBlitFramebuffer", userptr);
+ glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load("glCheckFramebufferStatus", userptr);
+ glClampColor = (PFNGLCLAMPCOLORPROC) load("glClampColor", userptr);
+ glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load("glClearBufferfi", userptr);
+ glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load("glClearBufferfv", userptr);
+ glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load("glClearBufferiv", userptr);
+ glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load("glClearBufferuiv", userptr);
+ glColorMaski = (PFNGLCOLORMASKIPROC) load("glColorMaski", userptr);
+ glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load("glDeleteFramebuffers", userptr);
+ glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load("glDeleteRenderbuffers", userptr);
+ glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load("glDeleteVertexArrays", userptr);
+ glDisablei = (PFNGLDISABLEIPROC) load("glDisablei", userptr);
+ glEnablei = (PFNGLENABLEIPROC) load("glEnablei", userptr);
+ glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) load("glEndConditionalRender", userptr);
+ glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load("glEndTransformFeedback", userptr);
+ glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load("glFlushMappedBufferRange", userptr);
+ glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load("glFramebufferRenderbuffer", userptr);
+ glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load("glFramebufferTexture1D", userptr);
+ glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load("glFramebufferTexture2D", userptr);
+ glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load("glFramebufferTexture3D", userptr);
+ glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load("glFramebufferTextureLayer", userptr);
+ glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load("glGenFramebuffers", userptr);
+ glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load("glGenRenderbuffers", userptr);
+ glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load("glGenVertexArrays", userptr);
+ glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load("glGenerateMipmap", userptr);
+ glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load("glGetBooleani_v", userptr);
+ glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load("glGetFragDataLocation", userptr);
+ glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load("glGetFramebufferAttachmentParameteriv", userptr);
+ glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load("glGetIntegeri_v", userptr);
+ glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load("glGetRenderbufferParameteriv", userptr);
+ glGetStringi = (PFNGLGETSTRINGIPROC) load("glGetStringi", userptr);
+ glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) load("glGetTexParameterIiv", userptr);
+ glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) load("glGetTexParameterIuiv", userptr);
+ glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load("glGetTransformFeedbackVarying", userptr);
+ glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load("glGetUniformuiv", userptr);
+ glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load("glGetVertexAttribIiv", userptr);
+ glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load("glGetVertexAttribIuiv", userptr);
+ glIsEnabledi = (PFNGLISENABLEDIPROC) load("glIsEnabledi", userptr);
+ glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load("glIsFramebuffer", userptr);
+ glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load("glIsRenderbuffer", userptr);
+ glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load("glIsVertexArray", userptr);
+ glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load("glMapBufferRange", userptr);
+ glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load("glRenderbufferStorage", userptr);
+ glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load("glRenderbufferStorageMultisample", userptr);
+ glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) load("glTexParameterIiv", userptr);
+ glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) load("glTexParameterIuiv", userptr);
+ glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load("glTransformFeedbackVaryings", userptr);
+ glUniform1ui = (PFNGLUNIFORM1UIPROC) load("glUniform1ui", userptr);
+ glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load("glUniform1uiv", userptr);
+ glUniform2ui = (PFNGLUNIFORM2UIPROC) load("glUniform2ui", userptr);
+ glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load("glUniform2uiv", userptr);
+ glUniform3ui = (PFNGLUNIFORM3UIPROC) load("glUniform3ui", userptr);
+ glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load("glUniform3uiv", userptr);
+ glUniform4ui = (PFNGLUNIFORM4UIPROC) load("glUniform4ui", userptr);
+ glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load("glUniform4uiv", userptr);
+ glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) load("glVertexAttribI1i", userptr);
+ glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) load("glVertexAttribI1iv", userptr);
+ glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) load("glVertexAttribI1ui", userptr);
+ glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) load("glVertexAttribI1uiv", userptr);
+ glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) load("glVertexAttribI2i", userptr);
+ glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) load("glVertexAttribI2iv", userptr);
+ glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) load("glVertexAttribI2ui", userptr);
+ glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) load("glVertexAttribI2uiv", userptr);
+ glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) load("glVertexAttribI3i", userptr);
+ glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) load("glVertexAttribI3iv", userptr);
+ glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) load("glVertexAttribI3ui", userptr);
+ glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) load("glVertexAttribI3uiv", userptr);
+ glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) load("glVertexAttribI4bv", userptr);
+ glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load("glVertexAttribI4i", userptr);
+ glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load("glVertexAttribI4iv", userptr);
+ glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) load("glVertexAttribI4sv", userptr);
+ glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) load("glVertexAttribI4ubv", userptr);
+ glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load("glVertexAttribI4ui", userptr);
+ glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load("glVertexAttribI4uiv", userptr);
+ glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) load("glVertexAttribI4usv", userptr);
+ glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load("glVertexAttribIPointer", userptr);
+}
+static void glad_gl_load_GL_VERSION_3_1( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_3_1) return;
+ glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load("glBindBufferBase", userptr);
+ glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load("glBindBufferRange", userptr);
+ glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load("glCopyBufferSubData", userptr);
+ glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load("glDrawArraysInstanced", userptr);
+ glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load("glDrawElementsInstanced", userptr);
+ glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load("glGetActiveUniformBlockName", userptr);
+ glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load("glGetActiveUniformBlockiv", userptr);
+ glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC) load("glGetActiveUniformName", userptr);
+ glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load("glGetActiveUniformsiv", userptr);
+ glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load("glGetIntegeri_v", userptr);
+ glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load("glGetUniformBlockIndex", userptr);
+ glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load("glGetUniformIndices", userptr);
+ glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC) load("glPrimitiveRestartIndex", userptr);
+ glTexBuffer = (PFNGLTEXBUFFERPROC) load("glTexBuffer", userptr);
+ glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load("glUniformBlockBinding", userptr);
+}
+static void glad_gl_load_GL_VERSION_3_2( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_3_2) return;
+ glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load("glClientWaitSync", userptr);
+ glDeleteSync = (PFNGLDELETESYNCPROC) load("glDeleteSync", userptr);
+ glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) load("glDrawElementsBaseVertex", userptr);
+ glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) load("glDrawElementsInstancedBaseVertex", userptr);
+ glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) load("glDrawRangeElementsBaseVertex", userptr);
+ glFenceSync = (PFNGLFENCESYNCPROC) load("glFenceSync", userptr);
+ glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC) load("glFramebufferTexture", userptr);
+ glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load("glGetBufferParameteri64v", userptr);
+ glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load("glGetInteger64i_v", userptr);
+ glGetInteger64v = (PFNGLGETINTEGER64VPROC) load("glGetInteger64v", userptr);
+ glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) load("glGetMultisamplefv", userptr);
+ glGetSynciv = (PFNGLGETSYNCIVPROC) load("glGetSynciv", userptr);
+ glIsSync = (PFNGLISSYNCPROC) load("glIsSync", userptr);
+ glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) load("glMultiDrawElementsBaseVertex", userptr);
+ glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC) load("glProvokingVertex", userptr);
+ glSampleMaski = (PFNGLSAMPLEMASKIPROC) load("glSampleMaski", userptr);
+ glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) load("glTexImage2DMultisample", userptr);
+ glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) load("glTexImage3DMultisample", userptr);
+ glWaitSync = (PFNGLWAITSYNCPROC) load("glWaitSync", userptr);
+}
+static void glad_gl_load_GL_VERSION_3_3( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_3_3) return;
+ glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) load("glBindFragDataLocationIndexed", userptr);
+ glBindSampler = (PFNGLBINDSAMPLERPROC) load("glBindSampler", userptr);
+ glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load("glDeleteSamplers", userptr);
+ glGenSamplers = (PFNGLGENSAMPLERSPROC) load("glGenSamplers", userptr);
+ glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC) load("glGetFragDataIndex", userptr);
+ glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) load("glGetQueryObjecti64v", userptr);
+ glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) load("glGetQueryObjectui64v", userptr);
+ glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) load("glGetSamplerParameterIiv", userptr);
+ glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) load("glGetSamplerParameterIuiv", userptr);
+ glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load("glGetSamplerParameterfv", userptr);
+ glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load("glGetSamplerParameteriv", userptr);
+ glIsSampler = (PFNGLISSAMPLERPROC) load("glIsSampler", userptr);
+ glQueryCounter = (PFNGLQUERYCOUNTERPROC) load("glQueryCounter", userptr);
+ glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) load("glSamplerParameterIiv", userptr);
+ glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) load("glSamplerParameterIuiv", userptr);
+ glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load("glSamplerParameterf", userptr);
+ glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load("glSamplerParameterfv", userptr);
+ glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load("glSamplerParameteri", userptr);
+ glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load("glSamplerParameteriv", userptr);
+ glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load("glVertexAttribDivisor", userptr);
+ glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC) load("glVertexAttribP1ui", userptr);
+ glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC) load("glVertexAttribP1uiv", userptr);
+ glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC) load("glVertexAttribP2ui", userptr);
+ glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC) load("glVertexAttribP2uiv", userptr);
+ glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC) load("glVertexAttribP3ui", userptr);
+ glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC) load("glVertexAttribP3uiv", userptr);
+ glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC) load("glVertexAttribP4ui", userptr);
+ glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC) load("glVertexAttribP4uiv", userptr);
+}
+static void glad_gl_load_GL_VERSION_4_0( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_0) return;
+ glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC) load("glBeginQueryIndexed", userptr);
+ glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) load("glBindTransformFeedback", userptr);
+ glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC) load("glBlendEquationSeparatei", userptr);
+ glBlendEquationi = (PFNGLBLENDEQUATIONIPROC) load("glBlendEquationi", userptr);
+ glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC) load("glBlendFuncSeparatei", userptr);
+ glBlendFunci = (PFNGLBLENDFUNCIPROC) load("glBlendFunci", userptr);
+ glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) load("glDeleteTransformFeedbacks", userptr);
+ glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC) load("glDrawArraysIndirect", userptr);
+ glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC) load("glDrawElementsIndirect", userptr);
+ glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC) load("glDrawTransformFeedback", userptr);
+ glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) load("glDrawTransformFeedbackStream", userptr);
+ glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC) load("glEndQueryIndexed", userptr);
+ glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) load("glGenTransformFeedbacks", userptr);
+ glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC) load("glGetActiveSubroutineName", userptr);
+ glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) load("glGetActiveSubroutineUniformName", userptr);
+ glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) load("glGetActiveSubroutineUniformiv", userptr);
+ glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC) load("glGetProgramStageiv", userptr);
+ glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC) load("glGetQueryIndexediv", userptr);
+ glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC) load("glGetSubroutineIndex", userptr);
+ glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) load("glGetSubroutineUniformLocation", userptr);
+ glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC) load("glGetUniformSubroutineuiv", userptr);
+ glGetUniformdv = (PFNGLGETUNIFORMDVPROC) load("glGetUniformdv", userptr);
+ glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) load("glIsTransformFeedback", userptr);
+ glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC) load("glMinSampleShading", userptr);
+ glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC) load("glPatchParameterfv", userptr);
+ glPatchParameteri = (PFNGLPATCHPARAMETERIPROC) load("glPatchParameteri", userptr);
+ glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) load("glPauseTransformFeedback", userptr);
+ glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) load("glResumeTransformFeedback", userptr);
+ glUniform1d = (PFNGLUNIFORM1DPROC) load("glUniform1d", userptr);
+ glUniform1dv = (PFNGLUNIFORM1DVPROC) load("glUniform1dv", userptr);
+ glUniform2d = (PFNGLUNIFORM2DPROC) load("glUniform2d", userptr);
+ glUniform2dv = (PFNGLUNIFORM2DVPROC) load("glUniform2dv", userptr);
+ glUniform3d = (PFNGLUNIFORM3DPROC) load("glUniform3d", userptr);
+ glUniform3dv = (PFNGLUNIFORM3DVPROC) load("glUniform3dv", userptr);
+ glUniform4d = (PFNGLUNIFORM4DPROC) load("glUniform4d", userptr);
+ glUniform4dv = (PFNGLUNIFORM4DVPROC) load("glUniform4dv", userptr);
+ glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC) load("glUniformMatrix2dv", userptr);
+ glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC) load("glUniformMatrix2x3dv", userptr);
+ glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC) load("glUniformMatrix2x4dv", userptr);
+ glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC) load("glUniformMatrix3dv", userptr);
+ glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC) load("glUniformMatrix3x2dv", userptr);
+ glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC) load("glUniformMatrix3x4dv", userptr);
+ glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC) load("glUniformMatrix4dv", userptr);
+ glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC) load("glUniformMatrix4x2dv", userptr);
+ glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC) load("glUniformMatrix4x3dv", userptr);
+ glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC) load("glUniformSubroutinesuiv", userptr);
+}
+static void glad_gl_load_GL_VERSION_4_1( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_1) return;
+ glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC) load("glActiveShaderProgram", userptr);
+ glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC) load("glBindProgramPipeline", userptr);
+ glClearDepthf = (PFNGLCLEARDEPTHFPROC) load("glClearDepthf", userptr);
+ glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC) load("glCreateShaderProgramv", userptr);
+ glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC) load("glDeleteProgramPipelines", userptr);
+ glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC) load("glDepthRangeArrayv", userptr);
+ glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC) load("glDepthRangeIndexed", userptr);
+ glDepthRangef = (PFNGLDEPTHRANGEFPROC) load("glDepthRangef", userptr);
+ glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC) load("glGenProgramPipelines", userptr);
+ glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC) load("glGetDoublei_v", userptr);
+ glGetFloati_v = (PFNGLGETFLOATI_VPROC) load("glGetFloati_v", userptr);
+ glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) load("glGetProgramBinary", userptr);
+ glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC) load("glGetProgramPipelineInfoLog", userptr);
+ glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC) load("glGetProgramPipelineiv", userptr);
+ glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load("glGetShaderPrecisionFormat", userptr);
+ glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC) load("glGetVertexAttribLdv", userptr);
+ glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC) load("glIsProgramPipeline", userptr);
+ glProgramBinary = (PFNGLPROGRAMBINARYPROC) load("glProgramBinary", userptr);
+ glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) load("glProgramParameteri", userptr);
+ glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC) load("glProgramUniform1d", userptr);
+ glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC) load("glProgramUniform1dv", userptr);
+ glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC) load("glProgramUniform1f", userptr);
+ glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC) load("glProgramUniform1fv", userptr);
+ glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC) load("glProgramUniform1i", userptr);
+ glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC) load("glProgramUniform1iv", userptr);
+ glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC) load("glProgramUniform1ui", userptr);
+ glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC) load("glProgramUniform1uiv", userptr);
+ glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC) load("glProgramUniform2d", userptr);
+ glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC) load("glProgramUniform2dv", userptr);
+ glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC) load("glProgramUniform2f", userptr);
+ glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC) load("glProgramUniform2fv", userptr);
+ glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC) load("glProgramUniform2i", userptr);
+ glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC) load("glProgramUniform2iv", userptr);
+ glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC) load("glProgramUniform2ui", userptr);
+ glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC) load("glProgramUniform2uiv", userptr);
+ glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC) load("glProgramUniform3d", userptr);
+ glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC) load("glProgramUniform3dv", userptr);
+ glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC) load("glProgramUniform3f", userptr);
+ glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC) load("glProgramUniform3fv", userptr);
+ glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC) load("glProgramUniform3i", userptr);
+ glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC) load("glProgramUniform3iv", userptr);
+ glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC) load("glProgramUniform3ui", userptr);
+ glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC) load("glProgramUniform3uiv", userptr);
+ glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC) load("glProgramUniform4d", userptr);
+ glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC) load("glProgramUniform4dv", userptr);
+ glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC) load("glProgramUniform4f", userptr);
+ glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC) load("glProgramUniform4fv", userptr);
+ glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC) load("glProgramUniform4i", userptr);
+ glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC) load("glProgramUniform4iv", userptr);
+ glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC) load("glProgramUniform4ui", userptr);
+ glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC) load("glProgramUniform4uiv", userptr);
+ glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC) load("glProgramUniformMatrix2dv", userptr);
+ glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC) load("glProgramUniformMatrix2fv", userptr);
+ glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) load("glProgramUniformMatrix2x3dv", userptr);
+ glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) load("glProgramUniformMatrix2x3fv", userptr);
+ glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) load("glProgramUniformMatrix2x4dv", userptr);
+ glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) load("glProgramUniformMatrix2x4fv", userptr);
+ glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC) load("glProgramUniformMatrix3dv", userptr);
+ glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC) load("glProgramUniformMatrix3fv", userptr);
+ glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) load("glProgramUniformMatrix3x2dv", userptr);
+ glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) load("glProgramUniformMatrix3x2fv", userptr);
+ glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) load("glProgramUniformMatrix3x4dv", userptr);
+ glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) load("glProgramUniformMatrix3x4fv", userptr);
+ glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC) load("glProgramUniformMatrix4dv", userptr);
+ glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC) load("glProgramUniformMatrix4fv", userptr);
+ glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) load("glProgramUniformMatrix4x2dv", userptr);
+ glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) load("glProgramUniformMatrix4x2fv", userptr);
+ glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) load("glProgramUniformMatrix4x3dv", userptr);
+ glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) load("glProgramUniformMatrix4x3fv", userptr);
+ glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load("glReleaseShaderCompiler", userptr);
+ glScissorArrayv = (PFNGLSCISSORARRAYVPROC) load("glScissorArrayv", userptr);
+ glScissorIndexed = (PFNGLSCISSORINDEXEDPROC) load("glScissorIndexed", userptr);
+ glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC) load("glScissorIndexedv", userptr);
+ glShaderBinary = (PFNGLSHADERBINARYPROC) load("glShaderBinary", userptr);
+ glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC) load("glUseProgramStages", userptr);
+ glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC) load("glValidateProgramPipeline", userptr);
+ glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC) load("glVertexAttribL1d", userptr);
+ glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC) load("glVertexAttribL1dv", userptr);
+ glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC) load("glVertexAttribL2d", userptr);
+ glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC) load("glVertexAttribL2dv", userptr);
+ glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC) load("glVertexAttribL3d", userptr);
+ glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC) load("glVertexAttribL3dv", userptr);
+ glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC) load("glVertexAttribL4d", userptr);
+ glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC) load("glVertexAttribL4dv", userptr);
+ glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC) load("glVertexAttribLPointer", userptr);
+ glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC) load("glViewportArrayv", userptr);
+ glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC) load("glViewportIndexedf", userptr);
+ glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC) load("glViewportIndexedfv", userptr);
+}
+static void glad_gl_load_GL_VERSION_4_2( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_2) return;
+ glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) load("glBindImageTexture", userptr);
+ glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) load("glDrawArraysInstancedBaseInstance", userptr);
+ glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) load("glDrawElementsInstancedBaseInstance", userptr);
+ glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) load("glDrawElementsInstancedBaseVertexBaseInstance", userptr);
+ glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) load("glDrawTransformFeedbackInstanced", userptr);
+ glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) load("glDrawTransformFeedbackStreamInstanced", userptr);
+ glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) load("glGetActiveAtomicCounterBufferiv", userptr);
+ glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) load("glGetInternalformativ", userptr);
+ glMemoryBarrier = (PFNGLMEMORYBARRIERPROC) load("glMemoryBarrier", userptr);
+ glTexStorage1D = (PFNGLTEXSTORAGE1DPROC) load("glTexStorage1D", userptr);
+ glTexStorage2D = (PFNGLTEXSTORAGE2DPROC) load("glTexStorage2D", userptr);
+ glTexStorage3D = (PFNGLTEXSTORAGE3DPROC) load("glTexStorage3D", userptr);
+}
+static void glad_gl_load_GL_VERSION_4_3( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_3) return;
+ glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC) load("glBindVertexBuffer", userptr);
+ glClearBufferData = (PFNGLCLEARBUFFERDATAPROC) load("glClearBufferData", userptr);
+ glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC) load("glClearBufferSubData", userptr);
+ glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC) load("glCopyImageSubData", userptr);
+ glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) load("glDebugMessageCallback", userptr);
+ glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) load("glDebugMessageControl", userptr);
+ glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC) load("glDebugMessageInsert", userptr);
+ glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC) load("glDispatchCompute", userptr);
+ glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC) load("glDispatchComputeIndirect", userptr);
+ glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC) load("glFramebufferParameteri", userptr);
+ glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC) load("glGetDebugMessageLog", userptr);
+ glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC) load("glGetFramebufferParameteriv", userptr);
+ glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC) load("glGetInternalformati64v", userptr);
+ glGetObjectLabel = (PFNGLGETOBJECTLABELPROC) load("glGetObjectLabel", userptr);
+ glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC) load("glGetObjectPtrLabel", userptr);
+ glGetPointerv = (PFNGLGETPOINTERVPROC) load("glGetPointerv", userptr);
+ glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC) load("glGetProgramInterfaceiv", userptr);
+ glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC) load("glGetProgramResourceIndex", userptr);
+ glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC) load("glGetProgramResourceLocation", userptr);
+ glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) load("glGetProgramResourceLocationIndex", userptr);
+ glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC) load("glGetProgramResourceName", userptr);
+ glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) load("glGetProgramResourceiv", userptr);
+ glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC) load("glInvalidateBufferData", userptr);
+ glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC) load("glInvalidateBufferSubData", userptr);
+ glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) load("glInvalidateFramebuffer", userptr);
+ glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) load("glInvalidateSubFramebuffer", userptr);
+ glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC) load("glInvalidateTexImage", userptr);
+ glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC) load("glInvalidateTexSubImage", userptr);
+ glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC) load("glMultiDrawArraysIndirect", userptr);
+ glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC) load("glMultiDrawElementsIndirect", userptr);
+ glObjectLabel = (PFNGLOBJECTLABELPROC) load("glObjectLabel", userptr);
+ glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC) load("glObjectPtrLabel", userptr);
+ glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC) load("glPopDebugGroup", userptr);
+ glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC) load("glPushDebugGroup", userptr);
+ glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC) load("glShaderStorageBlockBinding", userptr);
+ glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC) load("glTexBufferRange", userptr);
+ glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC) load("glTexStorage2DMultisample", userptr);
+ glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC) load("glTexStorage3DMultisample", userptr);
+ glTextureView = (PFNGLTEXTUREVIEWPROC) load("glTextureView", userptr);
+ glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC) load("glVertexAttribBinding", userptr);
+ glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC) load("glVertexAttribFormat", userptr);
+ glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC) load("glVertexAttribIFormat", userptr);
+ glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC) load("glVertexAttribLFormat", userptr);
+ glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC) load("glVertexBindingDivisor", userptr);
+}
+static void glad_gl_load_GL_VERSION_4_4( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_4) return;
+ glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC) load("glBindBuffersBase", userptr);
+ glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC) load("glBindBuffersRange", userptr);
+ glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC) load("glBindImageTextures", userptr);
+ glBindSamplers = (PFNGLBINDSAMPLERSPROC) load("glBindSamplers", userptr);
+ glBindTextures = (PFNGLBINDTEXTURESPROC) load("glBindTextures", userptr);
+ glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC) load("glBindVertexBuffers", userptr);
+ glBufferStorage = (PFNGLBUFFERSTORAGEPROC) load("glBufferStorage", userptr);
+ glClearTexImage = (PFNGLCLEARTEXIMAGEPROC) load("glClearTexImage", userptr);
+ glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC) load("glClearTexSubImage", userptr);
+}
+static void glad_gl_load_GL_VERSION_4_5( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_5) return;
+ glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC) load("glBindTextureUnit", userptr);
+ glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC) load("glBlitNamedFramebuffer", userptr);
+ glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) load("glCheckNamedFramebufferStatus", userptr);
+ glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC) load("glClearNamedBufferData", userptr);
+ glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC) load("glClearNamedBufferSubData", userptr);
+ glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) load("glClearNamedFramebufferfi", userptr);
+ glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) load("glClearNamedFramebufferfv", userptr);
+ glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) load("glClearNamedFramebufferiv", userptr);
+ glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) load("glClearNamedFramebufferuiv", userptr);
+ glClipControl = (PFNGLCLIPCONTROLPROC) load("glClipControl", userptr);
+ glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) load("glCompressedTextureSubImage1D", userptr);
+ glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) load("glCompressedTextureSubImage2D", userptr);
+ glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) load("glCompressedTextureSubImage3D", userptr);
+ glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC) load("glCopyNamedBufferSubData", userptr);
+ glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC) load("glCopyTextureSubImage1D", userptr);
+ glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC) load("glCopyTextureSubImage2D", userptr);
+ glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC) load("glCopyTextureSubImage3D", userptr);
+ glCreateBuffers = (PFNGLCREATEBUFFERSPROC) load("glCreateBuffers", userptr);
+ glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC) load("glCreateFramebuffers", userptr);
+ glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC) load("glCreateProgramPipelines", userptr);
+ glCreateQueries = (PFNGLCREATEQUERIESPROC) load("glCreateQueries", userptr);
+ glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC) load("glCreateRenderbuffers", userptr);
+ glCreateSamplers = (PFNGLCREATESAMPLERSPROC) load("glCreateSamplers", userptr);
+ glCreateTextures = (PFNGLCREATETEXTURESPROC) load("glCreateTextures", userptr);
+ glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC) load("glCreateTransformFeedbacks", userptr);
+ glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC) load("glCreateVertexArrays", userptr);
+ glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC) load("glDisableVertexArrayAttrib", userptr);
+ glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC) load("glEnableVertexArrayAttrib", userptr);
+ glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) load("glFlushMappedNamedBufferRange", userptr);
+ glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) load("glGenerateTextureMipmap", userptr);
+ glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) load("glGetCompressedTextureImage", userptr);
+ glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) load("glGetCompressedTextureSubImage", userptr);
+ glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC) load("glGetGraphicsResetStatus", userptr);
+ glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) load("glGetNamedBufferParameteri64v", userptr);
+ glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC) load("glGetNamedBufferParameteriv", userptr);
+ glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC) load("glGetNamedBufferPointerv", userptr);
+ glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC) load("glGetNamedBufferSubData", userptr);
+ glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load("glGetNamedFramebufferAttachmentParameteriv", userptr);
+ glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) load("glGetNamedFramebufferParameteriv", userptr);
+ glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) load("glGetNamedRenderbufferParameteriv", userptr);
+ glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC) load("glGetQueryBufferObjecti64v", userptr);
+ glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC) load("glGetQueryBufferObjectiv", userptr);
+ glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC) load("glGetQueryBufferObjectui64v", userptr);
+ glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC) load("glGetQueryBufferObjectuiv", userptr);
+ glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC) load("glGetTextureImage", userptr);
+ glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC) load("glGetTextureLevelParameterfv", userptr);
+ glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC) load("glGetTextureLevelParameteriv", userptr);
+ glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC) load("glGetTextureParameterIiv", userptr);
+ glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC) load("glGetTextureParameterIuiv", userptr);
+ glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC) load("glGetTextureParameterfv", userptr);
+ glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC) load("glGetTextureParameteriv", userptr);
+ glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC) load("glGetTextureSubImage", userptr);
+ glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC) load("glGetTransformFeedbacki64_v", userptr);
+ glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC) load("glGetTransformFeedbacki_v", userptr);
+ glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC) load("glGetTransformFeedbackiv", userptr);
+ glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC) load("glGetVertexArrayIndexed64iv", userptr);
+ glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC) load("glGetVertexArrayIndexediv", userptr);
+ glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC) load("glGetVertexArrayiv", userptr);
+ glGetnCompressedTexImage = (PFNGLGETNCOMPRESSEDTEXIMAGEPROC) load("glGetnCompressedTexImage", userptr);
+ glGetnTexImage = (PFNGLGETNTEXIMAGEPROC) load("glGetnTexImage", userptr);
+ glGetnUniformdv = (PFNGLGETNUNIFORMDVPROC) load("glGetnUniformdv", userptr);
+ glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC) load("glGetnUniformfv", userptr);
+ glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC) load("glGetnUniformiv", userptr);
+ glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC) load("glGetnUniformuiv", userptr);
+ glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) load("glInvalidateNamedFramebufferData", userptr);
+ glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) load("glInvalidateNamedFramebufferSubData", userptr);
+ glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC) load("glMapNamedBuffer", userptr);
+ glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC) load("glMapNamedBufferRange", userptr);
+ glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC) load("glMemoryBarrierByRegion", userptr);
+ glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC) load("glNamedBufferData", userptr);
+ glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC) load("glNamedBufferStorage", userptr);
+ glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC) load("glNamedBufferSubData", userptr);
+ glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) load("glNamedFramebufferDrawBuffer", userptr);
+ glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) load("glNamedFramebufferDrawBuffers", userptr);
+ glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) load("glNamedFramebufferParameteri", userptr);
+ glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) load("glNamedFramebufferReadBuffer", userptr);
+ glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) load("glNamedFramebufferRenderbuffer", userptr);
+ glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) load("glNamedFramebufferTexture", userptr);
+ glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) load("glNamedFramebufferTextureLayer", userptr);
+ glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC) load("glNamedRenderbufferStorage", userptr);
+ glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) load("glNamedRenderbufferStorageMultisample", userptr);
+ glReadnPixels = (PFNGLREADNPIXELSPROC) load("glReadnPixels", userptr);
+ glTextureBarrier = (PFNGLTEXTUREBARRIERPROC) load("glTextureBarrier", userptr);
+ glTextureBuffer = (PFNGLTEXTUREBUFFERPROC) load("glTextureBuffer", userptr);
+ glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC) load("glTextureBufferRange", userptr);
+ glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC) load("glTextureParameterIiv", userptr);
+ glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC) load("glTextureParameterIuiv", userptr);
+ glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC) load("glTextureParameterf", userptr);
+ glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC) load("glTextureParameterfv", userptr);
+ glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC) load("glTextureParameteri", userptr);
+ glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC) load("glTextureParameteriv", userptr);
+ glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC) load("glTextureStorage1D", userptr);
+ glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC) load("glTextureStorage2D", userptr);
+ glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) load("glTextureStorage2DMultisample", userptr);
+ glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC) load("glTextureStorage3D", userptr);
+ glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) load("glTextureStorage3DMultisample", userptr);
+ glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC) load("glTextureSubImage1D", userptr);
+ glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC) load("glTextureSubImage2D", userptr);
+ glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC) load("glTextureSubImage3D", userptr);
+ glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) load("glTransformFeedbackBufferBase", userptr);
+ glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) load("glTransformFeedbackBufferRange", userptr);
+ glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC) load("glUnmapNamedBuffer", userptr);
+ glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC) load("glVertexArrayAttribBinding", userptr);
+ glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC) load("glVertexArrayAttribFormat", userptr);
+ glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC) load("glVertexArrayAttribIFormat", userptr);
+ glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC) load("glVertexArrayAttribLFormat", userptr);
+ glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC) load("glVertexArrayBindingDivisor", userptr);
+ glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC) load("glVertexArrayElementBuffer", userptr);
+ glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC) load("glVertexArrayVertexBuffer", userptr);
+ glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC) load("glVertexArrayVertexBuffers", userptr);
+}
+static void glad_gl_load_GL_EXT_memory_object( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_EXT_memory_object) return;
+ glBufferStorageMemEXT = (PFNGLBUFFERSTORAGEMEMEXTPROC) load("glBufferStorageMemEXT", userptr);
+ glCreateMemoryObjectsEXT = (PFNGLCREATEMEMORYOBJECTSEXTPROC) load("glCreateMemoryObjectsEXT", userptr);
+ glDeleteMemoryObjectsEXT = (PFNGLDELETEMEMORYOBJECTSEXTPROC) load("glDeleteMemoryObjectsEXT", userptr);
+ glGetMemoryObjectParameterivEXT = (PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) load("glGetMemoryObjectParameterivEXT", userptr);
+ glGetUnsignedBytei_vEXT = (PFNGLGETUNSIGNEDBYTEI_VEXTPROC) load("glGetUnsignedBytei_vEXT", userptr);
+ glGetUnsignedBytevEXT = (PFNGLGETUNSIGNEDBYTEVEXTPROC) load("glGetUnsignedBytevEXT", userptr);
+ glIsMemoryObjectEXT = (PFNGLISMEMORYOBJECTEXTPROC) load("glIsMemoryObjectEXT", userptr);
+ glMemoryObjectParameterivEXT = (PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) load("glMemoryObjectParameterivEXT", userptr);
+ glNamedBufferStorageMemEXT = (PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) load("glNamedBufferStorageMemEXT", userptr);
+ glTexStorageMem1DEXT = (PFNGLTEXSTORAGEMEM1DEXTPROC) load("glTexStorageMem1DEXT", userptr);
+ glTexStorageMem2DEXT = (PFNGLTEXSTORAGEMEM2DEXTPROC) load("glTexStorageMem2DEXT", userptr);
+ glTexStorageMem2DMultisampleEXT = (PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) load("glTexStorageMem2DMultisampleEXT", userptr);
+ glTexStorageMem3DEXT = (PFNGLTEXSTORAGEMEM3DEXTPROC) load("glTexStorageMem3DEXT", userptr);
+ glTexStorageMem3DMultisampleEXT = (PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) load("glTexStorageMem3DMultisampleEXT", userptr);
+ glTextureStorageMem1DEXT = (PFNGLTEXTURESTORAGEMEM1DEXTPROC) load("glTextureStorageMem1DEXT", userptr);
+ glTextureStorageMem2DEXT = (PFNGLTEXTURESTORAGEMEM2DEXTPROC) load("glTextureStorageMem2DEXT", userptr);
+ glTextureStorageMem2DMultisampleEXT = (PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) load("glTextureStorageMem2DMultisampleEXT", userptr);
+ glTextureStorageMem3DEXT = (PFNGLTEXTURESTORAGEMEM3DEXTPROC) load("glTextureStorageMem3DEXT", userptr);
+ glTextureStorageMem3DMultisampleEXT = (PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) load("glTextureStorageMem3DMultisampleEXT", userptr);
+}
+static void glad_gl_load_GL_EXT_memory_object_fd( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_EXT_memory_object_fd) return;
+ glImportMemoryFdEXT = (PFNGLIMPORTMEMORYFDEXTPROC) load("glImportMemoryFdEXT", userptr);
+}
+
+
+
+#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0)
+#define GLAD_GL_IS_SOME_NEW_VERSION 1
+#else
+#define GLAD_GL_IS_SOME_NEW_VERSION 0
+#endif
+
+static int glad_gl_get_extensions( int version, const char **out_exts, unsigned int *out_num_exts_i, char ***out_exts_i) {
+#if GLAD_GL_IS_SOME_NEW_VERSION
+ if(GLAD_VERSION_MAJOR(version) < 3) {
+#else
+ (void) version;
+ (void) out_num_exts_i;
+ (void) out_exts_i;
+#endif
+ if (glGetString == NULL) {
+ return 0;
+ }
+ *out_exts = (const char *)glGetString(GL_EXTENSIONS);
+#if GLAD_GL_IS_SOME_NEW_VERSION
+ } else {
+ unsigned int index = 0;
+ unsigned int num_exts_i = 0;
+ char **exts_i = NULL;
+ if (glGetStringi == NULL || glGetIntegerv == NULL) {
+ return 0;
+ }
+ glGetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i);
+ if (num_exts_i > 0) {
+ exts_i = (char **) malloc(num_exts_i * (sizeof *exts_i));
+ }
+ if (exts_i == NULL) {
+ return 0;
+ }
+ for(index = 0; index < num_exts_i; index++) {
+ const char *gl_str_tmp = (const char*) glGetStringi(GL_EXTENSIONS, index);
+ size_t len = strlen(gl_str_tmp) + 1;
+
+ char *local_str = (char*) malloc(len * sizeof(char));
+ if(local_str != NULL) {
+ memcpy(local_str, gl_str_tmp, len * sizeof(char));
+ }
+
+ exts_i[index] = local_str;
+ }
+
+ *out_num_exts_i = num_exts_i;
+ *out_exts_i = exts_i;
+ }
+#endif
+ return 1;
+}
+static void glad_gl_free_extensions(char **exts_i, unsigned int num_exts_i) {
+ if (exts_i != NULL) {
+ unsigned int index;
+ for(index = 0; index < num_exts_i; index++) {
+ free((void *) (exts_i[index]));
+ }
+ free((void *)exts_i);
+ exts_i = NULL;
+ }
+}
+static int glad_gl_has_extension(int version, const char *exts, unsigned int num_exts_i, char **exts_i, const char *ext) {
+ if(GLAD_VERSION_MAJOR(version) < 3 || !GLAD_GL_IS_SOME_NEW_VERSION) {
+ const char *extensions;
+ const char *loc;
+ const char *terminator;
+ extensions = exts;
+ if(extensions == NULL || ext == NULL) {
+ return 0;
+ }
+ while(1) {
+ loc = strstr(extensions, ext);
+ if(loc == NULL) {
+ return 0;
+ }
+ terminator = loc + strlen(ext);
+ if((loc == extensions || *(loc - 1) == ' ') &&
+ (*terminator == ' ' || *terminator == '\0')) {
+ return 1;
+ }
+ extensions = terminator;
+ }
+ } else {
+ unsigned int index;
+ for(index = 0; index < num_exts_i; index++) {
+ const char *e = exts_i[index];
+ if(strcmp(e, ext) == 0) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static GLADapiproc glad_gl_get_proc_from_userptr(const char* name, void *userptr) {
+ return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name);
+}
+
+static int glad_gl_find_extensions_gl( int version) {
+ const char *exts = NULL;
+ unsigned int num_exts_i = 0;
+ char **exts_i = NULL;
+ if (!glad_gl_get_extensions(version, &exts, &num_exts_i, &exts_i)) return 0;
+
+ GLAD_GL_EXT_memory_object = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_memory_object");
+ GLAD_GL_EXT_memory_object_fd = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_memory_object_fd");
+
+ glad_gl_free_extensions(exts_i, num_exts_i);
+
+ return 1;
+}
+
+static int glad_gl_find_core_gl(void) {
+ int i, major, minor;
+ const char* version;
+ const char* prefixes[] = {
+ "OpenGL ES-CM ",
+ "OpenGL ES-CL ",
+ "OpenGL ES ",
+ NULL
+ };
+ version = (const char*) glGetString(GL_VERSION);
+ if (!version) return 0;
+ for (i = 0; prefixes[i]; i++) {
+ const size_t length = strlen(prefixes[i]);
+ if (strncmp(version, prefixes[i], length) == 0) {
+ version += length;
+ break;
+ }
+ }
+
+ GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor);
+
+ GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1;
+ GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1;
+ GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1;
+ GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1;
+ GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1;
+ GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1;
+ GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2;
+ GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2;
+ GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3;
+ GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3;
+ GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3;
+ GLAD_GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3;
+ GLAD_GL_VERSION_4_0 = (major == 4 && minor >= 0) || major > 4;
+ GLAD_GL_VERSION_4_1 = (major == 4 && minor >= 1) || major > 4;
+ GLAD_GL_VERSION_4_2 = (major == 4 && minor >= 2) || major > 4;
+ GLAD_GL_VERSION_4_3 = (major == 4 && minor >= 3) || major > 4;
+ GLAD_GL_VERSION_4_4 = (major == 4 && minor >= 4) || major > 4;
+ GLAD_GL_VERSION_4_5 = (major == 4 && minor >= 5) || major > 4;
+
+ return GLAD_MAKE_VERSION(major, minor);
+}
+
+int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) {
+ int version;
+
+ glGetString = (PFNGLGETSTRINGPROC) load("glGetString", userptr);
+ if(glGetString == NULL) return 0;
+ if(glGetString(GL_VERSION) == NULL) return 0;
+ version = glad_gl_find_core_gl();
+
+ glad_gl_load_GL_VERSION_1_0(load, userptr);
+ glad_gl_load_GL_VERSION_1_1(load, userptr);
+ glad_gl_load_GL_VERSION_1_2(load, userptr);
+ glad_gl_load_GL_VERSION_1_3(load, userptr);
+ glad_gl_load_GL_VERSION_1_4(load, userptr);
+ glad_gl_load_GL_VERSION_1_5(load, userptr);
+ glad_gl_load_GL_VERSION_2_0(load, userptr);
+ glad_gl_load_GL_VERSION_2_1(load, userptr);
+ glad_gl_load_GL_VERSION_3_0(load, userptr);
+ glad_gl_load_GL_VERSION_3_1(load, userptr);
+ glad_gl_load_GL_VERSION_3_2(load, userptr);
+ glad_gl_load_GL_VERSION_3_3(load, userptr);
+ glad_gl_load_GL_VERSION_4_0(load, userptr);
+ glad_gl_load_GL_VERSION_4_1(load, userptr);
+ glad_gl_load_GL_VERSION_4_2(load, userptr);
+ glad_gl_load_GL_VERSION_4_3(load, userptr);
+ glad_gl_load_GL_VERSION_4_4(load, userptr);
+ glad_gl_load_GL_VERSION_4_5(load, userptr);
+
+ if (!glad_gl_find_extensions_gl(version)) return 0;
+ glad_gl_load_GL_EXT_memory_object(load, userptr);
+ glad_gl_load_GL_EXT_memory_object_fd(load, userptr);
+
+
+
+ return version;
+}
+
+
+int gladLoadGL( GLADloadfunc load) {
+ return gladLoadGLUserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
+}
+
+
+
+
diff --git a/src/external/glad/gl.h b/src/external/glad/gl.h
new file mode 100644
index 000000000..01ad3848e
--- /dev/null
+++ b/src/external/glad/gl.h
@@ -0,0 +1,3692 @@
+/**
+ * Loader generated by glad 2.0.0-beta on Fri Feb 22 16:29:14 2019
+ *
+ * Generator: C/C++
+ * Specification: gl
+ * Extensions: 2
+ *
+ * APIs:
+ * - gl:core=4.5
+ *
+ * Options:
+ * - MX_GLOBAL = False
+ * - LOADER = False
+ * - ALIAS = False
+ * - HEADER_ONLY = False
+ * - DEBUG = False
+ * - MX = False
+ *
+ * Commandline:
+ * --api='gl:core=4.5' --extensions='GL_EXT_memory_object,GL_EXT_memory_object_fd' c
+ *
+ * Online:
+ * http://glad.sh/#api=gl%3Acore%3D4.5&extensions=GL_EXT_memory_object%2CGL_EXT_memory_object_fd&generator=c&options=
+ *
+ */
+
+#ifndef GLAD_GL_H_
+#define GLAD_GL_H_
+
+#ifdef __gl_h_
+ #error OpenGL header already included (API: gl), remove previous include!
+#endif
+#define __gl_h_ 1
+
+
+#define GLAD_GL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef GLAD_PLATFORM_H_
+#define GLAD_PLATFORM_H_
+
+#ifndef GLAD_PLATFORM_WIN32
+ #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)
+ #define GLAD_PLATFORM_WIN32 1
+ #else
+ #define GLAD_PLATFORM_WIN32 0
+ #endif
+#endif
+
+#ifndef GLAD_PLATFORM_APPLE
+ #ifdef __APPLE__
+ #define GLAD_PLATFORM_APPLE 1
+ #else
+ #define GLAD_PLATFORM_APPLE 0
+ #endif
+#endif
+
+#ifndef GLAD_PLATFORM_EMSCRIPTEN
+ #ifdef __EMSCRIPTEN__
+ #define GLAD_PLATFORM_EMSCRIPTEN 1
+ #else
+ #define GLAD_PLATFORM_EMSCRIPTEN 0
+ #endif
+#endif
+
+#ifndef GLAD_PLATFORM_UWP
+ #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY)
+ #ifdef __has_include
+ #if __has_include()
+ #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1
+ #endif
+ #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_
+ #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1
+ #endif
+ #endif
+
+ #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY
+ #include
+ #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
+ #define GLAD_PLATFORM_UWP 1
+ #endif
+ #endif
+
+ #ifndef GLAD_PLATFORM_UWP
+ #define GLAD_PLATFORM_UWP 0
+ #endif
+#endif
+
+#ifdef __GNUC__
+ #define GLAD_GNUC_EXTENSION __extension__
+#else
+ #define GLAD_GNUC_EXTENSION
+#endif
+
+#ifndef GLAD_API_CALL
+ #if defined(GLAD_API_CALL_EXPORT)
+ #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__)
+ #if defined(GLAD_API_CALL_EXPORT_BUILD)
+ #if defined(__GNUC__)
+ #define GLAD_API_CALL __attribute__ ((dllexport)) extern
+ #else
+ #define GLAD_API_CALL __declspec(dllexport) extern
+ #endif
+ #else
+ #if defined(__GNUC__)
+ #define GLAD_API_CALL __attribute__ ((dllimport)) extern
+ #else
+ #define GLAD_API_CALL __declspec(dllimport) extern
+ #endif
+ #endif
+ #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD)
+ #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern
+ #else
+ #define GLAD_API_CALL extern
+ #endif
+ #else
+ #define GLAD_API_CALL extern
+ #endif
+#endif
+
+#ifdef APIENTRY
+ #define GLAD_API_PTR APIENTRY
+#elif GLAD_PLATFORM_WIN32
+ #define GLAD_API_PTR __stdcall
+#else
+ #define GLAD_API_PTR
+#endif
+
+#ifndef GLAPI
+#define GLAPI GLAD_API_CALL
+#endif
+
+#ifndef GLAPIENTRY
+#define GLAPIENTRY GLAD_API_PTR
+#endif
+
+
+#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor)
+#define GLAD_VERSION_MAJOR(version) (version / 10000)
+#define GLAD_VERSION_MINOR(version) (version % 10000)
+
+typedef void (*GLADapiproc)(void);
+
+typedef GLADapiproc (*GLADloadfunc)(const char *name);
+typedef GLADapiproc (*GLADuserptrloadfunc)(const char *name, void *userptr);
+
+typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...);
+typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...);
+
+#endif /* GLAD_PLATFORM_H_ */
+
+#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_ACTIVE_PROGRAM 0x8259
+#define GL_ACTIVE_RESOURCES 0x92F5
+#define GL_ACTIVE_SUBROUTINES 0x8DE5
+#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48
+#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ACTIVE_VARIABLES 0x9305
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
+#define GL_ALL_SHADER_BITS 0xFFFFFFFF
+#define GL_ALPHA 0x1906
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_ALWAYS 0x0207
+#define GL_AND 0x1501
+#define GL_AND_INVERTED 0x1504
+#define GL_AND_REVERSE 0x1502
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ARRAY_SIZE 0x92FB
+#define GL_ARRAY_STRIDE 0x92FE
+#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
+#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6
+#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1
+#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4
+#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7
+#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3
+#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_AUTO_GENERATE_MIPMAP 0x8295
+#define GL_BACK 0x0405
+#define GL_BACK_LEFT 0x0402
+#define GL_BACK_RIGHT 0x0403
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_BGRA_INTEGER 0x8D9B
+#define GL_BGR_INTEGER 0x8D9A
+#define GL_BLEND 0x0BE2
+#define GL_BLEND_COLOR 0x8005
+#define GL_BLEND_DST 0x0BE0
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_BLEND_SRC 0x0BE1
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLOCK_INDEX 0x92FD
+#define GL_BLUE 0x1905
+#define GL_BLUE_INTEGER 0x8D96
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_BUFFER 0x82E0
+#define GL_BUFFER_ACCESS 0x88BB
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_BINDING 0x9302
+#define GL_BUFFER_DATA_SIZE 0x9303
+#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_STORAGE_FLAGS 0x8220
+#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
+#define GL_BUFFER_USAGE 0x8765
+#define GL_BUFFER_VARIABLE 0x92E5
+#define GL_BYTE 0x1400
+#define GL_CAVEAT_SUPPORT 0x82B8
+#define GL_CCW 0x0901
+#define GL_CLAMP_READ_COLOR 0x891C
+#define GL_CLAMP_TO_BORDER 0x812D
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_CLEAR 0x1500
+#define GL_CLEAR_BUFFER 0x82B4
+#define GL_CLEAR_TEXTURE 0x9365
+#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000
+#define GL_CLIENT_STORAGE_BIT 0x0200
+#define GL_CLIP_DEPTH_MODE 0x935D
+#define GL_CLIP_DISTANCE0 0x3000
+#define GL_CLIP_DISTANCE1 0x3001
+#define GL_CLIP_DISTANCE2 0x3002
+#define GL_CLIP_DISTANCE3 0x3003
+#define GL_CLIP_DISTANCE4 0x3004
+#define GL_CLIP_DISTANCE5 0x3005
+#define GL_CLIP_DISTANCE6 0x3006
+#define GL_CLIP_DISTANCE7 0x3007
+#define GL_CLIP_ORIGIN 0x935C
+#define GL_COLOR 0x1800
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_COLOR_ATTACHMENT16 0x8CF0
+#define GL_COLOR_ATTACHMENT17 0x8CF1
+#define GL_COLOR_ATTACHMENT18 0x8CF2
+#define GL_COLOR_ATTACHMENT19 0x8CF3
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT20 0x8CF4
+#define GL_COLOR_ATTACHMENT21 0x8CF5
+#define GL_COLOR_ATTACHMENT22 0x8CF6
+#define GL_COLOR_ATTACHMENT23 0x8CF7
+#define GL_COLOR_ATTACHMENT24 0x8CF8
+#define GL_COLOR_ATTACHMENT25 0x8CF9
+#define GL_COLOR_ATTACHMENT26 0x8CFA
+#define GL_COLOR_ATTACHMENT27 0x8CFB
+#define GL_COLOR_ATTACHMENT28 0x8CFC
+#define GL_COLOR_ATTACHMENT29 0x8CFD
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT30 0x8CFE
+#define GL_COLOR_ATTACHMENT31 0x8CFF
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_COMPONENTS 0x8283
+#define GL_COLOR_ENCODING 0x8296
+#define GL_COLOR_LOGIC_OP 0x0BF2
+#define GL_COLOR_RENDERABLE 0x8286
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_COMMAND_BARRIER_BIT 0x00000040
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_COMPATIBLE_SUBROUTINES 0x8E4B
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_RED 0x8225
+#define GL_COMPRESSED_RED_RGTC1 0x8DBB
+#define GL_COMPRESSED_RG 0x8226
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
+#define GL_COMPRESSED_RG_RGTC2 0x8DBD
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
+#define GL_COMPRESSED_SRGB 0x8C48
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_COMPUTE_SHADER 0x91B9
+#define GL_COMPUTE_SHADER_BIT 0x00000020
+#define GL_COMPUTE_SUBROUTINE 0x92ED
+#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3
+#define GL_COMPUTE_TEXTURE 0x82A0
+#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004
+#define GL_CONTEXT_LOST 0x0507
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB
+#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC
+#define GL_COPY 0x1503
+#define GL_COPY_INVERTED 0x150C
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_READ_BUFFER_BINDING 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
+#define GL_CULL_FACE 0x0B44
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_CURRENT_QUERY 0x8865
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_CW 0x0900
+#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
+#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
+#define GL_DEBUG_LOGGED_MESSAGES 0x9145
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
+#define GL_DEBUG_OUTPUT 0x92E0
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_DEBUG_SEVERITY_HIGH 0x9146
+#define GL_DEBUG_SEVERITY_LOW 0x9148
+#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
+#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
+#define GL_DEBUG_SOURCE_API 0x8246
+#define GL_DEBUG_SOURCE_APPLICATION 0x824A
+#define GL_DEBUG_SOURCE_OTHER 0x824B
+#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_TYPE_MARKER 0x8268
+#define GL_DEBUG_TYPE_OTHER 0x8251
+#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
+#define GL_DEBUG_TYPE_POP_GROUP 0x826A
+#define GL_DEBUG_TYPE_PORTABILITY 0x824F
+#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
+#define GL_DECR 0x1E03
+#define GL_DECR_WRAP 0x8508
+#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581
+#define GL_DELETE_STATUS 0x8B80
+#define GL_DEPTH 0x1801
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_DEPTH_CLAMP 0x864F
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_DEPTH_COMPONENT32 0x81A7
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH_COMPONENTS 0x8284
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_RENDERABLE 0x8287
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA
+#define GL_DEPTH_TEST 0x0B71
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEVICE_UUID_EXT 0x9597
+#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
+#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
+#define GL_DITHER 0x0BD0
+#define GL_DONT_CARE 0x1100
+#define GL_DOUBLE 0x140A
+#define GL_DOUBLEBUFFER 0x0C32
+#define GL_DOUBLE_MAT2 0x8F46
+#define GL_DOUBLE_MAT2x3 0x8F49
+#define GL_DOUBLE_MAT2x4 0x8F4A
+#define GL_DOUBLE_MAT3 0x8F47
+#define GL_DOUBLE_MAT3x2 0x8F4B
+#define GL_DOUBLE_MAT3x4 0x8F4C
+#define GL_DOUBLE_MAT4 0x8F48
+#define GL_DOUBLE_MAT4x2 0x8F4D
+#define GL_DOUBLE_MAT4x3 0x8F4E
+#define GL_DOUBLE_VEC2 0x8FFC
+#define GL_DOUBLE_VEC3 0x8FFD
+#define GL_DOUBLE_VEC4 0x8FFE
+#define GL_DRAW_BUFFER 0x0C01
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+#define GL_DRIVER_UUID_EXT 0x9598
+#define GL_DST_ALPHA 0x0304
+#define GL_DST_COLOR 0x0306
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_STORAGE_BIT 0x0100
+#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_EQUAL 0x0202
+#define GL_EQUIV 0x1509
+#define GL_EXTENSIONS 0x1F03
+#define GL_FALSE 0
+#define GL_FASTEST 0x1101
+#define GL_FILL 0x1B02
+#define GL_FILTER 0x829A
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_FIXED 0x140C
+#define GL_FIXED_ONLY 0x891D
+#define GL_FLOAT 0x1406
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_FRACTIONAL_EVEN 0x8E7C
+#define GL_FRACTIONAL_ODD 0x8E7B
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_FRAGMENT_SUBROUTINE 0x92EC
+#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2
+#define GL_FRAGMENT_TEXTURE 0x829F
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_FRAMEBUFFER_BLEND 0x828B
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314
+#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312
+#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313
+#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_RENDERABLE 0x8289
+#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_FRONT 0x0404
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_FRONT_FACE 0x0B46
+#define GL_FRONT_LEFT 0x0400
+#define GL_FRONT_RIGHT 0x0401
+#define GL_FULL_SUPPORT 0x82B7
+#define GL_FUNC_ADD 0x8006
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_GEOMETRY_SHADER_BIT 0x00000004
+#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+#define GL_GEOMETRY_SUBROUTINE 0x92EB
+#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1
+#define GL_GEOMETRY_TEXTURE 0x829E
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_GEQUAL 0x0206
+#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291
+#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292
+#define GL_GREATER 0x0204
+#define GL_GREEN 0x1904
+#define GL_GREEN_INTEGER 0x8D95
+#define GL_GUILTY_CONTEXT_RESET 0x8253
+#define GL_HALF_FLOAT 0x140B
+#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_HIGH_INT 0x8DF5
+#define GL_IMAGE_1D 0x904C
+#define GL_IMAGE_1D_ARRAY 0x9052
+#define GL_IMAGE_2D 0x904D
+#define GL_IMAGE_2D_ARRAY 0x9053
+#define GL_IMAGE_2D_MULTISAMPLE 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056
+#define GL_IMAGE_2D_RECT 0x904F
+#define GL_IMAGE_3D 0x904E
+#define GL_IMAGE_BINDING_ACCESS 0x8F3E
+#define GL_IMAGE_BINDING_FORMAT 0x906E
+#define GL_IMAGE_BINDING_LAYER 0x8F3D
+#define GL_IMAGE_BINDING_LAYERED 0x8F3C
+#define GL_IMAGE_BINDING_LEVEL 0x8F3B
+#define GL_IMAGE_BINDING_NAME 0x8F3A
+#define GL_IMAGE_BUFFER 0x9051
+#define GL_IMAGE_CLASS_10_10_10_2 0x82C3
+#define GL_IMAGE_CLASS_11_11_10 0x82C2
+#define GL_IMAGE_CLASS_1_X_16 0x82BE
+#define GL_IMAGE_CLASS_1_X_32 0x82BB
+#define GL_IMAGE_CLASS_1_X_8 0x82C1
+#define GL_IMAGE_CLASS_2_X_16 0x82BD
+#define GL_IMAGE_CLASS_2_X_32 0x82BA
+#define GL_IMAGE_CLASS_2_X_8 0x82C0
+#define GL_IMAGE_CLASS_4_X_16 0x82BC
+#define GL_IMAGE_CLASS_4_X_32 0x82B9
+#define GL_IMAGE_CLASS_4_X_8 0x82BF
+#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8
+#define GL_IMAGE_CUBE 0x9050
+#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
+#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
+#define GL_IMAGE_PIXEL_FORMAT 0x82A9
+#define GL_IMAGE_PIXEL_TYPE 0x82AA
+#define GL_IMAGE_TEXEL_SIZE 0x82A7
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_INCR 0x1E02
+#define GL_INCR_WRAP 0x8507
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_INNOCENT_CONTEXT_RESET 0x8254
+#define GL_INT 0x1404
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274
+#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B
+#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273
+#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A
+#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275
+#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C
+#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272
+#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279
+#define GL_INTERNALFORMAT_PREFERRED 0x8270
+#define GL_INTERNALFORMAT_RED_SIZE 0x8271
+#define GL_INTERNALFORMAT_RED_TYPE 0x8278
+#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277
+#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276
+#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D
+#define GL_INTERNALFORMAT_SUPPORTED 0x826F
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#define GL_INT_IMAGE_1D 0x9057
+#define GL_INT_IMAGE_1D_ARRAY 0x905D
+#define GL_INT_IMAGE_2D 0x9058
+#define GL_INT_IMAGE_2D_ARRAY 0x905E
+#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
+#define GL_INT_IMAGE_2D_RECT 0x905A
+#define GL_INT_IMAGE_3D 0x9059
+#define GL_INT_IMAGE_BUFFER 0x905C
+#define GL_INT_IMAGE_CUBE 0x905B
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
+#define GL_INT_SAMPLER_1D 0x8DC9
+#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_INT_SAMPLER_2D_RECT 0x8DCD
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_BUFFER 0x8DD0
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#define GL_INVALID_INDEX 0xFFFFFFFF
+#define GL_INVALID_OPERATION 0x0502
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVERT 0x150A
+#define GL_ISOLINES 0x8E7A
+#define GL_IS_PER_PATCH 0x92E7
+#define GL_IS_ROW_MAJOR 0x9300
+#define GL_KEEP 0x1E00
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_LAYER_PROVOKING_VERTEX 0x825E
+#define GL_LEFT 0x0406
+#define GL_LEQUAL 0x0203
+#define GL_LESS 0x0201
+#define GL_LINE 0x1B01
+#define GL_LINEAR 0x2601
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_LINEAR_TILING_EXT 0x9585
+#define GL_LINES 0x0001
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_SMOOTH 0x0B20
+#define GL_LINE_SMOOTH_HINT 0x0C52
+#define GL_LINE_STRIP 0x0003
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_LINE_WIDTH 0x0B21
+#define GL_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_LINE_WIDTH_RANGE 0x0B22
+#define GL_LINK_STATUS 0x8B82
+#define GL_LOCATION 0x930E
+#define GL_LOCATION_COMPONENT 0x934A
+#define GL_LOCATION_INDEX 0x930F
+#define GL_LOGIC_OP_MODE 0x0BF0
+#define GL_LOSE_CONTEXT_ON_RESET 0x8252
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_LOW_INT 0x8DF3
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MANUAL_GENERATE_MIPMAP 0x8294
+#define GL_MAP_COHERENT_BIT 0x0080
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_PERSISTENT_BIT 0x0040
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MATRIX_STRIDE 0x92FF
+#define GL_MAX 0x8008
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8
+#define GL_MAX_CLIP_DISTANCES 0x0D32
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7
+#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1
+#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA
+#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
+#define GL_MAX_COMBINED_DIMENSIONS 0x8282
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
+#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
+#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39
+#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
+#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
+#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
+#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB
+#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
+#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
+#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
+#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
+#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
+#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB
+#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_MAX_CULL_DISTANCES 0x82F9
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
+#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
+#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
+#define GL_MAX_DEPTH 0x8280
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0
+#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
+#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317
+#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
+#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_HEIGHT 0x827F
+#define GL_MAX_IMAGE_SAMPLES 0x906D
+#define GL_MAX_IMAGE_UNITS 0x8F38
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+#define GL_MAX_LABEL_LENGTH 0x82E8
+#define GL_MAX_LAYERS 0x8281
+#define GL_MAX_NAME_LENGTH 0x92F6
+#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
+#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8
+#define GL_MAX_PATCH_VERTICES 0x8E7D
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_MAX_SAMPLES 0x8D57
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
+#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
+#define GL_MAX_SUBROUTINES 0x8DE7
+#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define GL_MAX_TESS_GEN_LEVEL 0x8E7E
+#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84
+#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_LOCATIONS 0x826E
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2
+#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA
+#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9
+#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5
+#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6
+#define GL_MAX_VERTEX_STREAMS 0x8E71
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VIEWPORTS 0x825B
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_MAX_WIDTH 0x827E
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_MIN 0x8007
+#define GL_MINOR_VERSION 0x821C
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#define GL_MIPMAP 0x8293
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_MIRROR_CLAMP_TO_EDGE 0x8743
+#define GL_MULTISAMPLE 0x809D
+#define GL_NAME_LENGTH 0x92F9
+#define GL_NAND 0x150E
+#define GL_NEAREST 0x2600
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_NEGATIVE_ONE_TO_ONE 0x935E
+#define GL_NEVER 0x0200
+#define GL_NICEST 0x1102
+#define GL_NONE 0
+#define GL_NOOP 0x1505
+#define GL_NOR 0x1508
+#define GL_NOTEQUAL 0x0205
+#define GL_NO_ERROR 0
+#define GL_NO_RESET_NOTIFICATION 0x8261
+#define GL_NUM_ACTIVE_VARIABLES 0x9304
+#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_NUM_DEVICE_UUIDS_EXT 0x9596
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9
+#define GL_NUM_TILING_TYPES_EXT 0x9582
+#define GL_OBJECT_TYPE 0x9112
+#define GL_OFFSET 0x92FC
+#define GL_ONE 1
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB
+#define GL_ONE_MINUS_SRC1_COLOR 0x88FA
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_OPTIMAL_TILING_EXT 0x9584
+#define GL_OR 0x1507
+#define GL_OR_INVERTED 0x150D
+#define GL_OR_REVERSE 0x150B
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D
+#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C
+#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E
+#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_PACK_LSB_FIRST 0x0D01
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SWAP_BYTES 0x0D00
+#define GL_PATCHES 0x000E
+#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
+#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74
+#define GL_PATCH_VERTICES 0x8E72
+#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_POINT 0x1B00
+#define GL_POINTS 0x0000
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_POINT_SIZE 0x0B11
+#define GL_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_POINT_SIZE_RANGE 0x0B12
+#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define GL_POLYGON_MODE 0x0B40
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_POLYGON_OFFSET_LINE 0x2A02
+#define GL_POLYGON_OFFSET_POINT 0x2A01
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_SMOOTH 0x0B41
+#define GL_POLYGON_SMOOTH_HINT 0x0C53
+#define GL_PRIMITIVES_GENERATED 0x8C87
+#define GL_PRIMITIVE_RESTART 0x8F9D
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221
+#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E
+#define GL_PROGRAM 0x82E2
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_INPUT 0x92E3
+#define GL_PROGRAM_OUTPUT 0x92E4
+#define GL_PROGRAM_PIPELINE 0x82E4
+#define GL_PROGRAM_PIPELINE_BINDING 0x825A
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#define GL_PROGRAM_SEPARABLE 0x8258
+#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B
+#define GL_PROVOKING_VERTEX 0x8E4F
+#define GL_PROXY_TEXTURE_1D 0x8063
+#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19
+#define GL_PROXY_TEXTURE_2D 0x8064
+#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
+#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#define GL_QUADS 0x0007
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_QUERY 0x82E3
+#define GL_QUERY_BUFFER 0x9192
+#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000
+#define GL_QUERY_BUFFER_BINDING 0x9193
+#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16
+#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A
+#define GL_QUERY_BY_REGION_WAIT 0x8E15
+#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19
+#define GL_QUERY_COUNTER_BITS 0x8864
+#define GL_QUERY_NO_WAIT 0x8E14
+#define GL_QUERY_NO_WAIT_INVERTED 0x8E18
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_QUERY_RESULT_NO_WAIT 0x9194
+#define GL_QUERY_TARGET 0x82EA
+#define GL_QUERY_WAIT 0x8E13
+#define GL_QUERY_WAIT_INVERTED 0x8E17
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_R16 0x822A
+#define GL_R16F 0x822D
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R16_SNORM 0x8F98
+#define GL_R32F 0x822E
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_R3_G3_B2 0x2A10
+#define GL_R8 0x8229
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R8_SNORM 0x8F94
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_READ_BUFFER 0x0C02
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_READ_ONLY 0x88B8
+#define GL_READ_PIXELS 0x828C
+#define GL_READ_PIXELS_FORMAT 0x828D
+#define GL_READ_PIXELS_TYPE 0x828E
+#define GL_READ_WRITE 0x88BA
+#define GL_RED 0x1903
+#define GL_RED_INTEGER 0x8D94
+#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B
+#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A
+#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308
+#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERER 0x1F01
+#define GL_REPEAT 0x2901
+#define GL_REPLACE 0x1E01
+#define GL_RESET_NOTIFICATION_STRATEGY 0x8256
+#define GL_RG 0x8227
+#define GL_RG16 0x822C
+#define GL_RG16F 0x822F
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG16_SNORM 0x8F99
+#define GL_RG32F 0x8230
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#define GL_RG8 0x822B
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB 0x1907
+#define GL_RGB10 0x8052
+#define GL_RGB10_A2 0x8059
+#define GL_RGB10_A2UI 0x906F
+#define GL_RGB12 0x8053
+#define GL_RGB16 0x8054
+#define GL_RGB16F 0x881B
+#define GL_RGB16I 0x8D89
+#define GL_RGB16UI 0x8D77
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGB32F 0x8815
+#define GL_RGB32I 0x8D83
+#define GL_RGB32UI 0x8D71
+#define GL_RGB4 0x804F
+#define GL_RGB5 0x8050
+#define GL_RGB565 0x8D62
+#define GL_RGB5_A1 0x8057
+#define GL_RGB8 0x8051
+#define GL_RGB8I 0x8D8F
+#define GL_RGB8UI 0x8D7D
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGB9_E5 0x8C3D
+#define GL_RGBA 0x1908
+#define GL_RGBA12 0x805A
+#define GL_RGBA16 0x805B
+#define GL_RGBA16F 0x881A
+#define GL_RGBA16I 0x8D88
+#define GL_RGBA16UI 0x8D76
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_RGBA2 0x8055
+#define GL_RGBA32F 0x8814
+#define GL_RGBA32I 0x8D82
+#define GL_RGBA32UI 0x8D70
+#define GL_RGBA4 0x8056
+#define GL_RGBA8 0x8058
+#define GL_RGBA8I 0x8D8E
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RG_INTEGER 0x8228
+#define GL_RIGHT 0x0407
+#define GL_SAMPLER 0x82E6
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_1D_ARRAY 0x8DC0
+#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
+#define GL_SAMPLER_1D_SHADOW 0x8B61
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_SAMPLER_2D_RECT 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_BINDING 0x8919
+#define GL_SAMPLER_BUFFER 0x8DC2
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLES_PASSED 0x8914
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SAMPLE_SHADING 0x8C36
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_SET 0x150F
+#define GL_SHADER 0x82E1
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#define GL_SHADER_IMAGE_ATOMIC 0x82A6
+#define GL_SHADER_IMAGE_LOAD 0x82A4
+#define GL_SHADER_IMAGE_STORE 0x82A5
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
+#define GL_SHADER_STORAGE_BLOCK 0x92E6
+#define GL_SHADER_STORAGE_BUFFER 0x90D2
+#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3
+#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
+#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5
+#define GL_SHADER_STORAGE_BUFFER_START 0x90D4
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_SHORT 0x1402
+#define GL_SIGNALED 0x9119
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_SRC1_ALPHA 0x8589
+#define GL_SRC1_COLOR 0x88F9
+#define GL_SRC_ALPHA 0x0302
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_SRC_COLOR 0x0300
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_SRGB_ALPHA 0x8C42
+#define GL_SRGB_READ 0x8297
+#define GL_SRGB_WRITE 0x8298
+#define GL_STACK_OVERFLOW 0x0503
+#define GL_STACK_UNDERFLOW 0x0504
+#define GL_STATIC_COPY 0x88E6
+#define GL_STATIC_DRAW 0x88E4
+#define GL_STATIC_READ 0x88E5
+#define GL_STENCIL 0x1802
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_COMPONENTS 0x8285
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_INDEX 0x1901
+#define GL_STENCIL_INDEX1 0x8D46
+#define GL_STENCIL_INDEX16 0x8D49
+#define GL_STENCIL_INDEX4 0x8D47
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_RENDERABLE 0x8288
+#define GL_STENCIL_TEST 0x0B90
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STEREO 0x0C33
+#define GL_STREAM_COPY 0x88E2
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STREAM_READ 0x88E1
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_SYNC_STATUS 0x9114
+#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75
+#define GL_TESS_CONTROL_SHADER 0x8E88
+#define GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#define GL_TESS_CONTROL_SUBROUTINE 0x92E9
+#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF
+#define GL_TESS_CONTROL_TEXTURE 0x829C
+#define GL_TESS_EVALUATION_SHADER 0x8E87
+#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA
+#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0
+#define GL_TESS_EVALUATION_TEXTURE 0x829D
+#define GL_TESS_GEN_MODE 0x8E76
+#define GL_TESS_GEN_POINT_MODE 0x8E79
+#define GL_TESS_GEN_SPACING 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER 0x8E78
+#define GL_TEXTURE 0x1702
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE_1D 0x0DE0
+#define GL_TEXTURE_1D_ARRAY 0x8C18
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_ALPHA_SIZE 0x805F
+#define GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_BINDING_1D 0x8068
+#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#define GL_TEXTURE_BLUE_SIZE 0x805E
+#define GL_TEXTURE_BLUE_TYPE 0x8C12
+#define GL_TEXTURE_BORDER_COLOR 0x1004
+#define GL_TEXTURE_BUFFER 0x8C2A
+#define GL_TEXTURE_BUFFER_BINDING 0x8C2A
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_BUFFER_OFFSET 0x919D
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F
+#define GL_TEXTURE_BUFFER_SIZE 0x919E
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2
+#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3
+#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_TEXTURE_GATHER 0x82A2
+#define GL_TEXTURE_GATHER_SHADOW 0x82A3
+#define GL_TEXTURE_GREEN_SIZE 0x805D
+#define GL_TEXTURE_GREEN_TYPE 0x8C11
+#define GL_TEXTURE_HEIGHT 0x1001
+#define GL_TEXTURE_IMAGE_FORMAT 0x828F
+#define GL_TEXTURE_IMAGE_TYPE 0x8290
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
+#define GL_TEXTURE_LOD_BIAS 0x8501
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#define GL_TEXTURE_RED_SIZE 0x805C
+#define GL_TEXTURE_RED_TYPE 0x8C10
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TEXTURE_SHADOW 0x82A1
+#define GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#define GL_TEXTURE_TARGET 0x1006
+#define GL_TEXTURE_TILING_EXT 0x9580
+#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
+#define GL_TEXTURE_VIEW 0x82B5
+#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD
+#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE
+#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC
+#define GL_TEXTURE_WIDTH 0x1000
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_TILING_TYPES_EXT 0x9583
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF
+#define GL_TIMESTAMP 0x8E28
+#define GL_TIME_ELAPSED 0x88BF
+#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C
+#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_TRUE 1
+#define GL_TYPE 0x92FA
+#define GL_UNDEFINED_VERTEX 0x8260
+#define GL_UNIFORM 0x92E1
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA
+#define GL_UNIFORM_BARRIER_BIT 0x00000004
+#define GL_UNIFORM_BLOCK 0x92E2
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNKNOWN_CONTEXT_RESET 0x8255
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129
+#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128
+#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A
+#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_UNPACK_LSB_FIRST 0x0CF1
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SWAP_BYTES 0x0CF0
+#define GL_UNSIGNALED 0x9118
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_INT 0x1405
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#define GL_UNSIGNED_INT_IMAGE_1D 0x9062
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_3D 0x9064
+#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
+#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
+#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_UUID_SIZE_EXT 16
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_VENDOR 0x1F00
+#define GL_VERSION 0x1F02
+#define GL_VERTEX_ARRAY 0x8074
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_ATTRIB_BINDING 0x82D4
+#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
+#define GL_VERTEX_BINDING_BUFFER 0x8F4F
+#define GL_VERTEX_BINDING_DIVISOR 0x82D6
+#define GL_VERTEX_BINDING_OFFSET 0x82D7
+#define GL_VERTEX_BINDING_STRIDE 0x82D8
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#define GL_VERTEX_SUBROUTINE 0x92E8
+#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE
+#define GL_VERTEX_TEXTURE 0x829B
+#define GL_VIEWPORT 0x0BA2
+#define GL_VIEWPORT_BOUNDS_RANGE 0x825D
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F
+#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C
+#define GL_VIEW_CLASS_128_BITS 0x82C4
+#define GL_VIEW_CLASS_16_BITS 0x82CA
+#define GL_VIEW_CLASS_24_BITS 0x82C9
+#define GL_VIEW_CLASS_32_BITS 0x82C8
+#define GL_VIEW_CLASS_48_BITS 0x82C7
+#define GL_VIEW_CLASS_64_BITS 0x82C6
+#define GL_VIEW_CLASS_8_BITS 0x82CB
+#define GL_VIEW_CLASS_96_BITS 0x82C5
+#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3
+#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2
+#define GL_VIEW_CLASS_RGTC1_RED 0x82D0
+#define GL_VIEW_CLASS_RGTC2_RG 0x82D1
+#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC
+#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD
+#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE
+#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF
+#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6
+#define GL_WAIT_FAILED 0x911D
+#define GL_WRITE_ONLY 0x88B9
+#define GL_XOR 0x1506
+#define GL_ZERO 0
+#define GL_ZERO_TO_ONE 0x935F
+
+
+#include
+#include
+#ifndef GLEXT_64_TYPES_DEFINED
+/* This code block is duplicated in glxext.h, so must be protected */
+#define GLEXT_64_TYPES_DEFINED
+/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
+/* (as used in the GL_EXT_timer_query extension). */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include
+#elif defined(__sun__) || defined(__digital__)
+#include
+#if defined(__STDC__)
+#if defined(__arch64__) || defined(_LP64)
+typedef long int int64_t;
+typedef unsigned long int uint64_t;
+#else
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#endif /* __arch64__ */
+#endif /* __STDC__ */
+#elif defined( __VMS ) || defined(__sgi)
+#include
+#elif defined(__SCO__) || defined(__USLC__)
+#include
+#elif defined(__UNIXOS2__) || defined(__SOL64__)
+typedef long int int32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#elif defined(_WIN32) && defined(__GNUC__)
+#include
+#elif defined(_WIN32)
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+/* Fallback if nothing above works */
+#include
+#endif
+#endif
+typedef unsigned int GLenum;
+typedef unsigned char GLboolean;
+typedef unsigned int GLbitfield;
+typedef void GLvoid;
+typedef signed char GLbyte;
+typedef short GLshort;
+typedef int GLint;
+typedef int GLclampx;
+typedef unsigned char GLubyte;
+typedef unsigned short GLushort;
+typedef unsigned int GLuint;
+typedef int GLsizei;
+typedef float GLfloat;
+typedef float GLclampf;
+typedef double GLdouble;
+typedef double GLclampd;
+typedef void *GLeglClientBufferEXT;
+typedef void *GLeglImageOES;
+typedef char GLchar;
+typedef char GLcharARB;
+#ifdef __APPLE__
+typedef void *GLhandleARB;
+#else
+typedef unsigned int GLhandleARB;
+#endif
+typedef unsigned short GLhalfARB;
+typedef unsigned short GLhalf;
+typedef GLint GLfixed;
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
+typedef khronos_intptr_t GLintptr;
+#else
+typedef khronos_intptr_t GLintptr;
+#endif
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
+typedef khronos_ssize_t GLsizeiptr;
+#else
+typedef khronos_ssize_t GLsizeiptr;
+#endif
+typedef int64_t GLint64;
+typedef uint64_t GLuint64;
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
+typedef long GLintptrARB;
+#else
+typedef ptrdiff_t GLintptrARB;
+#endif
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
+typedef long GLsizeiptrARB;
+#else
+typedef ptrdiff_t GLsizeiptrARB;
+#endif
+typedef int64_t GLint64EXT;
+typedef uint64_t GLuint64EXT;
+typedef struct __GLsync *GLsync;
+struct _cl_context;
+struct _cl_event;
+typedef void ( *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+typedef void ( *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+typedef void ( *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+typedef void ( *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
+typedef unsigned short GLhalfNV;
+typedef GLintptr GLvdpauSurfaceNV;
+typedef void ( *GLVULKANPROCNV)(void);
+
+
+#define GL_VERSION_1_0 1
+GLAD_API_CALL int GLAD_GL_VERSION_1_0;
+#define GL_VERSION_1_1 1
+GLAD_API_CALL int GLAD_GL_VERSION_1_1;
+#define GL_VERSION_1_2 1
+GLAD_API_CALL int GLAD_GL_VERSION_1_2;
+#define GL_VERSION_1_3 1
+GLAD_API_CALL int GLAD_GL_VERSION_1_3;
+#define GL_VERSION_1_4 1
+GLAD_API_CALL int GLAD_GL_VERSION_1_4;
+#define GL_VERSION_1_5 1
+GLAD_API_CALL int GLAD_GL_VERSION_1_5;
+#define GL_VERSION_2_0 1
+GLAD_API_CALL int GLAD_GL_VERSION_2_0;
+#define GL_VERSION_2_1 1
+GLAD_API_CALL int GLAD_GL_VERSION_2_1;
+#define GL_VERSION_3_0 1
+GLAD_API_CALL int GLAD_GL_VERSION_3_0;
+#define GL_VERSION_3_1 1
+GLAD_API_CALL int GLAD_GL_VERSION_3_1;
+#define GL_VERSION_3_2 1
+GLAD_API_CALL int GLAD_GL_VERSION_3_2;
+#define GL_VERSION_3_3 1
+GLAD_API_CALL int GLAD_GL_VERSION_3_3;
+#define GL_VERSION_4_0 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_0;
+#define GL_VERSION_4_1 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_1;
+#define GL_VERSION_4_2 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_2;
+#define GL_VERSION_4_3 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_3;
+#define GL_VERSION_4_4 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_4;
+#define GL_VERSION_4_5 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_5;
+#define GL_EXT_memory_object 1
+GLAD_API_CALL int GLAD_GL_EXT_memory_object;
+#define GL_EXT_memory_object_fd 1
+GLAD_API_CALL int GLAD_GL_EXT_memory_object_fd;
+
+
+typedef void (GLAD_API_PTR *PFNGLACTIVESHADERPROGRAMPROC)(GLuint pipeline, GLuint program);
+typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture);
+typedef void (GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader);
+typedef void (GLAD_API_PTR *PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLBEGINQUERYPROC)(GLenum target, GLuint id);
+typedef void (GLAD_API_PTR *PFNGLBEGINQUERYINDEXEDPROC)(GLenum target, GLuint index, GLuint id);
+typedef void (GLAD_API_PTR *PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode);
+typedef void (GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAD_API_PTR *PFNGLBINDBUFFERSBASEPROC)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers);
+typedef void (GLAD_API_PTR *PFNGLBINDBUFFERSRANGEPROC)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizeiptr * sizes);
+typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONPROC)(GLuint program, GLuint color, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer);
+typedef void (GLAD_API_PTR *PFNGLBINDIMAGETEXTUREPROC)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+typedef void (GLAD_API_PTR *PFNGLBINDIMAGETEXTURESPROC)(GLuint first, GLsizei count, const GLuint * textures);
+typedef void (GLAD_API_PTR *PFNGLBINDPROGRAMPIPELINEPROC)(GLuint pipeline);
+typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer);
+typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler);
+typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERSPROC)(GLuint first, GLsizei count, const GLuint * samplers);
+typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture);
+typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREUNITPROC)(GLuint unit, GLuint texture);
+typedef void (GLAD_API_PTR *PFNGLBINDTEXTURESPROC)(GLuint first, GLsizei count, const GLuint * textures);
+typedef void (GLAD_API_PTR *PFNGLBINDTRANSFORMFEEDBACKPROC)(GLenum target, GLuint id);
+typedef void (GLAD_API_PTR *PFNGLBINDVERTEXARRAYPROC)(GLuint array);
+typedef void (GLAD_API_PTR *PFNGLBINDVERTEXBUFFERPROC)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+typedef void (GLAD_API_PTR *PFNGLBINDVERTEXBUFFERSPROC)(GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides);
+typedef void (GLAD_API_PTR *PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONPROC)(GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEIPROC)(GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONIPROC)(GLuint buf, GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor);
+typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEIPROC)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GLAD_API_PTR *PFNGLBLENDFUNCIPROC)(GLuint buf, GLenum src, GLenum dst);
+typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (GLAD_API_PTR *PFNGLBLITNAMEDFRAMEBUFFERPROC)(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (GLAD_API_PTR *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void * data, GLenum usage);
+typedef void (GLAD_API_PTR *PFNGLBUFFERSTORAGEPROC)(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags);
+typedef void (GLAD_API_PTR *PFNGLBUFFERSTORAGEMEMEXTPROC)(GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset);
+typedef void (GLAD_API_PTR *PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void * data);
+typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target);
+typedef GLenum (GLAD_API_PTR *PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)(GLuint framebuffer, GLenum target);
+typedef void (GLAD_API_PTR *PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp);
+typedef void (GLAD_API_PTR *PFNGLCLEARPROC)(GLbitfield mask);
+typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERDATAPROC)(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERSUBDATAPROC)(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHPROC)(GLdouble depth);
+typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHFPROC)(GLfloat d);
+typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERDATAPROC)(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLCLEARSTENCILPROC)(GLint s);
+typedef void (GLAD_API_PTR *PFNGLCLEARTEXIMAGEPROC)(GLuint texture, GLint level, GLenum format, GLenum type, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCLEARTEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * data);
+typedef GLenum (GLAD_API_PTR *PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GLAD_API_PTR *PFNGLCLIPCONTROLPROC)(GLenum origin, GLenum depth);
+typedef void (GLAD_API_PTR *PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+typedef void (GLAD_API_PTR *PFNGLCOLORMASKIPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERPROC)(GLuint shader);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (GLAD_API_PTR *PFNGLCOPYIMAGESUBDATAPROC)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+typedef void (GLAD_API_PTR *PFNGLCOPYNAMEDBUFFERSUBDATAPROC)(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLCREATEBUFFERSPROC)(GLsizei n, GLuint * buffers);
+typedef void (GLAD_API_PTR *PFNGLCREATEFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers);
+typedef void (GLAD_API_PTR *PFNGLCREATEMEMORYOBJECTSEXTPROC)(GLsizei n, GLuint * memoryObjects);
+typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLCREATEPROGRAMPIPELINESPROC)(GLsizei n, GLuint * pipelines);
+typedef void (GLAD_API_PTR *PFNGLCREATEQUERIESPROC)(GLenum target, GLsizei n, GLuint * ids);
+typedef void (GLAD_API_PTR *PFNGLCREATERENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers);
+typedef void (GLAD_API_PTR *PFNGLCREATESAMPLERSPROC)(GLsizei n, GLuint * samplers);
+typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type);
+typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROGRAMVPROC)(GLenum type, GLsizei count, const GLchar *const* strings);
+typedef void (GLAD_API_PTR *PFNGLCREATETEXTURESPROC)(GLenum target, GLsizei n, GLuint * textures);
+typedef void (GLAD_API_PTR *PFNGLCREATETRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint * ids);
+typedef void (GLAD_API_PTR *PFNGLCREATEVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays);
+typedef void (GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECALLBACKPROC)(GLDEBUGPROC callback, const void * userParam);
+typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECONTROLPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled);
+typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGEINSERTPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf);
+typedef void (GLAD_API_PTR *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint * buffers);
+typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint * framebuffers);
+typedef void (GLAD_API_PTR *PFNGLDELETEMEMORYOBJECTSEXTPROC)(GLsizei n, const GLuint * memoryObjects);
+typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPROC)(GLuint program);
+typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPIPELINESPROC)(GLsizei n, const GLuint * pipelines);
+typedef void (GLAD_API_PTR *PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint * ids);
+typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint * renderbuffers);
+typedef void (GLAD_API_PTR *PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint * samplers);
+typedef void (GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader);
+typedef void (GLAD_API_PTR *PFNGLDELETESYNCPROC)(GLsync sync);
+typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint * textures);
+typedef void (GLAD_API_PTR *PFNGLDELETETRANSFORMFEEDBACKSPROC)(GLsizei n, const GLuint * ids);
+typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint * arrays);
+typedef void (GLAD_API_PTR *PFNGLDEPTHFUNCPROC)(GLenum func);
+typedef void (GLAD_API_PTR *PFNGLDEPTHMASKPROC)(GLboolean flag);
+typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEPROC)(GLdouble n, GLdouble f);
+typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEARRAYVPROC)(GLuint first, GLsizei count, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEINDEXEDPROC)(GLuint index, GLdouble n, GLdouble f);
+typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f);
+typedef void (GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader);
+typedef void (GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap);
+typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXARRAYATTRIBPROC)(GLuint vaobj, GLuint index);
+typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index);
+typedef void (GLAD_API_PTR *PFNGLDISABLEIPROC)(GLenum target, GLuint index);
+typedef void (GLAD_API_PTR *PFNGLDISPATCHCOMPUTEPROC)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+typedef void (GLAD_API_PTR *PFNGLDISPATCHCOMPUTEINDIRECTPROC)(GLintptr indirect);
+typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count);
+typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINDIRECTPROC)(GLenum mode, const void * indirect);
+typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
+typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERPROC)(GLenum buf);
+typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum * bufs);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLint basevertex);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void * indirect);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
+typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices);
+typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex);
+typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKPROC)(GLenum mode, GLuint id);
+typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)(GLenum mode, GLuint id, GLsizei instancecount);
+typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)(GLenum mode, GLuint id, GLuint stream);
+typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount);
+typedef void (GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap);
+typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXARRAYATTRIBPROC)(GLuint vaobj, GLuint index);
+typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index);
+typedef void (GLAD_API_PTR *PFNGLENABLEIPROC)(GLenum target, GLuint index);
+typedef void (GLAD_API_PTR *PFNGLENDCONDITIONALRENDERPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLENDQUERYPROC)(GLenum target);
+typedef void (GLAD_API_PTR *PFNGLENDQUERYINDEXEDPROC)(GLenum target, GLuint index);
+typedef void (GLAD_API_PTR *PFNGLENDTRANSFORMFEEDBACKPROC)(void);
+typedef GLsync (GLAD_API_PTR *PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags);
+typedef void (GLAD_API_PTR *PFNGLFINISHPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLFLUSHPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length);
+typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERPARAMETERIPROC)(GLenum target, GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (GLAD_API_PTR *PFNGLFRONTFACEPROC)(GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint * buffers);
+typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers);
+typedef void (GLAD_API_PTR *PFNGLGENPROGRAMPIPELINESPROC)(GLsizei n, GLuint * pipelines);
+typedef void (GLAD_API_PTR *PFNGLGENQUERIESPROC)(GLsizei n, GLuint * ids);
+typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers);
+typedef void (GLAD_API_PTR *PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint * samplers);
+typedef void (GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures);
+typedef void (GLAD_API_PTR *PFNGLGENTRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint * ids);
+typedef void (GLAD_API_PTR *PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays);
+typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPPROC)(GLenum target);
+typedef void (GLAD_API_PTR *PFNGLGENERATETEXTUREMIPMAPPROC)(GLuint texture);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)(GLuint program, GLuint bufferIndex, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINENAMEPROC)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei * length, GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei * length, GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint * values);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformBlockName);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformName);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders);
+typedef GLint (GLAD_API_PTR *PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean * data);
+typedef void (GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean * data);
+typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 * params);
+typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void ** params);
+typedef void (GLAD_API_PTR *PFNGLGETBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, void * data);
+typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void * img);
+typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)(GLuint texture, GLint level, GLsizei bufSize, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void * pixels);
+typedef GLuint (GLAD_API_PTR *PFNGLGETDEBUGMESSAGELOGPROC)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog);
+typedef void (GLAD_API_PTR *PFNGLGETDOUBLEI_VPROC)(GLenum target, GLuint index, GLdouble * data);
+typedef void (GLAD_API_PTR *PFNGLGETDOUBLEVPROC)(GLenum pname, GLdouble * data);
+typedef GLenum (GLAD_API_PTR *PFNGLGETERRORPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLGETFLOATI_VPROC)(GLenum target, GLuint index, GLfloat * data);
+typedef void (GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat * data);
+typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATAINDEXPROC)(GLuint program, const GLchar * name);
+typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params);
+typedef GLenum (GLAD_API_PTR *PFNGLGETGRAPHICSRESETSTATUSPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 * data);
+typedef void (GLAD_API_PTR *PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 * data);
+typedef void (GLAD_API_PTR *PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint * data);
+typedef void (GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint * data);
+typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATI64VPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 * params);
+typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATIVPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC)(GLuint memoryObject, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat * val);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)(GLuint buffer, GLenum pname, GLint64 * params);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERIVPROC)(GLuint buffer, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPOINTERVPROC)(GLuint buffer, GLenum pname, void ** params);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, void * data);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLuint framebuffer, GLenum attachment, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)(GLuint framebuffer, GLenum pname, GLint * param);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)(GLuint renderbuffer, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label);
+typedef void (GLAD_API_PTR *PFNGLGETOBJECTPTRLABELPROC)(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label);
+typedef void (GLAD_API_PTR *PFNGLGETPOINTERVPROC)(GLenum pname, void ** params);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMBINARYPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLenum * binaryFormat, void * binary);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINTERFACEIVPROC)(GLuint program, GLenum programInterface, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEINFOLOGPROC)(GLuint pipeline, GLsizei bufSize, GLsizei * length, GLchar * infoLog);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEIVPROC)(GLuint pipeline, GLenum pname, GLint * params);
+typedef GLuint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEINDEXPROC)(GLuint program, GLenum programInterface, const GLchar * name);
+typedef GLint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONPROC)(GLuint program, GLenum programInterface, const GLchar * name);
+typedef GLint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)(GLuint program, GLenum programInterface, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCENAMEPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEIVPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMSTAGEIVPROC)(GLuint program, GLenum shadertype, GLenum pname, GLint * values);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTI64VPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTIVPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTUI64VPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTUIVPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYINDEXEDIVPROC)(GLenum target, GLuint index, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64 * params);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64 * params);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog);
+typedef void (GLAD_API_PTR *PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision);
+typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source);
+typedef void (GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint * params);
+typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name);
+typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGIPROC)(GLenum name, GLuint index);
+typedef GLuint (GLAD_API_PTR *PFNGLGETSUBROUTINEINDEXPROC)(GLuint program, GLenum shadertype, const GLchar * name);
+typedef GLint (GLAD_API_PTR *PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)(GLuint program, GLenum shadertype, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei * length, GLint * values);
+typedef void (GLAD_API_PTR *PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTUREIMAGEPROC)(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERFVPROC)(GLuint texture, GLint level, GLenum pname, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERIVPROC)(GLuint texture, GLint level, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIIVPROC)(GLuint texture, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIUIVPROC)(GLuint texture, GLenum pname, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERFVPROC)(GLuint texture, GLenum pname, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIVPROC)(GLuint texture, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTURESUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKI64_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint64 * param);
+typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKI_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint * param);
+typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKIVPROC)(GLuint xfb, GLenum pname, GLint * param);
+typedef GLuint (GLAD_API_PTR *PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar * uniformBlockName);
+typedef void (GLAD_API_PTR *PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint * uniformIndices);
+typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETUNIFORMSUBROUTINEUIVPROC)(GLenum shadertype, GLint location, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETUNIFORMDVPROC)(GLuint program, GLint location, GLdouble * params);
+typedef void (GLAD_API_PTR *PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETUNSIGNEDBYTEI_VEXTPROC)(GLenum target, GLuint index, GLubyte * data);
+typedef void (GLAD_API_PTR *PFNGLGETUNSIGNEDBYTEVEXTPROC)(GLenum pname, GLubyte * data);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYINDEXED64IVPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint64 * param);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYINDEXEDIVPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint * param);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYIVPROC)(GLuint vaobj, GLenum pname, GLint * param);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBLDVPROC)(GLuint index, GLenum pname, GLdouble * params);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void ** pointer);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble * params);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETNCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint lod, GLsizei bufSize, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLGETNTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMDVPROC)(GLuint program, GLint location, GLsizei bufSize, GLdouble * params);
+typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMFVPROC)(GLuint program, GLint location, GLsizei bufSize, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMIVPROC)(GLuint program, GLint location, GLsizei bufSize, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMUIVPROC)(GLuint program, GLint location, GLsizei bufSize, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLHINTPROC)(GLenum target, GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLIMPORTMEMORYFDEXTPROC)(GLuint memory, GLuint64 size, GLenum handleType, GLint fd);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATEBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATETEXIMAGEPROC)(GLuint texture, GLint level);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATETEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
+typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer);
+typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap);
+typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDIPROC)(GLenum target, GLuint index);
+typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer);
+typedef GLboolean (GLAD_API_PTR *PFNGLISMEMORYOBJECTEXTPROC)(GLuint memoryObject);
+typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPROC)(GLuint program);
+typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPIPELINEPROC)(GLuint pipeline);
+typedef GLboolean (GLAD_API_PTR *PFNGLISQUERYPROC)(GLuint id);
+typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer);
+typedef GLboolean (GLAD_API_PTR *PFNGLISSAMPLERPROC)(GLuint sampler);
+typedef GLboolean (GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader);
+typedef GLboolean (GLAD_API_PTR *PFNGLISSYNCPROC)(GLsync sync);
+typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture);
+typedef GLboolean (GLAD_API_PTR *PFNGLISTRANSFORMFEEDBACKPROC)(GLuint id);
+typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXARRAYPROC)(GLuint array);
+typedef void (GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width);
+typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program);
+typedef void (GLAD_API_PTR *PFNGLLOGICOPPROC)(GLenum opcode);
+typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERPROC)(GLenum target, GLenum access);
+typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void * (GLAD_API_PTR *PFNGLMAPNAMEDBUFFERPROC)(GLuint buffer, GLenum access);
+typedef void * (GLAD_API_PTR *PFNGLMAPNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIERPROC)(GLbitfield barriers);
+typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIERBYREGIONPROC)(GLbitfield barriers);
+typedef void (GLAD_API_PTR *PFNGLMEMORYOBJECTPARAMETERIVEXTPROC)(GLuint memoryObject, GLenum pname, const GLint * params);
+typedef void (GLAD_API_PTR *PFNGLMINSAMPLESHADINGPROC)(GLfloat value);
+typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSPROC)(GLenum mode, const GLint * first, const GLsizei * count, GLsizei drawcount);
+typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTPROC)(GLenum mode, const void * indirect, GLsizei drawcount, GLsizei stride);
+typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount);
+typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount, const GLint * basevertex);
+typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void * indirect, GLsizei drawcount, GLsizei stride);
+typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERDATAPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLenum usage);
+typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSTORAGEPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLbitfield flags);
+typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC)(GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset);
+typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)(GLuint framebuffer, GLenum buf);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)(GLuint framebuffer, GLsizei n, const GLenum * bufs);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)(GLuint framebuffer, GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)(GLuint framebuffer, GLenum src);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEPROC)(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar * label);
+typedef void (GLAD_API_PTR *PFNGLOBJECTPTRLABELPROC)(const void * ptr, GLsizei length, const GLchar * label);
+typedef void (GLAD_API_PTR *PFNGLPATCHPARAMETERFVPROC)(GLenum pname, const GLfloat * values);
+typedef void (GLAD_API_PTR *PFNGLPATCHPARAMETERIPROC)(GLenum pname, GLint value);
+typedef void (GLAD_API_PTR *PFNGLPAUSETRANSFORMFEEDBACKPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLPIXELSTOREFPROC)(GLenum pname, GLfloat param);
+typedef void (GLAD_API_PTR *PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param);
+typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint * params);
+typedef void (GLAD_API_PTR *PFNGLPOINTSIZEPROC)(GLfloat size);
+typedef void (GLAD_API_PTR *PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units);
+typedef void (GLAD_API_PTR *PFNGLPOPDEBUGGROUPPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMBINARYPROC)(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETERIPROC)(GLuint program, GLenum pname, GLint value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DPROC)(GLuint program, GLint location, GLdouble v0);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FPROC)(GLuint program, GLint location, GLfloat v0);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IPROC)(GLuint program, GLint location, GLint v0);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIPROC)(GLuint program, GLint location, GLuint v0);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IPROC)(GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROVOKINGVERTEXPROC)(GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLPUSHDEBUGGROUPPROC)(GLenum source, GLuint id, GLsizei length, const GLchar * message);
+typedef void (GLAD_API_PTR *PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target);
+typedef void (GLAD_API_PTR *PFNGLREADBUFFERPROC)(GLenum src);
+typedef void (GLAD_API_PTR *PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLREADNPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void * data);
+typedef void (GLAD_API_PTR *PFNGLRELEASESHADERCOMPILERPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLRESUMETRANSFORMFEEDBACKPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert);
+typedef void (GLAD_API_PTR *PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask);
+typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, const GLint * param);
+typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, const GLuint * param);
+typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param);
+typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat * param);
+typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint * param);
+typedef void (GLAD_API_PTR *PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLSCISSORARRAYVPROC)(GLuint first, GLsizei count, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDPROC)(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint * shaders, GLenum binaryformat, const void * binary, GLsizei length);
+typedef void (GLAD_API_PTR *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length);
+typedef void (GLAD_API_PTR *PFNGLSHADERSTORAGEBLOCKBINDINGPROC)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);
+typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask);
+typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask);
+typedef void (GLAD_API_PTR *PFNGLSTENCILMASKPROC)(GLuint mask);
+typedef void (GLAD_API_PTR *PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask);
+typedef void (GLAD_API_PTR *PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass);
+typedef void (GLAD_API_PTR *PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (GLAD_API_PTR *PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLTEXBUFFERRANGEPROC)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAD_API_PTR *PFNGLTEXIMAGE1DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint * params);
+typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE1DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGEMEM1DEXTPROC)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGEMEM2DEXTPROC)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGEMEM3DEXTPROC)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREBARRIERPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREBUFFERPROC)(GLuint texture, GLenum internalformat, GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREBUFFERRANGEPROC)(GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIIVPROC)(GLuint texture, GLenum pname, const GLint * params);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIUIVPROC)(GLuint texture, GLenum pname, const GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERFPROC)(GLuint texture, GLenum pname, GLfloat param);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERFVPROC)(GLuint texture, GLenum pname, const GLfloat * param);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIPROC)(GLuint texture, GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIVPROC)(GLuint texture, GLenum pname, const GLint * param);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE1DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGEMEM1DEXTPROC)(GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGEMEM2DEXTPROC)(GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC)(GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGEMEM3DEXTPROC)(GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC)(GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREVIEWPROC)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)(GLuint xfb, GLuint index, GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1DPROC)(GLint location, GLdouble x);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1DVPROC)(GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1IPROC)(GLint location, GLint v0);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2DPROC)(GLint location, GLdouble x, GLdouble y);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2DVPROC)(GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3DPROC)(GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3DVPROC)(GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4DPROC)(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4DVPROC)(GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMSUBROUTINESUIVPROC)(GLenum shadertype, GLsizei count, const GLuint * indices);
+typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPBUFFERPROC)(GLenum target);
+typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPNAMEDBUFFERPROC)(GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program);
+typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMSTAGESPROC)(GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program);
+typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPIPELINEPROC)(GLuint pipeline);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBBINDINGPROC)(GLuint vaobj, GLuint attribindex, GLuint bindingindex);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBIFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBLFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYBINDINGDIVISORPROC)(GLuint vaobj, GLuint bindingindex, GLuint divisor);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYELEMENTBUFFERPROC)(GLuint vaobj, GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBUFFERPROC)(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBUFFERSPROC)(GLuint vaobj, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBBINDINGPROC)(GLuint attribindex, GLuint bindingindex);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint x);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint x);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint x, GLint y);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint x, GLuint y);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint x, GLint y, GLint z);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1DPROC)(GLuint index, GLdouble x);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2DPROC)(GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBLFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBLPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer);
+typedef void (GLAD_API_PTR *PFNGLVERTEXBINDINGDIVISORPROC)(GLuint bindingindex, GLuint divisor);
+typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLVIEWPORTARRAYVPROC)(GLuint first, GLsizei count, const GLfloat * v);
+typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFVPROC)(GLuint index, const GLfloat * v);
+typedef void (GLAD_API_PTR *PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout);
+
+GLAD_API_CALL PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram;
+#define glActiveShaderProgram glad_glActiveShaderProgram
+GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture;
+#define glActiveTexture glad_glActiveTexture
+GLAD_API_CALL PFNGLATTACHSHADERPROC glad_glAttachShader;
+#define glAttachShader glad_glAttachShader
+GLAD_API_CALL PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender;
+#define glBeginConditionalRender glad_glBeginConditionalRender
+GLAD_API_CALL PFNGLBEGINQUERYPROC glad_glBeginQuery;
+#define glBeginQuery glad_glBeginQuery
+GLAD_API_CALL PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed;
+#define glBeginQueryIndexed glad_glBeginQueryIndexed
+GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback;
+#define glBeginTransformFeedback glad_glBeginTransformFeedback
+GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation;
+#define glBindAttribLocation glad_glBindAttribLocation
+GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer;
+#define glBindBuffer glad_glBindBuffer
+GLAD_API_CALL PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase;
+#define glBindBufferBase glad_glBindBufferBase
+GLAD_API_CALL PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange;
+#define glBindBufferRange glad_glBindBufferRange
+GLAD_API_CALL PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase;
+#define glBindBuffersBase glad_glBindBuffersBase
+GLAD_API_CALL PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange;
+#define glBindBuffersRange glad_glBindBuffersRange
+GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation;
+#define glBindFragDataLocation glad_glBindFragDataLocation
+GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed;
+#define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed
+GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer;
+#define glBindFramebuffer glad_glBindFramebuffer
+GLAD_API_CALL PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture;
+#define glBindImageTexture glad_glBindImageTexture
+GLAD_API_CALL PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures;
+#define glBindImageTextures glad_glBindImageTextures
+GLAD_API_CALL PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline;
+#define glBindProgramPipeline glad_glBindProgramPipeline
+GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer;
+#define glBindRenderbuffer glad_glBindRenderbuffer
+GLAD_API_CALL PFNGLBINDSAMPLERPROC glad_glBindSampler;
+#define glBindSampler glad_glBindSampler
+GLAD_API_CALL PFNGLBINDSAMPLERSPROC glad_glBindSamplers;
+#define glBindSamplers glad_glBindSamplers
+GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture;
+#define glBindTexture glad_glBindTexture
+GLAD_API_CALL PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit;
+#define glBindTextureUnit glad_glBindTextureUnit
+GLAD_API_CALL PFNGLBINDTEXTURESPROC glad_glBindTextures;
+#define glBindTextures glad_glBindTextures
+GLAD_API_CALL PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback;
+#define glBindTransformFeedback glad_glBindTransformFeedback
+GLAD_API_CALL PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray;
+#define glBindVertexArray glad_glBindVertexArray
+GLAD_API_CALL PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer;
+#define glBindVertexBuffer glad_glBindVertexBuffer
+GLAD_API_CALL PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers;
+#define glBindVertexBuffers glad_glBindVertexBuffers
+GLAD_API_CALL PFNGLBLENDCOLORPROC glad_glBlendColor;
+#define glBlendColor glad_glBlendColor
+GLAD_API_CALL PFNGLBLENDEQUATIONPROC glad_glBlendEquation;
+#define glBlendEquation glad_glBlendEquation
+GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate;
+#define glBlendEquationSeparate glad_glBlendEquationSeparate
+GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEIPROC glad_glBlendEquationSeparatei;
+#define glBlendEquationSeparatei glad_glBlendEquationSeparatei
+GLAD_API_CALL PFNGLBLENDEQUATIONIPROC glad_glBlendEquationi;
+#define glBlendEquationi glad_glBlendEquationi
+GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc;
+#define glBlendFunc glad_glBlendFunc
+GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate;
+#define glBlendFuncSeparate glad_glBlendFuncSeparate
+GLAD_API_CALL PFNGLBLENDFUNCSEPARATEIPROC glad_glBlendFuncSeparatei;
+#define glBlendFuncSeparatei glad_glBlendFuncSeparatei
+GLAD_API_CALL PFNGLBLENDFUNCIPROC glad_glBlendFunci;
+#define glBlendFunci glad_glBlendFunci
+GLAD_API_CALL PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer;
+#define glBlitFramebuffer glad_glBlitFramebuffer
+GLAD_API_CALL PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer;
+#define glBlitNamedFramebuffer glad_glBlitNamedFramebuffer
+GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData;
+#define glBufferData glad_glBufferData
+GLAD_API_CALL PFNGLBUFFERSTORAGEPROC glad_glBufferStorage;
+#define glBufferStorage glad_glBufferStorage
+GLAD_API_CALL PFNGLBUFFERSTORAGEMEMEXTPROC glad_glBufferStorageMemEXT;
+#define glBufferStorageMemEXT glad_glBufferStorageMemEXT
+GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData;
+#define glBufferSubData glad_glBufferSubData
+GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus;
+#define glCheckFramebufferStatus glad_glCheckFramebufferStatus
+GLAD_API_CALL PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus;
+#define glCheckNamedFramebufferStatus glad_glCheckNamedFramebufferStatus
+GLAD_API_CALL PFNGLCLAMPCOLORPROC glad_glClampColor;
+#define glClampColor glad_glClampColor
+GLAD_API_CALL PFNGLCLEARPROC glad_glClear;
+#define glClear glad_glClear
+GLAD_API_CALL PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData;
+#define glClearBufferData glad_glClearBufferData
+GLAD_API_CALL PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData;
+#define glClearBufferSubData glad_glClearBufferSubData
+GLAD_API_CALL PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi;
+#define glClearBufferfi glad_glClearBufferfi
+GLAD_API_CALL PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv;
+#define glClearBufferfv glad_glClearBufferfv
+GLAD_API_CALL PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv;
+#define glClearBufferiv glad_glClearBufferiv
+GLAD_API_CALL PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv;
+#define glClearBufferuiv glad_glClearBufferuiv
+GLAD_API_CALL PFNGLCLEARCOLORPROC glad_glClearColor;
+#define glClearColor glad_glClearColor
+GLAD_API_CALL PFNGLCLEARDEPTHPROC glad_glClearDepth;
+#define glClearDepth glad_glClearDepth
+GLAD_API_CALL PFNGLCLEARDEPTHFPROC glad_glClearDepthf;
+#define glClearDepthf glad_glClearDepthf
+GLAD_API_CALL PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData;
+#define glClearNamedBufferData glad_glClearNamedBufferData
+GLAD_API_CALL PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData;
+#define glClearNamedBufferSubData glad_glClearNamedBufferSubData
+GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi;
+#define glClearNamedFramebufferfi glad_glClearNamedFramebufferfi
+GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv;
+#define glClearNamedFramebufferfv glad_glClearNamedFramebufferfv
+GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv;
+#define glClearNamedFramebufferiv glad_glClearNamedFramebufferiv
+GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv;
+#define glClearNamedFramebufferuiv glad_glClearNamedFramebufferuiv
+GLAD_API_CALL PFNGLCLEARSTENCILPROC glad_glClearStencil;
+#define glClearStencil glad_glClearStencil
+GLAD_API_CALL PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage;
+#define glClearTexImage glad_glClearTexImage
+GLAD_API_CALL PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage;
+#define glClearTexSubImage glad_glClearTexSubImage
+GLAD_API_CALL PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync;
+#define glClientWaitSync glad_glClientWaitSync
+GLAD_API_CALL PFNGLCLIPCONTROLPROC glad_glClipControl;
+#define glClipControl glad_glClipControl
+GLAD_API_CALL PFNGLCOLORMASKPROC glad_glColorMask;
+#define glColorMask glad_glColorMask
+GLAD_API_CALL PFNGLCOLORMASKIPROC glad_glColorMaski;
+#define glColorMaski glad_glColorMaski
+GLAD_API_CALL PFNGLCOMPILESHADERPROC glad_glCompileShader;
+#define glCompileShader glad_glCompileShader
+GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D;
+#define glCompressedTexImage1D glad_glCompressedTexImage1D
+GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D;
+#define glCompressedTexImage2D glad_glCompressedTexImage2D
+GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D;
+#define glCompressedTexImage3D glad_glCompressedTexImage3D
+GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D;
+#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D
+GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D;
+#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D
+GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D;
+#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D
+GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D;
+#define glCompressedTextureSubImage1D glad_glCompressedTextureSubImage1D
+GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D;
+#define glCompressedTextureSubImage2D glad_glCompressedTextureSubImage2D
+GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D;
+#define glCompressedTextureSubImage3D glad_glCompressedTextureSubImage3D
+GLAD_API_CALL PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData;
+#define glCopyBufferSubData glad_glCopyBufferSubData
+GLAD_API_CALL PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData;
+#define glCopyImageSubData glad_glCopyImageSubData
+GLAD_API_CALL PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData;
+#define glCopyNamedBufferSubData glad_glCopyNamedBufferSubData
+GLAD_API_CALL PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D;
+#define glCopyTexImage1D glad_glCopyTexImage1D
+GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D;
+#define glCopyTexImage2D glad_glCopyTexImage2D
+GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D;
+#define glCopyTexSubImage1D glad_glCopyTexSubImage1D
+GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D;
+#define glCopyTexSubImage2D glad_glCopyTexSubImage2D
+GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D;
+#define glCopyTexSubImage3D glad_glCopyTexSubImage3D
+GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D;
+#define glCopyTextureSubImage1D glad_glCopyTextureSubImage1D
+GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D;
+#define glCopyTextureSubImage2D glad_glCopyTextureSubImage2D
+GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D;
+#define glCopyTextureSubImage3D glad_glCopyTextureSubImage3D
+GLAD_API_CALL PFNGLCREATEBUFFERSPROC glad_glCreateBuffers;
+#define glCreateBuffers glad_glCreateBuffers
+GLAD_API_CALL PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers;
+#define glCreateFramebuffers glad_glCreateFramebuffers
+GLAD_API_CALL PFNGLCREATEMEMORYOBJECTSEXTPROC glad_glCreateMemoryObjectsEXT;
+#define glCreateMemoryObjectsEXT glad_glCreateMemoryObjectsEXT
+GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram;
+#define glCreateProgram glad_glCreateProgram
+GLAD_API_CALL PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines;
+#define glCreateProgramPipelines glad_glCreateProgramPipelines
+GLAD_API_CALL PFNGLCREATEQUERIESPROC glad_glCreateQueries;
+#define glCreateQueries glad_glCreateQueries
+GLAD_API_CALL PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers;
+#define glCreateRenderbuffers glad_glCreateRenderbuffers
+GLAD_API_CALL PFNGLCREATESAMPLERSPROC glad_glCreateSamplers;
+#define glCreateSamplers glad_glCreateSamplers
+GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader;
+#define glCreateShader glad_glCreateShader
+GLAD_API_CALL PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv;
+#define glCreateShaderProgramv glad_glCreateShaderProgramv
+GLAD_API_CALL PFNGLCREATETEXTURESPROC glad_glCreateTextures;
+#define glCreateTextures glad_glCreateTextures
+GLAD_API_CALL PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks;
+#define glCreateTransformFeedbacks glad_glCreateTransformFeedbacks
+GLAD_API_CALL PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays;
+#define glCreateVertexArrays glad_glCreateVertexArrays
+GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace;
+#define glCullFace glad_glCullFace
+GLAD_API_CALL PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback;
+#define glDebugMessageCallback glad_glDebugMessageCallback
+GLAD_API_CALL PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl;
+#define glDebugMessageControl glad_glDebugMessageControl
+GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert;
+#define glDebugMessageInsert glad_glDebugMessageInsert
+GLAD_API_CALL PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers;
+#define glDeleteBuffers glad_glDeleteBuffers
+GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers;
+#define glDeleteFramebuffers glad_glDeleteFramebuffers
+GLAD_API_CALL PFNGLDELETEMEMORYOBJECTSEXTPROC glad_glDeleteMemoryObjectsEXT;
+#define glDeleteMemoryObjectsEXT glad_glDeleteMemoryObjectsEXT
+GLAD_API_CALL PFNGLDELETEPROGRAMPROC glad_glDeleteProgram;
+#define glDeleteProgram glad_glDeleteProgram
+GLAD_API_CALL PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines;
+#define glDeleteProgramPipelines glad_glDeleteProgramPipelines
+GLAD_API_CALL PFNGLDELETEQUERIESPROC glad_glDeleteQueries;
+#define glDeleteQueries glad_glDeleteQueries
+GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers;
+#define glDeleteRenderbuffers glad_glDeleteRenderbuffers
+GLAD_API_CALL PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers;
+#define glDeleteSamplers glad_glDeleteSamplers
+GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader;
+#define glDeleteShader glad_glDeleteShader
+GLAD_API_CALL PFNGLDELETESYNCPROC glad_glDeleteSync;
+#define glDeleteSync glad_glDeleteSync
+GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures;
+#define glDeleteTextures glad_glDeleteTextures
+GLAD_API_CALL PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks;
+#define glDeleteTransformFeedbacks glad_glDeleteTransformFeedbacks
+GLAD_API_CALL PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays;
+#define glDeleteVertexArrays glad_glDeleteVertexArrays
+GLAD_API_CALL PFNGLDEPTHFUNCPROC glad_glDepthFunc;
+#define glDepthFunc glad_glDepthFunc
+GLAD_API_CALL PFNGLDEPTHMASKPROC glad_glDepthMask;
+#define glDepthMask glad_glDepthMask
+GLAD_API_CALL PFNGLDEPTHRANGEPROC glad_glDepthRange;
+#define glDepthRange glad_glDepthRange
+GLAD_API_CALL PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv;
+#define glDepthRangeArrayv glad_glDepthRangeArrayv
+GLAD_API_CALL PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed;
+#define glDepthRangeIndexed glad_glDepthRangeIndexed
+GLAD_API_CALL PFNGLDEPTHRANGEFPROC glad_glDepthRangef;
+#define glDepthRangef glad_glDepthRangef
+GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader;
+#define glDetachShader glad_glDetachShader
+GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable;
+#define glDisable glad_glDisable
+GLAD_API_CALL PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib;
+#define glDisableVertexArrayAttrib glad_glDisableVertexArrayAttrib
+GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray;
+#define glDisableVertexAttribArray glad_glDisableVertexAttribArray
+GLAD_API_CALL PFNGLDISABLEIPROC glad_glDisablei;
+#define glDisablei glad_glDisablei
+GLAD_API_CALL PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute;
+#define glDispatchCompute glad_glDispatchCompute
+GLAD_API_CALL PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect;
+#define glDispatchComputeIndirect glad_glDispatchComputeIndirect
+GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays;
+#define glDrawArrays glad_glDrawArrays
+GLAD_API_CALL PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect;
+#define glDrawArraysIndirect glad_glDrawArraysIndirect
+GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced;
+#define glDrawArraysInstanced glad_glDrawArraysInstanced
+GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance;
+#define glDrawArraysInstancedBaseInstance glad_glDrawArraysInstancedBaseInstance
+GLAD_API_CALL PFNGLDRAWBUFFERPROC glad_glDrawBuffer;
+#define glDrawBuffer glad_glDrawBuffer
+GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers;
+#define glDrawBuffers glad_glDrawBuffers
+GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements;
+#define glDrawElements glad_glDrawElements
+GLAD_API_CALL PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex;
+#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex
+GLAD_API_CALL PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect;
+#define glDrawElementsIndirect glad_glDrawElementsIndirect
+GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced;
+#define glDrawElementsInstanced glad_glDrawElementsInstanced
+GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance;
+#define glDrawElementsInstancedBaseInstance glad_glDrawElementsInstancedBaseInstance
+GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex;
+#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex
+GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance;
+#define glDrawElementsInstancedBaseVertexBaseInstance glad_glDrawElementsInstancedBaseVertexBaseInstance
+GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements;
+#define glDrawRangeElements glad_glDrawRangeElements
+GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex;
+#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex
+GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback;
+#define glDrawTransformFeedback glad_glDrawTransformFeedback
+GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced;
+#define glDrawTransformFeedbackInstanced glad_glDrawTransformFeedbackInstanced
+GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream;
+#define glDrawTransformFeedbackStream glad_glDrawTransformFeedbackStream
+GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced;
+#define glDrawTransformFeedbackStreamInstanced glad_glDrawTransformFeedbackStreamInstanced
+GLAD_API_CALL PFNGLENABLEPROC glad_glEnable;
+#define glEnable glad_glEnable
+GLAD_API_CALL PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib;
+#define glEnableVertexArrayAttrib glad_glEnableVertexArrayAttrib
+GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray;
+#define glEnableVertexAttribArray glad_glEnableVertexAttribArray
+GLAD_API_CALL PFNGLENABLEIPROC glad_glEnablei;
+#define glEnablei glad_glEnablei
+GLAD_API_CALL PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender;
+#define glEndConditionalRender glad_glEndConditionalRender
+GLAD_API_CALL PFNGLENDQUERYPROC glad_glEndQuery;
+#define glEndQuery glad_glEndQuery
+GLAD_API_CALL PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed;
+#define glEndQueryIndexed glad_glEndQueryIndexed
+GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback;
+#define glEndTransformFeedback glad_glEndTransformFeedback
+GLAD_API_CALL PFNGLFENCESYNCPROC glad_glFenceSync;
+#define glFenceSync glad_glFenceSync
+GLAD_API_CALL PFNGLFINISHPROC glad_glFinish;
+#define glFinish glad_glFinish
+GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush;
+#define glFlush glad_glFlush
+GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange;
+#define glFlushMappedBufferRange glad_glFlushMappedBufferRange
+GLAD_API_CALL PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange;
+#define glFlushMappedNamedBufferRange glad_glFlushMappedNamedBufferRange
+GLAD_API_CALL PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri;
+#define glFramebufferParameteri glad_glFramebufferParameteri
+GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer;
+#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer
+GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture;
+#define glFramebufferTexture glad_glFramebufferTexture
+GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D;
+#define glFramebufferTexture1D glad_glFramebufferTexture1D
+GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D;
+#define glFramebufferTexture2D glad_glFramebufferTexture2D
+GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D;
+#define glFramebufferTexture3D glad_glFramebufferTexture3D
+GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer;
+#define glFramebufferTextureLayer glad_glFramebufferTextureLayer
+GLAD_API_CALL PFNGLFRONTFACEPROC glad_glFrontFace;
+#define glFrontFace glad_glFrontFace
+GLAD_API_CALL PFNGLGENBUFFERSPROC glad_glGenBuffers;
+#define glGenBuffers glad_glGenBuffers
+GLAD_API_CALL PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers;
+#define glGenFramebuffers glad_glGenFramebuffers
+GLAD_API_CALL PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines;
+#define glGenProgramPipelines glad_glGenProgramPipelines
+GLAD_API_CALL PFNGLGENQUERIESPROC glad_glGenQueries;
+#define glGenQueries glad_glGenQueries
+GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers;
+#define glGenRenderbuffers glad_glGenRenderbuffers
+GLAD_API_CALL PFNGLGENSAMPLERSPROC glad_glGenSamplers;
+#define glGenSamplers glad_glGenSamplers
+GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures;
+#define glGenTextures glad_glGenTextures
+GLAD_API_CALL PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks;
+#define glGenTransformFeedbacks glad_glGenTransformFeedbacks
+GLAD_API_CALL PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays;
+#define glGenVertexArrays glad_glGenVertexArrays
+GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap;
+#define glGenerateMipmap glad_glGenerateMipmap
+GLAD_API_CALL PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap;
+#define glGenerateTextureMipmap glad_glGenerateTextureMipmap
+GLAD_API_CALL PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv;
+#define glGetActiveAtomicCounterBufferiv glad_glGetActiveAtomicCounterBufferiv
+GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib;
+#define glGetActiveAttrib glad_glGetActiveAttrib
+GLAD_API_CALL PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName;
+#define glGetActiveSubroutineName glad_glGetActiveSubroutineName
+GLAD_API_CALL PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName;
+#define glGetActiveSubroutineUniformName glad_glGetActiveSubroutineUniformName
+GLAD_API_CALL PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv;
+#define glGetActiveSubroutineUniformiv glad_glGetActiveSubroutineUniformiv
+GLAD_API_CALL PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform;
+#define glGetActiveUniform glad_glGetActiveUniform
+GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName;
+#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName
+GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv;
+#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv
+GLAD_API_CALL PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName;
+#define glGetActiveUniformName glad_glGetActiveUniformName
+GLAD_API_CALL PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv;
+#define glGetActiveUniformsiv glad_glGetActiveUniformsiv
+GLAD_API_CALL PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders;
+#define glGetAttachedShaders glad_glGetAttachedShaders
+GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation;
+#define glGetAttribLocation glad_glGetAttribLocation
+GLAD_API_CALL PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v;
+#define glGetBooleani_v glad_glGetBooleani_v
+GLAD_API_CALL PFNGLGETBOOLEANVPROC glad_glGetBooleanv;
+#define glGetBooleanv glad_glGetBooleanv
+GLAD_API_CALL PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v;
+#define glGetBufferParameteri64v glad_glGetBufferParameteri64v
+GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv;
+#define glGetBufferParameteriv glad_glGetBufferParameteriv
+GLAD_API_CALL PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv;
+#define glGetBufferPointerv glad_glGetBufferPointerv
+GLAD_API_CALL PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData;
+#define glGetBufferSubData glad_glGetBufferSubData
+GLAD_API_CALL PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage;
+#define glGetCompressedTexImage glad_glGetCompressedTexImage
+GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage;
+#define glGetCompressedTextureImage glad_glGetCompressedTextureImage
+GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage;
+#define glGetCompressedTextureSubImage glad_glGetCompressedTextureSubImage
+GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog;
+#define glGetDebugMessageLog glad_glGetDebugMessageLog
+GLAD_API_CALL PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v;
+#define glGetDoublei_v glad_glGetDoublei_v
+GLAD_API_CALL PFNGLGETDOUBLEVPROC glad_glGetDoublev;
+#define glGetDoublev glad_glGetDoublev
+GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError;
+#define glGetError glad_glGetError
+GLAD_API_CALL PFNGLGETFLOATI_VPROC glad_glGetFloati_v;
+#define glGetFloati_v glad_glGetFloati_v
+GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv;
+#define glGetFloatv glad_glGetFloatv
+GLAD_API_CALL PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex;
+#define glGetFragDataIndex glad_glGetFragDataIndex
+GLAD_API_CALL PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation;
+#define glGetFragDataLocation glad_glGetFragDataLocation
+GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv;
+#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv
+GLAD_API_CALL PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv;
+#define glGetFramebufferParameteriv glad_glGetFramebufferParameteriv
+GLAD_API_CALL PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus;
+#define glGetGraphicsResetStatus glad_glGetGraphicsResetStatus
+GLAD_API_CALL PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v;
+#define glGetInteger64i_v glad_glGetInteger64i_v
+GLAD_API_CALL PFNGLGETINTEGER64VPROC glad_glGetInteger64v;
+#define glGetInteger64v glad_glGetInteger64v
+GLAD_API_CALL PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v;
+#define glGetIntegeri_v glad_glGetIntegeri_v
+GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv;
+#define glGetIntegerv glad_glGetIntegerv
+GLAD_API_CALL PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v;
+#define glGetInternalformati64v glad_glGetInternalformati64v
+GLAD_API_CALL PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ;
+#define glGetInternalformativ glad_glGetInternalformativ
+GLAD_API_CALL PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glad_glGetMemoryObjectParameterivEXT;
+#define glGetMemoryObjectParameterivEXT glad_glGetMemoryObjectParameterivEXT
+GLAD_API_CALL PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv;
+#define glGetMultisamplefv glad_glGetMultisamplefv
+GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v;
+#define glGetNamedBufferParameteri64v glad_glGetNamedBufferParameteri64v
+GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv;
+#define glGetNamedBufferParameteriv glad_glGetNamedBufferParameteriv
+GLAD_API_CALL PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv;
+#define glGetNamedBufferPointerv glad_glGetNamedBufferPointerv
+GLAD_API_CALL PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData;
+#define glGetNamedBufferSubData glad_glGetNamedBufferSubData
+GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv;
+#define glGetNamedFramebufferAttachmentParameteriv glad_glGetNamedFramebufferAttachmentParameteriv
+GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv;
+#define glGetNamedFramebufferParameteriv glad_glGetNamedFramebufferParameteriv
+GLAD_API_CALL PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv;
+#define glGetNamedRenderbufferParameteriv glad_glGetNamedRenderbufferParameteriv
+GLAD_API_CALL PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel;
+#define glGetObjectLabel glad_glGetObjectLabel
+GLAD_API_CALL PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel;
+#define glGetObjectPtrLabel glad_glGetObjectPtrLabel
+GLAD_API_CALL PFNGLGETPOINTERVPROC glad_glGetPointerv;
+#define glGetPointerv glad_glGetPointerv
+GLAD_API_CALL PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary;
+#define glGetProgramBinary glad_glGetProgramBinary
+GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog;
+#define glGetProgramInfoLog glad_glGetProgramInfoLog
+GLAD_API_CALL PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv;
+#define glGetProgramInterfaceiv glad_glGetProgramInterfaceiv
+GLAD_API_CALL PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog;
+#define glGetProgramPipelineInfoLog glad_glGetProgramPipelineInfoLog
+GLAD_API_CALL PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv;
+#define glGetProgramPipelineiv glad_glGetProgramPipelineiv
+GLAD_API_CALL PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex;
+#define glGetProgramResourceIndex glad_glGetProgramResourceIndex
+GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation;
+#define glGetProgramResourceLocation glad_glGetProgramResourceLocation
+GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex;
+#define glGetProgramResourceLocationIndex glad_glGetProgramResourceLocationIndex
+GLAD_API_CALL PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName;
+#define glGetProgramResourceName glad_glGetProgramResourceName
+GLAD_API_CALL PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv;
+#define glGetProgramResourceiv glad_glGetProgramResourceiv
+GLAD_API_CALL PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv;
+#define glGetProgramStageiv glad_glGetProgramStageiv
+GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv;
+#define glGetProgramiv glad_glGetProgramiv
+GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v;
+#define glGetQueryBufferObjecti64v glad_glGetQueryBufferObjecti64v
+GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv;
+#define glGetQueryBufferObjectiv glad_glGetQueryBufferObjectiv
+GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v;
+#define glGetQueryBufferObjectui64v glad_glGetQueryBufferObjectui64v
+GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv;
+#define glGetQueryBufferObjectuiv glad_glGetQueryBufferObjectuiv
+GLAD_API_CALL PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv;
+#define glGetQueryIndexediv glad_glGetQueryIndexediv
+GLAD_API_CALL PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v;
+#define glGetQueryObjecti64v glad_glGetQueryObjecti64v
+GLAD_API_CALL PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv;
+#define glGetQueryObjectiv glad_glGetQueryObjectiv
+GLAD_API_CALL PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v;
+#define glGetQueryObjectui64v glad_glGetQueryObjectui64v
+GLAD_API_CALL PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv;
+#define glGetQueryObjectuiv glad_glGetQueryObjectuiv
+GLAD_API_CALL PFNGLGETQUERYIVPROC glad_glGetQueryiv;
+#define glGetQueryiv glad_glGetQueryiv
+GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv;
+#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv
+GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv;
+#define glGetSamplerParameterIiv glad_glGetSamplerParameterIiv
+GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv;
+#define glGetSamplerParameterIuiv glad_glGetSamplerParameterIuiv
+GLAD_API_CALL PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv;
+#define glGetSamplerParameterfv glad_glGetSamplerParameterfv
+GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv;
+#define glGetSamplerParameteriv glad_glGetSamplerParameteriv
+GLAD_API_CALL PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog;
+#define glGetShaderInfoLog glad_glGetShaderInfoLog
+GLAD_API_CALL PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat;
+#define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat
+GLAD_API_CALL PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource;
+#define glGetShaderSource glad_glGetShaderSource
+GLAD_API_CALL PFNGLGETSHADERIVPROC glad_glGetShaderiv;
+#define glGetShaderiv glad_glGetShaderiv
+GLAD_API_CALL PFNGLGETSTRINGPROC glad_glGetString;
+#define glGetString glad_glGetString
+GLAD_API_CALL PFNGLGETSTRINGIPROC glad_glGetStringi;
+#define glGetStringi glad_glGetStringi
+GLAD_API_CALL PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex;
+#define glGetSubroutineIndex glad_glGetSubroutineIndex
+GLAD_API_CALL PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation;
+#define glGetSubroutineUniformLocation glad_glGetSubroutineUniformLocation
+GLAD_API_CALL PFNGLGETSYNCIVPROC glad_glGetSynciv;
+#define glGetSynciv glad_glGetSynciv
+GLAD_API_CALL PFNGLGETTEXIMAGEPROC glad_glGetTexImage;
+#define glGetTexImage glad_glGetTexImage
+GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv;
+#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv
+GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv;
+#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv
+GLAD_API_CALL PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv;
+#define glGetTexParameterIiv glad_glGetTexParameterIiv
+GLAD_API_CALL PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv;
+#define glGetTexParameterIuiv glad_glGetTexParameterIuiv
+GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv;
+#define glGetTexParameterfv glad_glGetTexParameterfv
+GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv;
+#define glGetTexParameteriv glad_glGetTexParameteriv
+GLAD_API_CALL PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage;
+#define glGetTextureImage glad_glGetTextureImage
+GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv;
+#define glGetTextureLevelParameterfv glad_glGetTextureLevelParameterfv
+GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv;
+#define glGetTextureLevelParameteriv glad_glGetTextureLevelParameteriv
+GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv;
+#define glGetTextureParameterIiv glad_glGetTextureParameterIiv
+GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv;
+#define glGetTextureParameterIuiv glad_glGetTextureParameterIuiv
+GLAD_API_CALL PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv;
+#define glGetTextureParameterfv glad_glGetTextureParameterfv
+GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv;
+#define glGetTextureParameteriv glad_glGetTextureParameteriv
+GLAD_API_CALL PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage;
+#define glGetTextureSubImage glad_glGetTextureSubImage
+GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying;
+#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying
+GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v;
+#define glGetTransformFeedbacki64_v glad_glGetTransformFeedbacki64_v
+GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v;
+#define glGetTransformFeedbacki_v glad_glGetTransformFeedbacki_v
+GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv;
+#define glGetTransformFeedbackiv glad_glGetTransformFeedbackiv
+GLAD_API_CALL PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex;
+#define glGetUniformBlockIndex glad_glGetUniformBlockIndex
+GLAD_API_CALL PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices;
+#define glGetUniformIndices glad_glGetUniformIndices
+GLAD_API_CALL PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation;
+#define glGetUniformLocation glad_glGetUniformLocation
+GLAD_API_CALL PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv;
+#define glGetUniformSubroutineuiv glad_glGetUniformSubroutineuiv
+GLAD_API_CALL PFNGLGETUNIFORMDVPROC glad_glGetUniformdv;
+#define glGetUniformdv glad_glGetUniformdv
+GLAD_API_CALL PFNGLGETUNIFORMFVPROC glad_glGetUniformfv;
+#define glGetUniformfv glad_glGetUniformfv
+GLAD_API_CALL PFNGLGETUNIFORMIVPROC glad_glGetUniformiv;
+#define glGetUniformiv glad_glGetUniformiv
+GLAD_API_CALL PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv;
+#define glGetUniformuiv glad_glGetUniformuiv
+GLAD_API_CALL PFNGLGETUNSIGNEDBYTEI_VEXTPROC glad_glGetUnsignedBytei_vEXT;
+#define glGetUnsignedBytei_vEXT glad_glGetUnsignedBytei_vEXT
+GLAD_API_CALL PFNGLGETUNSIGNEDBYTEVEXTPROC glad_glGetUnsignedBytevEXT;
+#define glGetUnsignedBytevEXT glad_glGetUnsignedBytevEXT
+GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv;
+#define glGetVertexArrayIndexed64iv glad_glGetVertexArrayIndexed64iv
+GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv;
+#define glGetVertexArrayIndexediv glad_glGetVertexArrayIndexediv
+GLAD_API_CALL PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv;
+#define glGetVertexArrayiv glad_glGetVertexArrayiv
+GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv;
+#define glGetVertexAttribIiv glad_glGetVertexAttribIiv
+GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv;
+#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv
+GLAD_API_CALL PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv;
+#define glGetVertexAttribLdv glad_glGetVertexAttribLdv
+GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv;
+#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv
+GLAD_API_CALL PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv;
+#define glGetVertexAttribdv glad_glGetVertexAttribdv
+GLAD_API_CALL PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv;
+#define glGetVertexAttribfv glad_glGetVertexAttribfv
+GLAD_API_CALL PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv;
+#define glGetVertexAttribiv glad_glGetVertexAttribiv
+GLAD_API_CALL PFNGLGETNCOMPRESSEDTEXIMAGEPROC glad_glGetnCompressedTexImage;
+#define glGetnCompressedTexImage glad_glGetnCompressedTexImage
+GLAD_API_CALL PFNGLGETNTEXIMAGEPROC glad_glGetnTexImage;
+#define glGetnTexImage glad_glGetnTexImage
+GLAD_API_CALL PFNGLGETNUNIFORMDVPROC glad_glGetnUniformdv;
+#define glGetnUniformdv glad_glGetnUniformdv
+GLAD_API_CALL PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv;
+#define glGetnUniformfv glad_glGetnUniformfv
+GLAD_API_CALL PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv;
+#define glGetnUniformiv glad_glGetnUniformiv
+GLAD_API_CALL PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv;
+#define glGetnUniformuiv glad_glGetnUniformuiv
+GLAD_API_CALL PFNGLHINTPROC glad_glHint;
+#define glHint glad_glHint
+GLAD_API_CALL PFNGLIMPORTMEMORYFDEXTPROC glad_glImportMemoryFdEXT;
+#define glImportMemoryFdEXT glad_glImportMemoryFdEXT
+GLAD_API_CALL PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData;
+#define glInvalidateBufferData glad_glInvalidateBufferData
+GLAD_API_CALL PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData;
+#define glInvalidateBufferSubData glad_glInvalidateBufferSubData
+GLAD_API_CALL PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer;
+#define glInvalidateFramebuffer glad_glInvalidateFramebuffer
+GLAD_API_CALL PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData;
+#define glInvalidateNamedFramebufferData glad_glInvalidateNamedFramebufferData
+GLAD_API_CALL PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData;
+#define glInvalidateNamedFramebufferSubData glad_glInvalidateNamedFramebufferSubData
+GLAD_API_CALL PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer;
+#define glInvalidateSubFramebuffer glad_glInvalidateSubFramebuffer
+GLAD_API_CALL PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage;
+#define glInvalidateTexImage glad_glInvalidateTexImage
+GLAD_API_CALL PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage;
+#define glInvalidateTexSubImage glad_glInvalidateTexSubImage
+GLAD_API_CALL PFNGLISBUFFERPROC glad_glIsBuffer;
+#define glIsBuffer glad_glIsBuffer
+GLAD_API_CALL PFNGLISENABLEDPROC glad_glIsEnabled;
+#define glIsEnabled glad_glIsEnabled
+GLAD_API_CALL PFNGLISENABLEDIPROC glad_glIsEnabledi;
+#define glIsEnabledi glad_glIsEnabledi
+GLAD_API_CALL PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer;
+#define glIsFramebuffer glad_glIsFramebuffer
+GLAD_API_CALL PFNGLISMEMORYOBJECTEXTPROC glad_glIsMemoryObjectEXT;
+#define glIsMemoryObjectEXT glad_glIsMemoryObjectEXT
+GLAD_API_CALL PFNGLISPROGRAMPROC glad_glIsProgram;
+#define glIsProgram glad_glIsProgram
+GLAD_API_CALL PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline;
+#define glIsProgramPipeline glad_glIsProgramPipeline
+GLAD_API_CALL PFNGLISQUERYPROC glad_glIsQuery;
+#define glIsQuery glad_glIsQuery
+GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer;
+#define glIsRenderbuffer glad_glIsRenderbuffer
+GLAD_API_CALL PFNGLISSAMPLERPROC glad_glIsSampler;
+#define glIsSampler glad_glIsSampler
+GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader;
+#define glIsShader glad_glIsShader
+GLAD_API_CALL PFNGLISSYNCPROC glad_glIsSync;
+#define glIsSync glad_glIsSync
+GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture;
+#define glIsTexture glad_glIsTexture
+GLAD_API_CALL PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback;
+#define glIsTransformFeedback glad_glIsTransformFeedback
+GLAD_API_CALL PFNGLISVERTEXARRAYPROC glad_glIsVertexArray;
+#define glIsVertexArray glad_glIsVertexArray
+GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth;
+#define glLineWidth glad_glLineWidth
+GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram;
+#define glLinkProgram glad_glLinkProgram
+GLAD_API_CALL PFNGLLOGICOPPROC glad_glLogicOp;
+#define glLogicOp glad_glLogicOp
+GLAD_API_CALL PFNGLMAPBUFFERPROC glad_glMapBuffer;
+#define glMapBuffer glad_glMapBuffer
+GLAD_API_CALL PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange;
+#define glMapBufferRange glad_glMapBufferRange
+GLAD_API_CALL PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer;
+#define glMapNamedBuffer glad_glMapNamedBuffer
+GLAD_API_CALL PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange;
+#define glMapNamedBufferRange glad_glMapNamedBufferRange
+GLAD_API_CALL PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier;
+#define glMemoryBarrier glad_glMemoryBarrier
+GLAD_API_CALL PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion;
+#define glMemoryBarrierByRegion glad_glMemoryBarrierByRegion
+GLAD_API_CALL PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glad_glMemoryObjectParameterivEXT;
+#define glMemoryObjectParameterivEXT glad_glMemoryObjectParameterivEXT
+GLAD_API_CALL PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading;
+#define glMinSampleShading glad_glMinSampleShading
+GLAD_API_CALL PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays;
+#define glMultiDrawArrays glad_glMultiDrawArrays
+GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect;
+#define glMultiDrawArraysIndirect glad_glMultiDrawArraysIndirect
+GLAD_API_CALL PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements;
+#define glMultiDrawElements glad_glMultiDrawElements
+GLAD_API_CALL PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex;
+#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex
+GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect;
+#define glMultiDrawElementsIndirect glad_glMultiDrawElementsIndirect
+GLAD_API_CALL PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData;
+#define glNamedBufferData glad_glNamedBufferData
+GLAD_API_CALL PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage;
+#define glNamedBufferStorage glad_glNamedBufferStorage
+GLAD_API_CALL PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glad_glNamedBufferStorageMemEXT;
+#define glNamedBufferStorageMemEXT glad_glNamedBufferStorageMemEXT
+GLAD_API_CALL PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData;
+#define glNamedBufferSubData glad_glNamedBufferSubData
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer;
+#define glNamedFramebufferDrawBuffer glad_glNamedFramebufferDrawBuffer
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers;
+#define glNamedFramebufferDrawBuffers glad_glNamedFramebufferDrawBuffers
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri;
+#define glNamedFramebufferParameteri glad_glNamedFramebufferParameteri
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer;
+#define glNamedFramebufferReadBuffer glad_glNamedFramebufferReadBuffer
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer;
+#define glNamedFramebufferRenderbuffer glad_glNamedFramebufferRenderbuffer
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture;
+#define glNamedFramebufferTexture glad_glNamedFramebufferTexture
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer;
+#define glNamedFramebufferTextureLayer glad_glNamedFramebufferTextureLayer
+GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage;
+#define glNamedRenderbufferStorage glad_glNamedRenderbufferStorage
+GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample;
+#define glNamedRenderbufferStorageMultisample glad_glNamedRenderbufferStorageMultisample
+GLAD_API_CALL PFNGLOBJECTLABELPROC glad_glObjectLabel;
+#define glObjectLabel glad_glObjectLabel
+GLAD_API_CALL PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel;
+#define glObjectPtrLabel glad_glObjectPtrLabel
+GLAD_API_CALL PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv;
+#define glPatchParameterfv glad_glPatchParameterfv
+GLAD_API_CALL PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri;
+#define glPatchParameteri glad_glPatchParameteri
+GLAD_API_CALL PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback;
+#define glPauseTransformFeedback glad_glPauseTransformFeedback
+GLAD_API_CALL PFNGLPIXELSTOREFPROC glad_glPixelStoref;
+#define glPixelStoref glad_glPixelStoref
+GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei;
+#define glPixelStorei glad_glPixelStorei
+GLAD_API_CALL PFNGLPOINTPARAMETERFPROC glad_glPointParameterf;
+#define glPointParameterf glad_glPointParameterf
+GLAD_API_CALL PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv;
+#define glPointParameterfv glad_glPointParameterfv
+GLAD_API_CALL PFNGLPOINTPARAMETERIPROC glad_glPointParameteri;
+#define glPointParameteri glad_glPointParameteri
+GLAD_API_CALL PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv;
+#define glPointParameteriv glad_glPointParameteriv
+GLAD_API_CALL PFNGLPOINTSIZEPROC glad_glPointSize;
+#define glPointSize glad_glPointSize
+GLAD_API_CALL PFNGLPOLYGONMODEPROC glad_glPolygonMode;
+#define glPolygonMode glad_glPolygonMode
+GLAD_API_CALL PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset;
+#define glPolygonOffset glad_glPolygonOffset
+GLAD_API_CALL PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup;
+#define glPopDebugGroup glad_glPopDebugGroup
+GLAD_API_CALL PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex;
+#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex
+GLAD_API_CALL PFNGLPROGRAMBINARYPROC glad_glProgramBinary;
+#define glProgramBinary glad_glProgramBinary
+GLAD_API_CALL PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri;
+#define glProgramParameteri glad_glProgramParameteri
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d;
+#define glProgramUniform1d glad_glProgramUniform1d
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv;
+#define glProgramUniform1dv glad_glProgramUniform1dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f;
+#define glProgramUniform1f glad_glProgramUniform1f
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv;
+#define glProgramUniform1fv glad_glProgramUniform1fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i;
+#define glProgramUniform1i glad_glProgramUniform1i
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv;
+#define glProgramUniform1iv glad_glProgramUniform1iv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui;
+#define glProgramUniform1ui glad_glProgramUniform1ui
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv;
+#define glProgramUniform1uiv glad_glProgramUniform1uiv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d;
+#define glProgramUniform2d glad_glProgramUniform2d
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv;
+#define glProgramUniform2dv glad_glProgramUniform2dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f;
+#define glProgramUniform2f glad_glProgramUniform2f
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv;
+#define glProgramUniform2fv glad_glProgramUniform2fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i;
+#define glProgramUniform2i glad_glProgramUniform2i
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv;
+#define glProgramUniform2iv glad_glProgramUniform2iv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui;
+#define glProgramUniform2ui glad_glProgramUniform2ui
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv;
+#define glProgramUniform2uiv glad_glProgramUniform2uiv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d;
+#define glProgramUniform3d glad_glProgramUniform3d
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv;
+#define glProgramUniform3dv glad_glProgramUniform3dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f;
+#define glProgramUniform3f glad_glProgramUniform3f
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv;
+#define glProgramUniform3fv glad_glProgramUniform3fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i;
+#define glProgramUniform3i glad_glProgramUniform3i
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv;
+#define glProgramUniform3iv glad_glProgramUniform3iv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui;
+#define glProgramUniform3ui glad_glProgramUniform3ui
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv;
+#define glProgramUniform3uiv glad_glProgramUniform3uiv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d;
+#define glProgramUniform4d glad_glProgramUniform4d
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv;
+#define glProgramUniform4dv glad_glProgramUniform4dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f;
+#define glProgramUniform4f glad_glProgramUniform4f
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv;
+#define glProgramUniform4fv glad_glProgramUniform4fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i;
+#define glProgramUniform4i glad_glProgramUniform4i
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv;
+#define glProgramUniform4iv glad_glProgramUniform4iv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui;
+#define glProgramUniform4ui glad_glProgramUniform4ui
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv;
+#define glProgramUniform4uiv glad_glProgramUniform4uiv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv;
+#define glProgramUniformMatrix2dv glad_glProgramUniformMatrix2dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv;
+#define glProgramUniformMatrix2fv glad_glProgramUniformMatrix2fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv;
+#define glProgramUniformMatrix2x3dv glad_glProgramUniformMatrix2x3dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv;
+#define glProgramUniformMatrix2x3fv glad_glProgramUniformMatrix2x3fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv;
+#define glProgramUniformMatrix2x4dv glad_glProgramUniformMatrix2x4dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv;
+#define glProgramUniformMatrix2x4fv glad_glProgramUniformMatrix2x4fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv;
+#define glProgramUniformMatrix3dv glad_glProgramUniformMatrix3dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv;
+#define glProgramUniformMatrix3fv glad_glProgramUniformMatrix3fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv;
+#define glProgramUniformMatrix3x2dv glad_glProgramUniformMatrix3x2dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv;
+#define glProgramUniformMatrix3x2fv glad_glProgramUniformMatrix3x2fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv;
+#define glProgramUniformMatrix3x4dv glad_glProgramUniformMatrix3x4dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv;
+#define glProgramUniformMatrix3x4fv glad_glProgramUniformMatrix3x4fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv;
+#define glProgramUniformMatrix4dv glad_glProgramUniformMatrix4dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv;
+#define glProgramUniformMatrix4fv glad_glProgramUniformMatrix4fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv;
+#define glProgramUniformMatrix4x2dv glad_glProgramUniformMatrix4x2dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv;
+#define glProgramUniformMatrix4x2fv glad_glProgramUniformMatrix4x2fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv;
+#define glProgramUniformMatrix4x3dv glad_glProgramUniformMatrix4x3dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv;
+#define glProgramUniformMatrix4x3fv glad_glProgramUniformMatrix4x3fv
+GLAD_API_CALL PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex;
+#define glProvokingVertex glad_glProvokingVertex
+GLAD_API_CALL PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup;
+#define glPushDebugGroup glad_glPushDebugGroup
+GLAD_API_CALL PFNGLQUERYCOUNTERPROC glad_glQueryCounter;
+#define glQueryCounter glad_glQueryCounter
+GLAD_API_CALL PFNGLREADBUFFERPROC glad_glReadBuffer;
+#define glReadBuffer glad_glReadBuffer
+GLAD_API_CALL PFNGLREADPIXELSPROC glad_glReadPixels;
+#define glReadPixels glad_glReadPixels
+GLAD_API_CALL PFNGLREADNPIXELSPROC glad_glReadnPixels;
+#define glReadnPixels glad_glReadnPixels
+GLAD_API_CALL PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler;
+#define glReleaseShaderCompiler glad_glReleaseShaderCompiler
+GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage;
+#define glRenderbufferStorage glad_glRenderbufferStorage
+GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample;
+#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample
+GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback;
+#define glResumeTransformFeedback glad_glResumeTransformFeedback
+GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage;
+#define glSampleCoverage glad_glSampleCoverage
+GLAD_API_CALL PFNGLSAMPLEMASKIPROC glad_glSampleMaski;
+#define glSampleMaski glad_glSampleMaski
+GLAD_API_CALL PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv;
+#define glSamplerParameterIiv glad_glSamplerParameterIiv
+GLAD_API_CALL PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv;
+#define glSamplerParameterIuiv glad_glSamplerParameterIuiv
+GLAD_API_CALL PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf;
+#define glSamplerParameterf glad_glSamplerParameterf
+GLAD_API_CALL PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv;
+#define glSamplerParameterfv glad_glSamplerParameterfv
+GLAD_API_CALL PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri;
+#define glSamplerParameteri glad_glSamplerParameteri
+GLAD_API_CALL PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv;
+#define glSamplerParameteriv glad_glSamplerParameteriv
+GLAD_API_CALL PFNGLSCISSORPROC glad_glScissor;
+#define glScissor glad_glScissor
+GLAD_API_CALL PFNGLSCISSORARRAYVPROC glad_glScissorArrayv;
+#define glScissorArrayv glad_glScissorArrayv
+GLAD_API_CALL PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed;
+#define glScissorIndexed glad_glScissorIndexed
+GLAD_API_CALL PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv;
+#define glScissorIndexedv glad_glScissorIndexedv
+GLAD_API_CALL PFNGLSHADERBINARYPROC glad_glShaderBinary;
+#define glShaderBinary glad_glShaderBinary
+GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource;
+#define glShaderSource glad_glShaderSource
+GLAD_API_CALL PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding;
+#define glShaderStorageBlockBinding glad_glShaderStorageBlockBinding
+GLAD_API_CALL PFNGLSTENCILFUNCPROC glad_glStencilFunc;
+#define glStencilFunc glad_glStencilFunc
+GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate;
+#define glStencilFuncSeparate glad_glStencilFuncSeparate
+GLAD_API_CALL PFNGLSTENCILMASKPROC glad_glStencilMask;
+#define glStencilMask glad_glStencilMask
+GLAD_API_CALL PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate;
+#define glStencilMaskSeparate glad_glStencilMaskSeparate
+GLAD_API_CALL PFNGLSTENCILOPPROC glad_glStencilOp;
+#define glStencilOp glad_glStencilOp
+GLAD_API_CALL PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate;
+#define glStencilOpSeparate glad_glStencilOpSeparate
+GLAD_API_CALL PFNGLTEXBUFFERPROC glad_glTexBuffer;
+#define glTexBuffer glad_glTexBuffer
+GLAD_API_CALL PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange;
+#define glTexBufferRange glad_glTexBufferRange
+GLAD_API_CALL PFNGLTEXIMAGE1DPROC glad_glTexImage1D;
+#define glTexImage1D glad_glTexImage1D
+GLAD_API_CALL PFNGLTEXIMAGE2DPROC glad_glTexImage2D;
+#define glTexImage2D glad_glTexImage2D
+GLAD_API_CALL PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample;
+#define glTexImage2DMultisample glad_glTexImage2DMultisample
+GLAD_API_CALL PFNGLTEXIMAGE3DPROC glad_glTexImage3D;
+#define glTexImage3D glad_glTexImage3D
+GLAD_API_CALL PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample;
+#define glTexImage3DMultisample glad_glTexImage3DMultisample
+GLAD_API_CALL PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv;
+#define glTexParameterIiv glad_glTexParameterIiv
+GLAD_API_CALL PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv;
+#define glTexParameterIuiv glad_glTexParameterIuiv
+GLAD_API_CALL PFNGLTEXPARAMETERFPROC glad_glTexParameterf;
+#define glTexParameterf glad_glTexParameterf
+GLAD_API_CALL PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv;
+#define glTexParameterfv glad_glTexParameterfv
+GLAD_API_CALL PFNGLTEXPARAMETERIPROC glad_glTexParameteri;
+#define glTexParameteri glad_glTexParameteri
+GLAD_API_CALL PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv;
+#define glTexParameteriv glad_glTexParameteriv
+GLAD_API_CALL PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D;
+#define glTexStorage1D glad_glTexStorage1D
+GLAD_API_CALL PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D;
+#define glTexStorage2D glad_glTexStorage2D
+GLAD_API_CALL PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample;
+#define glTexStorage2DMultisample glad_glTexStorage2DMultisample
+GLAD_API_CALL PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D;
+#define glTexStorage3D glad_glTexStorage3D
+GLAD_API_CALL PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample;
+#define glTexStorage3DMultisample glad_glTexStorage3DMultisample
+GLAD_API_CALL PFNGLTEXSTORAGEMEM1DEXTPROC glad_glTexStorageMem1DEXT;
+#define glTexStorageMem1DEXT glad_glTexStorageMem1DEXT
+GLAD_API_CALL PFNGLTEXSTORAGEMEM2DEXTPROC glad_glTexStorageMem2DEXT;
+#define glTexStorageMem2DEXT glad_glTexStorageMem2DEXT
+GLAD_API_CALL PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTexStorageMem2DMultisampleEXT;
+#define glTexStorageMem2DMultisampleEXT glad_glTexStorageMem2DMultisampleEXT
+GLAD_API_CALL PFNGLTEXSTORAGEMEM3DEXTPROC glad_glTexStorageMem3DEXT;
+#define glTexStorageMem3DEXT glad_glTexStorageMem3DEXT
+GLAD_API_CALL PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTexStorageMem3DMultisampleEXT;
+#define glTexStorageMem3DMultisampleEXT glad_glTexStorageMem3DMultisampleEXT
+GLAD_API_CALL PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D;
+#define glTexSubImage1D glad_glTexSubImage1D
+GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D;
+#define glTexSubImage2D glad_glTexSubImage2D
+GLAD_API_CALL PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D;
+#define glTexSubImage3D glad_glTexSubImage3D
+GLAD_API_CALL PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier;
+#define glTextureBarrier glad_glTextureBarrier
+GLAD_API_CALL PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer;
+#define glTextureBuffer glad_glTextureBuffer
+GLAD_API_CALL PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange;
+#define glTextureBufferRange glad_glTextureBufferRange
+GLAD_API_CALL PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv;
+#define glTextureParameterIiv glad_glTextureParameterIiv
+GLAD_API_CALL PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv;
+#define glTextureParameterIuiv glad_glTextureParameterIuiv
+GLAD_API_CALL PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf;
+#define glTextureParameterf glad_glTextureParameterf
+GLAD_API_CALL PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv;
+#define glTextureParameterfv glad_glTextureParameterfv
+GLAD_API_CALL PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri;
+#define glTextureParameteri glad_glTextureParameteri
+GLAD_API_CALL PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv;
+#define glTextureParameteriv glad_glTextureParameteriv
+GLAD_API_CALL PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D;
+#define glTextureStorage1D glad_glTextureStorage1D
+GLAD_API_CALL PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D;
+#define glTextureStorage2D glad_glTextureStorage2D
+GLAD_API_CALL PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample;
+#define glTextureStorage2DMultisample glad_glTextureStorage2DMultisample
+GLAD_API_CALL PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D;
+#define glTextureStorage3D glad_glTextureStorage3D
+GLAD_API_CALL PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample;
+#define glTextureStorage3DMultisample glad_glTextureStorage3DMultisample
+GLAD_API_CALL PFNGLTEXTURESTORAGEMEM1DEXTPROC glad_glTextureStorageMem1DEXT;
+#define glTextureStorageMem1DEXT glad_glTextureStorageMem1DEXT
+GLAD_API_CALL PFNGLTEXTURESTORAGEMEM2DEXTPROC glad_glTextureStorageMem2DEXT;
+#define glTextureStorageMem2DEXT glad_glTextureStorageMem2DEXT
+GLAD_API_CALL PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTextureStorageMem2DMultisampleEXT;
+#define glTextureStorageMem2DMultisampleEXT glad_glTextureStorageMem2DMultisampleEXT
+GLAD_API_CALL PFNGLTEXTURESTORAGEMEM3DEXTPROC glad_glTextureStorageMem3DEXT;
+#define glTextureStorageMem3DEXT glad_glTextureStorageMem3DEXT
+GLAD_API_CALL PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTextureStorageMem3DMultisampleEXT;
+#define glTextureStorageMem3DMultisampleEXT glad_glTextureStorageMem3DMultisampleEXT
+GLAD_API_CALL PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D;
+#define glTextureSubImage1D glad_glTextureSubImage1D
+GLAD_API_CALL PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D;
+#define glTextureSubImage2D glad_glTextureSubImage2D
+GLAD_API_CALL PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D;
+#define glTextureSubImage3D glad_glTextureSubImage3D
+GLAD_API_CALL PFNGLTEXTUREVIEWPROC glad_glTextureView;
+#define glTextureView glad_glTextureView
+GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase;
+#define glTransformFeedbackBufferBase glad_glTransformFeedbackBufferBase
+GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange;
+#define glTransformFeedbackBufferRange glad_glTransformFeedbackBufferRange
+GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings;
+#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings
+GLAD_API_CALL PFNGLUNIFORM1DPROC glad_glUniform1d;
+#define glUniform1d glad_glUniform1d
+GLAD_API_CALL PFNGLUNIFORM1DVPROC glad_glUniform1dv;
+#define glUniform1dv glad_glUniform1dv
+GLAD_API_CALL PFNGLUNIFORM1FPROC glad_glUniform1f;
+#define glUniform1f glad_glUniform1f
+GLAD_API_CALL PFNGLUNIFORM1FVPROC glad_glUniform1fv;
+#define glUniform1fv glad_glUniform1fv
+GLAD_API_CALL PFNGLUNIFORM1IPROC glad_glUniform1i;
+#define glUniform1i glad_glUniform1i
+GLAD_API_CALL PFNGLUNIFORM1IVPROC glad_glUniform1iv;
+#define glUniform1iv glad_glUniform1iv
+GLAD_API_CALL PFNGLUNIFORM1UIPROC glad_glUniform1ui;
+#define glUniform1ui glad_glUniform1ui
+GLAD_API_CALL PFNGLUNIFORM1UIVPROC glad_glUniform1uiv;
+#define glUniform1uiv glad_glUniform1uiv
+GLAD_API_CALL PFNGLUNIFORM2DPROC glad_glUniform2d;
+#define glUniform2d glad_glUniform2d
+GLAD_API_CALL PFNGLUNIFORM2DVPROC glad_glUniform2dv;
+#define glUniform2dv glad_glUniform2dv
+GLAD_API_CALL PFNGLUNIFORM2FPROC glad_glUniform2f;
+#define glUniform2f glad_glUniform2f
+GLAD_API_CALL PFNGLUNIFORM2FVPROC glad_glUniform2fv;
+#define glUniform2fv glad_glUniform2fv
+GLAD_API_CALL PFNGLUNIFORM2IPROC glad_glUniform2i;
+#define glUniform2i glad_glUniform2i
+GLAD_API_CALL PFNGLUNIFORM2IVPROC glad_glUniform2iv;
+#define glUniform2iv glad_glUniform2iv
+GLAD_API_CALL PFNGLUNIFORM2UIPROC glad_glUniform2ui;
+#define glUniform2ui glad_glUniform2ui
+GLAD_API_CALL PFNGLUNIFORM2UIVPROC glad_glUniform2uiv;
+#define glUniform2uiv glad_glUniform2uiv
+GLAD_API_CALL PFNGLUNIFORM3DPROC glad_glUniform3d;
+#define glUniform3d glad_glUniform3d
+GLAD_API_CALL PFNGLUNIFORM3DVPROC glad_glUniform3dv;
+#define glUniform3dv glad_glUniform3dv
+GLAD_API_CALL PFNGLUNIFORM3FPROC glad_glUniform3f;
+#define glUniform3f glad_glUniform3f
+GLAD_API_CALL PFNGLUNIFORM3FVPROC glad_glUniform3fv;
+#define glUniform3fv glad_glUniform3fv
+GLAD_API_CALL PFNGLUNIFORM3IPROC glad_glUniform3i;
+#define glUniform3i glad_glUniform3i
+GLAD_API_CALL PFNGLUNIFORM3IVPROC glad_glUniform3iv;
+#define glUniform3iv glad_glUniform3iv
+GLAD_API_CALL PFNGLUNIFORM3UIPROC glad_glUniform3ui;
+#define glUniform3ui glad_glUniform3ui
+GLAD_API_CALL PFNGLUNIFORM3UIVPROC glad_glUniform3uiv;
+#define glUniform3uiv glad_glUniform3uiv
+GLAD_API_CALL PFNGLUNIFORM4DPROC glad_glUniform4d;
+#define glUniform4d glad_glUniform4d
+GLAD_API_CALL PFNGLUNIFORM4DVPROC glad_glUniform4dv;
+#define glUniform4dv glad_glUniform4dv
+GLAD_API_CALL PFNGLUNIFORM4FPROC glad_glUniform4f;
+#define glUniform4f glad_glUniform4f
+GLAD_API_CALL PFNGLUNIFORM4FVPROC glad_glUniform4fv;
+#define glUniform4fv glad_glUniform4fv
+GLAD_API_CALL PFNGLUNIFORM4IPROC glad_glUniform4i;
+#define glUniform4i glad_glUniform4i
+GLAD_API_CALL PFNGLUNIFORM4IVPROC glad_glUniform4iv;
+#define glUniform4iv glad_glUniform4iv
+GLAD_API_CALL PFNGLUNIFORM4UIPROC glad_glUniform4ui;
+#define glUniform4ui glad_glUniform4ui
+GLAD_API_CALL PFNGLUNIFORM4UIVPROC glad_glUniform4uiv;
+#define glUniform4uiv glad_glUniform4uiv
+GLAD_API_CALL PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding;
+#define glUniformBlockBinding glad_glUniformBlockBinding
+GLAD_API_CALL PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv;
+#define glUniformMatrix2dv glad_glUniformMatrix2dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv;
+#define glUniformMatrix2fv glad_glUniformMatrix2fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv;
+#define glUniformMatrix2x3dv glad_glUniformMatrix2x3dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv;
+#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv;
+#define glUniformMatrix2x4dv glad_glUniformMatrix2x4dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv;
+#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv;
+#define glUniformMatrix3dv glad_glUniformMatrix3dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv;
+#define glUniformMatrix3fv glad_glUniformMatrix3fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv;
+#define glUniformMatrix3x2dv glad_glUniformMatrix3x2dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv;
+#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv;
+#define glUniformMatrix3x4dv glad_glUniformMatrix3x4dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv;
+#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv;
+#define glUniformMatrix4dv glad_glUniformMatrix4dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv;
+#define glUniformMatrix4fv glad_glUniformMatrix4fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv;
+#define glUniformMatrix4x2dv glad_glUniformMatrix4x2dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv;
+#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv;
+#define glUniformMatrix4x3dv glad_glUniformMatrix4x3dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv;
+#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv
+GLAD_API_CALL PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv;
+#define glUniformSubroutinesuiv glad_glUniformSubroutinesuiv
+GLAD_API_CALL PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer;
+#define glUnmapBuffer glad_glUnmapBuffer
+GLAD_API_CALL PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer;
+#define glUnmapNamedBuffer glad_glUnmapNamedBuffer
+GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram;
+#define glUseProgram glad_glUseProgram
+GLAD_API_CALL PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages;
+#define glUseProgramStages glad_glUseProgramStages
+GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram;
+#define glValidateProgram glad_glValidateProgram
+GLAD_API_CALL PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline;
+#define glValidateProgramPipeline glad_glValidateProgramPipeline
+GLAD_API_CALL PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding;
+#define glVertexArrayAttribBinding glad_glVertexArrayAttribBinding
+GLAD_API_CALL PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat;
+#define glVertexArrayAttribFormat glad_glVertexArrayAttribFormat
+GLAD_API_CALL PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat;
+#define glVertexArrayAttribIFormat glad_glVertexArrayAttribIFormat
+GLAD_API_CALL PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat;
+#define glVertexArrayAttribLFormat glad_glVertexArrayAttribLFormat
+GLAD_API_CALL PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor;
+#define glVertexArrayBindingDivisor glad_glVertexArrayBindingDivisor
+GLAD_API_CALL PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer;
+#define glVertexArrayElementBuffer glad_glVertexArrayElementBuffer
+GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer;
+#define glVertexArrayVertexBuffer glad_glVertexArrayVertexBuffer
+GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers;
+#define glVertexArrayVertexBuffers glad_glVertexArrayVertexBuffers
+GLAD_API_CALL PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d;
+#define glVertexAttrib1d glad_glVertexAttrib1d
+GLAD_API_CALL PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv;
+#define glVertexAttrib1dv glad_glVertexAttrib1dv
+GLAD_API_CALL PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f;
+#define glVertexAttrib1f glad_glVertexAttrib1f
+GLAD_API_CALL PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv;
+#define glVertexAttrib1fv glad_glVertexAttrib1fv
+GLAD_API_CALL PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s;
+#define glVertexAttrib1s glad_glVertexAttrib1s
+GLAD_API_CALL PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv;
+#define glVertexAttrib1sv glad_glVertexAttrib1sv
+GLAD_API_CALL PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d;
+#define glVertexAttrib2d glad_glVertexAttrib2d
+GLAD_API_CALL PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv;
+#define glVertexAttrib2dv glad_glVertexAttrib2dv
+GLAD_API_CALL PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f;
+#define glVertexAttrib2f glad_glVertexAttrib2f
+GLAD_API_CALL PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv;
+#define glVertexAttrib2fv glad_glVertexAttrib2fv
+GLAD_API_CALL PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s;
+#define glVertexAttrib2s glad_glVertexAttrib2s
+GLAD_API_CALL PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv;
+#define glVertexAttrib2sv glad_glVertexAttrib2sv
+GLAD_API_CALL PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d;
+#define glVertexAttrib3d glad_glVertexAttrib3d
+GLAD_API_CALL PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv;
+#define glVertexAttrib3dv glad_glVertexAttrib3dv
+GLAD_API_CALL PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f;
+#define glVertexAttrib3f glad_glVertexAttrib3f
+GLAD_API_CALL PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv;
+#define glVertexAttrib3fv glad_glVertexAttrib3fv
+GLAD_API_CALL PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s;
+#define glVertexAttrib3s glad_glVertexAttrib3s
+GLAD_API_CALL PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv;
+#define glVertexAttrib3sv glad_glVertexAttrib3sv
+GLAD_API_CALL PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv;
+#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv
+GLAD_API_CALL PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv;
+#define glVertexAttrib4Niv glad_glVertexAttrib4Niv
+GLAD_API_CALL PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv;
+#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv
+GLAD_API_CALL PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub;
+#define glVertexAttrib4Nub glad_glVertexAttrib4Nub
+GLAD_API_CALL PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv;
+#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv
+GLAD_API_CALL PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv;
+#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv
+GLAD_API_CALL PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv;
+#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv
+GLAD_API_CALL PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv;
+#define glVertexAttrib4bv glad_glVertexAttrib4bv
+GLAD_API_CALL PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d;
+#define glVertexAttrib4d glad_glVertexAttrib4d
+GLAD_API_CALL PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv;
+#define glVertexAttrib4dv glad_glVertexAttrib4dv
+GLAD_API_CALL PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f;
+#define glVertexAttrib4f glad_glVertexAttrib4f
+GLAD_API_CALL PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv;
+#define glVertexAttrib4fv glad_glVertexAttrib4fv
+GLAD_API_CALL PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv;
+#define glVertexAttrib4iv glad_glVertexAttrib4iv
+GLAD_API_CALL PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s;
+#define glVertexAttrib4s glad_glVertexAttrib4s
+GLAD_API_CALL PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv;
+#define glVertexAttrib4sv glad_glVertexAttrib4sv
+GLAD_API_CALL PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv;
+#define glVertexAttrib4ubv glad_glVertexAttrib4ubv
+GLAD_API_CALL PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv;
+#define glVertexAttrib4uiv glad_glVertexAttrib4uiv
+GLAD_API_CALL PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv;
+#define glVertexAttrib4usv glad_glVertexAttrib4usv
+GLAD_API_CALL PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding;
+#define glVertexAttribBinding glad_glVertexAttribBinding
+GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor;
+#define glVertexAttribDivisor glad_glVertexAttribDivisor
+GLAD_API_CALL PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat;
+#define glVertexAttribFormat glad_glVertexAttribFormat
+GLAD_API_CALL PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i;
+#define glVertexAttribI1i glad_glVertexAttribI1i
+GLAD_API_CALL PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv;
+#define glVertexAttribI1iv glad_glVertexAttribI1iv
+GLAD_API_CALL PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui;
+#define glVertexAttribI1ui glad_glVertexAttribI1ui
+GLAD_API_CALL PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv;
+#define glVertexAttribI1uiv glad_glVertexAttribI1uiv
+GLAD_API_CALL PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i;
+#define glVertexAttribI2i glad_glVertexAttribI2i
+GLAD_API_CALL PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv;
+#define glVertexAttribI2iv glad_glVertexAttribI2iv
+GLAD_API_CALL PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui;
+#define glVertexAttribI2ui glad_glVertexAttribI2ui
+GLAD_API_CALL PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv;
+#define glVertexAttribI2uiv glad_glVertexAttribI2uiv
+GLAD_API_CALL PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i;
+#define glVertexAttribI3i glad_glVertexAttribI3i
+GLAD_API_CALL PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv;
+#define glVertexAttribI3iv glad_glVertexAttribI3iv
+GLAD_API_CALL PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui;
+#define glVertexAttribI3ui glad_glVertexAttribI3ui
+GLAD_API_CALL PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv;
+#define glVertexAttribI3uiv glad_glVertexAttribI3uiv
+GLAD_API_CALL PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv;
+#define glVertexAttribI4bv glad_glVertexAttribI4bv
+GLAD_API_CALL PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i;
+#define glVertexAttribI4i glad_glVertexAttribI4i
+GLAD_API_CALL PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv;
+#define glVertexAttribI4iv glad_glVertexAttribI4iv
+GLAD_API_CALL PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv;
+#define glVertexAttribI4sv glad_glVertexAttribI4sv
+GLAD_API_CALL PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv;
+#define glVertexAttribI4ubv glad_glVertexAttribI4ubv
+GLAD_API_CALL PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui;
+#define glVertexAttribI4ui glad_glVertexAttribI4ui
+GLAD_API_CALL PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv;
+#define glVertexAttribI4uiv glad_glVertexAttribI4uiv
+GLAD_API_CALL PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv;
+#define glVertexAttribI4usv glad_glVertexAttribI4usv
+GLAD_API_CALL PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat;
+#define glVertexAttribIFormat glad_glVertexAttribIFormat
+GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer;
+#define glVertexAttribIPointer glad_glVertexAttribIPointer
+GLAD_API_CALL PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d;
+#define glVertexAttribL1d glad_glVertexAttribL1d
+GLAD_API_CALL PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv;
+#define glVertexAttribL1dv glad_glVertexAttribL1dv
+GLAD_API_CALL PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d;
+#define glVertexAttribL2d glad_glVertexAttribL2d
+GLAD_API_CALL PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv;
+#define glVertexAttribL2dv glad_glVertexAttribL2dv
+GLAD_API_CALL PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d;
+#define glVertexAttribL3d glad_glVertexAttribL3d
+GLAD_API_CALL PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv;
+#define glVertexAttribL3dv glad_glVertexAttribL3dv
+GLAD_API_CALL PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d;
+#define glVertexAttribL4d glad_glVertexAttribL4d
+GLAD_API_CALL PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv;
+#define glVertexAttribL4dv glad_glVertexAttribL4dv
+GLAD_API_CALL PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat;
+#define glVertexAttribLFormat glad_glVertexAttribLFormat
+GLAD_API_CALL PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer;
+#define glVertexAttribLPointer glad_glVertexAttribLPointer
+GLAD_API_CALL PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui;
+#define glVertexAttribP1ui glad_glVertexAttribP1ui
+GLAD_API_CALL PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv;
+#define glVertexAttribP1uiv glad_glVertexAttribP1uiv
+GLAD_API_CALL PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui;
+#define glVertexAttribP2ui glad_glVertexAttribP2ui
+GLAD_API_CALL PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv;
+#define glVertexAttribP2uiv glad_glVertexAttribP2uiv
+GLAD_API_CALL PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui;
+#define glVertexAttribP3ui glad_glVertexAttribP3ui
+GLAD_API_CALL PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv;
+#define glVertexAttribP3uiv glad_glVertexAttribP3uiv
+GLAD_API_CALL PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui;
+#define glVertexAttribP4ui glad_glVertexAttribP4ui
+GLAD_API_CALL PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv;
+#define glVertexAttribP4uiv glad_glVertexAttribP4uiv
+GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer;
+#define glVertexAttribPointer glad_glVertexAttribPointer
+GLAD_API_CALL PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor;
+#define glVertexBindingDivisor glad_glVertexBindingDivisor
+GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport;
+#define glViewport glad_glViewport
+GLAD_API_CALL PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv;
+#define glViewportArrayv glad_glViewportArrayv
+GLAD_API_CALL PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf;
+#define glViewportIndexedf glad_glViewportIndexedf
+GLAD_API_CALL PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv;
+#define glViewportIndexedfv glad_glViewportIndexedfv
+GLAD_API_CALL PFNGLWAITSYNCPROC glad_glWaitSync;
+#define glWaitSync glad_glWaitSync
+
+
+GLAD_API_CALL int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr);
+GLAD_API_CALL int gladLoadGL( GLADloadfunc load);
+
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/external/openxr_includes/loader_interfaces.h b/src/external/openxr_includes/loader_interfaces.h
new file mode 100644
index 000000000..3dda953e3
--- /dev/null
+++ b/src/external/openxr_includes/loader_interfaces.h
@@ -0,0 +1,122 @@
+// Copyright (c) 2017 The Khronos Group Inc.
+// Copyright (c) 2017 Valve Corporation
+// Copyright (c) 2017 LunarG, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Author: Mark Young
+//
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Forward declare.
+typedef struct XrApiLayerCreateInfo XrApiLayerCreateInfo;
+
+// Function pointer prototype for the xrCreateApiLayerInstance function used in place of xrCreateInstance.
+// This function allows us to pass special API layer information to each layer during the process of creating an Instance.
+typedef XrResult(XRAPI_PTR *PFN_xrCreateApiLayerInstance)(const XrInstanceCreateInfo *info,
+ const XrApiLayerCreateInfo *apiLayerInfo, XrInstance *instance);
+
+// Loader/API Layer Interface versions
+// 1 - First version, introduces negotiation structure and functions
+#define XR_CURRENT_LOADER_API_LAYER_VERSION 1
+
+// Loader/Runtime Interface versions
+// 1 - First version, introduces negotiation structure and functions
+#define XR_CURRENT_LOADER_RUNTIME_VERSION 1
+
+// Version negotiation values
+typedef enum XrLoaderInterfaceStructs {
+ XR_LOADER_INTERFACE_STRUCT_UNINTIALIZED = 0,
+ XR_LOADER_INTERFACE_STRUCT_LOADER_INFO,
+ XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST,
+ XR_LOADER_INTERFACE_STRUCT_RUNTIME_REQUEST,
+ XR_LOADER_INTERFACE_STRUCT_API_LAYER_CREATE_INFO,
+ XR_LOADER_INTERFACE_STRUCT_API_LAYER_NEXT_INFO,
+} XrLoaderInterfaceStructs;
+
+#define XR_LOADER_INFO_STRUCT_VERSION 1
+typedef struct XrNegotiateLoaderInfo {
+ XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_LOADER_INFO
+ uint32_t structVersion; // XR_LOADER_INFO_STRUCT_VERSION
+ size_t structSize; // sizeof(XrNegotiateLoaderInfo)
+ uint32_t minInterfaceVersion;
+ uint32_t maxInterfaceVersion;
+ uint32_t minXrVersion;
+ uint32_t maxXrVersion;
+} XrNegotiateLoaderInfo;
+
+#define XR_API_LAYER_INFO_STRUCT_VERSION 1
+typedef struct XrNegotiateApiLayerRequest {
+ XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST
+ uint32_t structVersion; // XR_API_LAYER_INFO_STRUCT_VERSION
+ size_t structSize; // sizeof(XrNegotiateApiLayerRequest)
+ uint32_t layerInterfaceVersion; // CURRENT_LOADER_API_LAYER_VERSION
+ uint32_t layerXrVersion;
+ PFN_xrGetInstanceProcAddr getInstanceProcAddr;
+ PFN_xrCreateApiLayerInstance createApiLayerInstance;
+} XrNegotiateApiLayerRequest;
+
+#define XR_RUNTIME_INFO_STRUCT_VERSION 1
+typedef struct XrNegotiateRuntimeRequest {
+ XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_RUNTIME_REQUEST
+ uint32_t structVersion; // XR_RUNTIME_INFO_STRUCT_VERSION
+ size_t structSize; // sizeof(XrNegotiateRuntimeRequest)
+ uint32_t runtimeInterfaceVersion; // CURRENT_LOADER_RUNTIME_VERSION
+ uint32_t runtimeXrVersion;
+ PFN_xrGetInstanceProcAddr getInstanceProcAddr;
+} XrNegotiateRuntimeRequest;
+
+// Function used to negotiate an interface betewen the loader and an API layer. Each library exposing one or
+// more API layers needs to expose at least this function.
+typedef XrResult(XRAPI_PTR *PFN_xrNegotiateLoaderApiLayerInterface)(const XrNegotiateLoaderInfo *loaderInfo,
+ const char *apiLayerName,
+ XrNegotiateApiLayerRequest *apiLayerRequest);
+
+// Function used to negotiate an interface betewen the loader and a runtime. Each runtime should expose
+// at least this function.
+typedef XrResult(XRAPI_PTR *PFN_xrNegotiateLoaderRuntimeInterface)(const XrNegotiateLoaderInfo *loaderInfo,
+ XrNegotiateRuntimeRequest *runtimeRequest);
+
+// Forward declare.
+typedef struct XrApiLayerNextInfo XrApiLayerNextInfo;
+
+#define XR_API_LAYER_NEXT_INFO_STRUCT_VERSION 1
+struct XrApiLayerNextInfo {
+ XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_API_LAYER_NEXT_INFO
+ uint32_t structVersion; // XR_API_LAYER_NEXT_INFO_STRUCT_VERSION
+ size_t structSize; // sizeof(XrApiLayerNextInfo)
+ char layerName[XR_MAX_API_LAYER_NAME_SIZE]; // Name of API layer which should receive this info
+ PFN_xrGetInstanceProcAddr nextGetInstanceProcAddr; // Pointer to next API layer's xrGetInstanceProcAddr
+ PFN_xrCreateApiLayerInstance nextCreateApiLayerInstance; // Pointer to next API layer's xrCreateApiLayerInstance
+ XrApiLayerNextInfo *next; // Pointer to the next API layer info in the sequence
+};
+
+#define XR_API_LAYER_MAX_SETTINGS_PATH_SIZE 512
+#define XR_API_LAYER_CREATE_INFO_STRUCT_VERSION 1
+typedef struct XrApiLayerCreateInfo {
+ XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_API_LAYER_CREATE_INFO
+ uint32_t structVersion; // XR_API_LAYER_CREATE_INFO_STRUCT_VERSION
+ size_t structSize; // sizeof(XrApiLayerCreateInfo)
+ void *loaderInstance; // Pointer to the LoaderInstance class
+ char settings_file_location[XR_API_LAYER_MAX_SETTINGS_PATH_SIZE]; // Location to the found settings file (or empty '\0')
+ XrApiLayerNextInfo *nextInfo; // Pointer to the next API layer's Info
+} XrApiLayerCreateInfo;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/external/openxr_includes/openxr.h b/src/external/openxr_includes/openxr.h
new file mode 100644
index 000000000..4744a7eac
--- /dev/null
+++ b/src/external/openxr_includes/openxr.h
@@ -0,0 +1,1479 @@
+#ifndef OPENXR_H_
+#define OPENXR_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2017-2019 The Khronos Group Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/*
+** This header is generated from the Khronos OpenXR XML API Registry.
+**
+*/
+
+
+
+#define XR_VERSION_0_90 1
+#include "openxr_platform_defines.h"
+#define XR_MAKE_VERSION(major, minor, patch) \
+ (((major) << 22) | ((minor) << 12) | (patch))
+
+// OpenXR current version number.
+#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(0, 90, 0)
+
+#define XR_VERSION_MAJOR(version) ((uint32_t)(version) >> 22)
+#define XR_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
+#define XR_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
+// Version of this file
+#define XR_HEADER_VERSION 42
+
+
+#if !defined(XR_NULL_HANDLE)
+#if (XR_PTR_SIZE == 8) && XR_CPP_NULLPTR_SUPPORTED
+ #define XR_NULL_HANDLE nullptr
+#else
+ #define XR_NULL_HANDLE 0
+#endif
+#endif
+
+
+
+#define XR_NULL_SYSTEM_ID 0
+
+
+#define XR_NULL_PATH 0
+
+
+#define XR_SUCCEEDED(result) ((result) >= 0)
+
+
+#define XR_FAILED(result) ((result) < 0)
+
+
+#define XR_UNQUALIFIED_SUCCESS(result) ((result) == 0)
+
+
+#define XR_NO_DURATION 0
+
+
+#define XR_INFINITE_DURATION 0x7fffffffffffffffLL
+
+
+#define XR_MIN_HAPTIC_DURATION -1
+
+
+#define XR_FREQUENCY_UNSPECIFIED 0
+
+
+#define XR_MAX_EVENT_DATA_SIZE sizeof(XrEventDataBuffer)
+
+
+#if !defined(XR_MAY_ALIAS)
+#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4))
+#define XR_MAY_ALIAS __attribute__((__may_alias__))
+#else
+#define XR_MAY_ALIAS
+#endif
+#endif
+
+
+#if !defined(XR_DEFINE_HANDLE)
+#if (XR_PTR_SIZE == 8)
+ #define XR_DEFINE_HANDLE(object) typedef struct object##_T* object;
+#else
+ #define XR_DEFINE_HANDLE(object) typedef uint64_t object;
+#endif
+#endif
+
+
+
+#if !defined(XR_DEFINE_ATOM)
+ #define XR_DEFINE_ATOM(object) typedef uint64_t object;
+#endif
+
+
+typedef uint64_t XrFlags64;
+XR_DEFINE_ATOM(XrSystemId)
+typedef uint32_t XrBool32;
+XR_DEFINE_ATOM(XrPath)
+typedef int64_t XrTime;
+typedef int64_t XrDuration;
+XR_DEFINE_HANDLE(XrInstance)
+XR_DEFINE_HANDLE(XrSession)
+XR_DEFINE_HANDLE(XrSpace)
+XR_DEFINE_HANDLE(XrAction)
+XR_DEFINE_HANDLE(XrSwapchain)
+XR_DEFINE_HANDLE(XrActionSet)
+#define XR_TRUE 1
+#define XR_FALSE 0
+#define XR_MAX_EXTENSION_NAME_SIZE 128
+#define XR_MAX_API_LAYER_NAME_SIZE 256
+#define XR_MAX_API_LAYER_DESCRIPTION_SIZE 256
+#define XR_MAX_SYSTEM_NAME_SIZE 256
+#define XR_MAX_APPLICATION_NAME_SIZE 128
+#define XR_MAX_ENGINE_NAME_SIZE 128
+#define XR_MAX_RUNTIME_NAME_SIZE 128
+#define XR_MAX_TOUCH_COUNT 2
+#define XR_MAX_ACTION_SOURCES_COUNT 8
+#define XR_MAX_PATH_LENGTH 256
+#define XR_MAX_STRUCTURE_NAME_SIZE 64
+#define XR_MAX_RESULT_STRING_SIZE 64
+#define XR_MIN_COMPOSITION_LAYERS_SUPPORTED 16
+#define XR_MAX_ACTION_SET_NAME_SIZE 64
+#define XR_MAX_LOCALIZED_ACTION_SET_NAME_SIZE 128
+#define XR_MAX_ACTION_NAME_SIZE 64
+#define XR_MAX_LOCALIZED_ACTION_NAME_SIZE 128
+
+typedef enum XrResult {
+ XR_SUCCESS = 0,
+ XR_TIMEOUT_EXPIRED = 1,
+ XR_SESSION_VISIBILITY_UNAVAILABLE = 2,
+ XR_SESSION_LOSS_PENDING = 3,
+ XR_EVENT_UNAVAILABLE = 4,
+ XR_STATE_UNAVAILABLE = 5,
+ XR_STATE_TYPE_UNAVAILABLE = 6,
+ XR_SPACE_BOUNDS_UNAVAILABLE = 7,
+ XR_SESSION_NOT_FOCUSED = 8,
+ XR_FRAME_DISCARDED = 9,
+ XR_ERROR_VALIDATION_FAILURE = -1,
+ XR_ERROR_RUNTIME_FAILURE = -2,
+ XR_ERROR_OUT_OF_MEMORY = -3,
+ XR_ERROR_RUNTIME_VERSION_INCOMPATIBLE = -4,
+ XR_ERROR_DRIVER_INCOMPATIBLE = -5,
+ XR_ERROR_INITIALIZATION_FAILED = -6,
+ XR_ERROR_FUNCTION_UNSUPPORTED = -7,
+ XR_ERROR_FEATURE_UNSUPPORTED = -8,
+ XR_ERROR_EXTENSION_NOT_PRESENT = -9,
+ XR_ERROR_LIMIT_REACHED = -10,
+ XR_ERROR_SIZE_INSUFFICIENT = -11,
+ XR_ERROR_HANDLE_INVALID = -12,
+ XR_ERROR_INSTANCE_LOST = -13,
+ XR_ERROR_SESSION_RUNNING = -14,
+ XR_ERROR_SESSION_NOT_RUNNING = -16,
+ XR_ERROR_SESSION_LOST = -17,
+ XR_ERROR_SYSTEM_INVALID = -18,
+ XR_ERROR_PATH_INVALID = -19,
+ XR_ERROR_PATH_COUNT_EXCEEDED = -20,
+ XR_ERROR_PATH_FORMAT_INVALID = -21,
+ XR_ERROR_LAYER_INVALID = -22,
+ XR_ERROR_LAYER_LIMIT_EXCEEDED = -23,
+ XR_ERROR_SWAPCHAIN_RECT_INVALID = -25,
+ XR_ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED = -26,
+ XR_ERROR_ACTION_TYPE_MISMATCH = -27,
+ XR_ERROR_REFERENCE_SPACE_UNSUPPORTED = -31,
+ XR_ERROR_FILE_ACCESS_ERROR = -32,
+ XR_ERROR_FILE_CONTENTS_INVALID = -33,
+ XR_ERROR_FORM_FACTOR_UNSUPPORTED = -34,
+ XR_ERROR_FORM_FACTOR_UNAVAILABLE = -35,
+ XR_ERROR_API_LAYER_NOT_PRESENT = -36,
+ XR_ERROR_CALL_ORDER_INVALID = -37,
+ XR_ERROR_GRAPHICS_DEVICE_INVALID = -38,
+ XR_ERROR_POSE_INVALID = -39,
+ XR_ERROR_INDEX_OUT_OF_RANGE = -40,
+ XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED = -41,
+ XR_ERROR_ENVIRONMENT_BLEND_MODE_UNSUPPORTED = -42,
+ XR_ERROR_BINDINGS_DUPLICATED = -43,
+ XR_ERROR_NAME_DUPLICATED = -44,
+ XR_ERROR_NAME_INVALID = -45,
+ XR_ERROR_ANDROID_THREAD_SETTINGS_ID_INVALID_KHR = -1000003000,
+ XR_ERROR_ANDROID_THREAD_SETTINGS_FAILURE_KHR = -1000003001,
+ XR_ERROR_DEBUG_UTILS_MESSENGER_INVALID_EXT = -1000019000,
+ XR_RESULT_MAX_ENUM = 0x7FFFFFFF
+} XrResult;
+
+typedef enum XrStructureType {
+ XR_TYPE_UNKNOWN = 0,
+ XR_TYPE_API_LAYER_PROPERTIES = 1,
+ XR_TYPE_EXTENSION_PROPERTIES = 2,
+ XR_TYPE_INSTANCE_CREATE_INFO = 3,
+ XR_TYPE_SYSTEM_GET_INFO = 4,
+ XR_TYPE_SYSTEM_PROPERTIES = 5,
+ XR_TYPE_VIEW_LOCATE_INFO = 6,
+ XR_TYPE_VIEW = 7,
+ XR_TYPE_SESSION_CREATE_INFO = 8,
+ XR_TYPE_SWAPCHAIN_CREATE_INFO = 9,
+ XR_TYPE_SESSION_BEGIN_INFO = 10,
+ XR_TYPE_VIEW_STATE = 11,
+ XR_TYPE_FRAME_END_INFO = 12,
+ XR_TYPE_HAPTIC_VIBRATION = 13,
+ XR_TYPE_EVENT_DATA_BUFFER = 16,
+ XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING = 17,
+ XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED = 18,
+ XR_TYPE_ACTION_STATE_BOOLEAN = 23,
+ XR_TYPE_ACTION_STATE_VECTOR1F = 24,
+ XR_TYPE_ACTION_STATE_VECTOR2F = 25,
+ XR_TYPE_ACTION_STATE_POSE = 27,
+ XR_TYPE_ACTION_SET_CREATE_INFO = 28,
+ XR_TYPE_ACTION_CREATE_INFO = 29,
+ XR_TYPE_INSTANCE_PROPERTIES = 32,
+ XR_TYPE_FRAME_WAIT_INFO = 33,
+ XR_TYPE_COMPOSITION_LAYER_PROJECTION = 35,
+ XR_TYPE_COMPOSITION_LAYER_QUAD = 36,
+ XR_TYPE_REFERENCE_SPACE_CREATE_INFO = 37,
+ XR_TYPE_ACTION_SPACE_CREATE_INFO = 38,
+ XR_TYPE_SPACE_RELATION = 39,
+ XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING = 40,
+ XR_TYPE_VIEW_CONFIGURATION_VIEW = 41,
+ XR_TYPE_FRAME_STATE = 44,
+ XR_TYPE_VIEW_CONFIGURATION_PROPERTIES = 45,
+ XR_TYPE_FRAME_BEGIN_INFO = 46,
+ XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW = 48,
+ XR_TYPE_EVENT_DATA_EVENTS_LOST = 49,
+ XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING = 51,
+ XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED = 52,
+ XR_TYPE_INTERACTION_PROFILE_INFO = 53,
+ XR_TYPE_ACTIVE_ACTION_SET = 54,
+ XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO = 55,
+ XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO = 56,
+ XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO = 57,
+ XR_TYPE_COMPOSITION_LAYER_CUBE_KHR = 1000006000,
+ XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR = 1000008000,
+ XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR = 1000010000,
+ XR_TYPE_VULKAN_SWAPCHAIN_FORMAT_LIST_CREATE_INFO_KHR = 1000014000,
+ XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT = 1000015000,
+ XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR = 1000017000,
+ XR_TYPE_COMPOSITION_LAYER_EQUIRECT_KHR = 1000018000,
+ XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000019000,
+ XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000019001,
+ XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000019002,
+ XR_TYPE_DEBUG_UTILS_LABEL_EXT = 1000019003,
+ XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR = 1000023000,
+ XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR = 1000023001,
+ XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR = 1000023002,
+ XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR = 1000023003,
+ XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR = 1000023004,
+ XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR = 1000023005,
+ XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR = 1000024001,
+ XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR = 1000024002,
+ XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR = 1000024003,
+ XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR = 1000025000,
+ XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR = 1000025001,
+ XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR = 1000025002,
+ XR_TYPE_GRAPHICS_BINDING_D3D10_KHR = 1000026000,
+ XR_TYPE_SWAPCHAIN_IMAGE_D3D10_KHR = 1000026001,
+ XR_TYPE_GRAPHICS_REQUIREMENTS_D3D10_KHR = 1000026002,
+ XR_TYPE_GRAPHICS_BINDING_D3D11_KHR = 1000027000,
+ XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR = 1000027001,
+ XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR = 1000027002,
+ XR_TYPE_GRAPHICS_BINDING_D3D12_KHR = 1000028000,
+ XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR = 1000028001,
+ XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR = 1000028002,
+ XR_TYPE_VISIBILITY_MASK_KHR = 1000031000,
+ XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR = 1000031001,
+ XR_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} XrStructureType;
+
+typedef enum XrFormFactor {
+ XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY = 1,
+ XR_FORM_FACTOR_HANDHELD_DISPLAY = 2,
+ XR_FORM_FACTOR_MAX_ENUM = 0x7FFFFFFF
+} XrFormFactor;
+
+typedef enum XrEnvironmentBlendMode {
+ XR_ENVIRONMENT_BLEND_MODE_OPAQUE = 1,
+ XR_ENVIRONMENT_BLEND_MODE_ADDITIVE = 2,
+ XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND = 3,
+ XR_ENVIRONMENT_BLEND_MODE_MAX_ENUM = 0x7FFFFFFF
+} XrEnvironmentBlendMode;
+
+typedef enum XrReferenceSpaceType {
+ XR_REFERENCE_SPACE_TYPE_VIEW = 1,
+ XR_REFERENCE_SPACE_TYPE_LOCAL = 2,
+ XR_REFERENCE_SPACE_TYPE_STAGE = 3,
+ XR_REFERENCE_SPACE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} XrReferenceSpaceType;
+
+typedef enum XrViewConfigurationType {
+ XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO = 1,
+ XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO = 2,
+ XR_VIEW_CONFIGURATION_TYPE_MAX_ENUM = 0x7FFFFFFF
+} XrViewConfigurationType;
+
+typedef enum XrActionType {
+ XR_INPUT_ACTION_TYPE_BOOLEAN = 1,
+ XR_INPUT_ACTION_TYPE_VECTOR1F = 2,
+ XR_INPUT_ACTION_TYPE_VECTOR2F = 3,
+ XR_INPUT_ACTION_TYPE_POSE = 4,
+ XR_OUTPUT_ACTION_TYPE_VIBRATION = 100,
+ XR_ACTION_TYPE_MAX_ENUM = 0x7FFFFFFF
+} XrActionType;
+
+typedef enum XrEyeVisibility {
+ XR_EYE_VISIBILITY_BOTH = 0,
+ XR_EYE_VISIBILITY_LEFT = 1,
+ XR_EYE_VISIBILITY_RIGHT = 2,
+ XR_EYE_VISIBILITY_MAX_ENUM = 0x7FFFFFFF
+} XrEyeVisibility;
+
+typedef enum XrSessionState {
+ XR_SESSION_STATE_UNKNOWN = 0,
+ XR_SESSION_STATE_IDLE = 1,
+ XR_SESSION_STATE_READY = 2,
+ XR_SESSION_STATE_RUNNING = 3,
+ XR_SESSION_STATE_VISIBLE = 4,
+ XR_SESSION_STATE_FOCUSED = 5,
+ XR_SESSION_STATE_STOPPING = 6,
+ XR_SESSION_STATE_LOSS_PENDING = 7,
+ XR_SESSION_STATE_EXITING = 8,
+ XR_SESSION_STATE_MAX_ENUM = 0x7FFFFFFF
+} XrSessionState;
+
+typedef enum XrObjectType {
+ XR_OBJECT_TYPE_UNKNOWN = 0,
+ XR_OBJECT_TYPE_INSTANCE = 1,
+ XR_OBJECT_TYPE_SESSION = 2,
+ XR_OBJECT_TYPE_SWAPCHAIN = 3,
+ XR_OBJECT_TYPE_SPACE = 4,
+ XR_OBJECT_TYPE_ACTION_SET = 5,
+ XR_OBJECT_TYPE_ACTION = 6,
+ XR_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000019000,
+ XR_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF
+} XrObjectType;
+typedef XrFlags64 XrInstanceCreateFlags;
+
+// Flag bits for XrInstanceCreateFlags
+
+typedef XrFlags64 XrSessionCreateFlags;
+
+// Flag bits for XrSessionCreateFlags
+
+typedef XrFlags64 XrSpaceRelationFlags;
+
+// Flag bits for XrSpaceRelationFlags
+static const XrSpaceRelationFlags XR_SPACE_RELATION_ORIENTATION_VALID_BIT = 0x00000001;
+static const XrSpaceRelationFlags XR_SPACE_RELATION_POSITION_VALID_BIT = 0x00000002;
+static const XrSpaceRelationFlags XR_SPACE_RELATION_LINEAR_VELOCITY_VALID_BIT = 0x00000004;
+static const XrSpaceRelationFlags XR_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT = 0x00000008;
+static const XrSpaceRelationFlags XR_SPACE_RELATION_LINEAR_ACCELERATION_VALID_BIT = 0x00000010;
+static const XrSpaceRelationFlags XR_SPACE_RELATION_ANGULAR_ACCELERATION_VALID_BIT = 0x00000020;
+static const XrSpaceRelationFlags XR_SPACE_RELATION_ORIENTATION_TRACKED_BIT = 0x00000040;
+static const XrSpaceRelationFlags XR_SPACE_RELATION_POSITION_TRACKED_BIT = 0x00000080;
+
+typedef XrFlags64 XrSwapchainCreateFlags;
+
+// Flag bits for XrSwapchainCreateFlags
+static const XrSwapchainCreateFlags XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT = 0x00000001;
+static const XrSwapchainCreateFlags XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT = 0x00000002;
+
+typedef XrFlags64 XrSwapchainUsageFlags;
+
+// Flag bits for XrSwapchainUsageFlags
+static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT = 0x00000001;
+static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000002;
+static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT = 0x00000004;
+static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT = 0x00000008;
+static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT = 0x00000010;
+static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_SAMPLED_BIT = 0x00000020;
+static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT = 0x00000040;
+
+typedef XrFlags64 XrCompositionLayerFlags;
+
+// Flag bits for XrCompositionLayerFlags
+static const XrCompositionLayerFlags XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT = 0x00000001;
+static const XrCompositionLayerFlags XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT = 0x00000002;
+
+typedef XrFlags64 XrViewStateFlags;
+
+// Flag bits for XrViewStateFlags
+static const XrViewStateFlags XR_VIEW_STATE_ORIENTATION_VALID_BIT = 0x00000001;
+static const XrViewStateFlags XR_VIEW_STATE_POSITION_VALID_BIT = 0x00000002;
+static const XrViewStateFlags XR_VIEW_STATE_ORIENTATION_TRACKED_BIT = 0x00000004;
+static const XrViewStateFlags XR_VIEW_STATE_POSITION_TRACKED_BIT = 0x00000008;
+
+typedef XrFlags64 XrInputSourceLocalizedNameFlags;
+
+// Flag bits for XrInputSourceLocalizedNameFlags
+static const XrInputSourceLocalizedNameFlags XR_INPUT_SOURCE_LOCALIZED_NAME_USER_PATH_BIT = 0x00000001;
+static const XrInputSourceLocalizedNameFlags XR_INPUT_SOURCE_LOCALIZED_NAME_INTERACTION_PROFILE_BIT = 0x00000002;
+static const XrInputSourceLocalizedNameFlags XR_INPUT_SOURCE_LOCALIZED_NAME_COMPONENT_BIT = 0x00000004;
+
+typedef void (XRAPI_PTR *PFN_xrVoidFunction)(void);
+typedef struct XrApiLayerProperties {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ char layerName[XR_MAX_API_LAYER_NAME_SIZE];
+ uint32_t specVersion;
+ uint32_t implementationVersion;
+ char description[XR_MAX_API_LAYER_DESCRIPTION_SIZE];
+} XrApiLayerProperties;
+
+typedef struct XrExtensionProperties {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ char extensionName[XR_MAX_EXTENSION_NAME_SIZE];
+ uint32_t specVersion;
+} XrExtensionProperties;
+
+typedef struct XrApplicationInfo {
+ char applicationName[XR_MAX_APPLICATION_NAME_SIZE];
+ uint32_t applicationVersion;
+ char engineName[XR_MAX_ENGINE_NAME_SIZE];
+ uint32_t engineVersion;
+ uint32_t apiVersion;
+} XrApplicationInfo;
+
+typedef struct XrInstanceCreateInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrInstanceCreateFlags createFlags;
+ XrApplicationInfo applicationInfo;
+ uint32_t enabledApiLayerCount;
+ const char* const* enabledApiLayerNames;
+ uint32_t enabledExtensionCount;
+ const char* const* enabledExtensionNames;
+} XrInstanceCreateInfo;
+
+typedef struct XrInstanceProperties {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t runtimeVersion;
+ char runtimeName[XR_MAX_RUNTIME_NAME_SIZE];
+} XrInstanceProperties;
+
+typedef struct XrEventDataBuffer {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ uint8_t varying[4000];
+} XrEventDataBuffer;
+
+typedef struct XrSystemGetInfo {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrFormFactor formFactor;
+} XrSystemGetInfo;
+
+typedef struct XrSystemGraphicsProperties {
+ uint32_t maxSwapchainImageHeight;
+ uint32_t maxSwapchainImageWidth;
+ uint32_t maxViewCount;
+ uint32_t maxLayerCount;
+} XrSystemGraphicsProperties;
+
+typedef struct XrSystemTrackingProperties {
+ XrBool32 orientationTracking;
+ XrBool32 positionTracking;
+} XrSystemTrackingProperties;
+
+typedef struct XrSystemProperties {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrSystemId systemId;
+ uint32_t vendorId;
+ char systemName[XR_MAX_SYSTEM_NAME_SIZE];
+ XrSystemGraphicsProperties graphicsProperties;
+ XrSystemTrackingProperties trackingProperties;
+} XrSystemProperties;
+
+typedef struct XrSessionCreateInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrSessionCreateFlags createFlags;
+ XrSystemId systemId;
+} XrSessionCreateInfo;
+
+typedef struct XrQuaternionf {
+ float x;
+ float y;
+ float z;
+ float w;
+} XrQuaternionf;
+
+typedef struct XrVector3f {
+ float x;
+ float y;
+ float z;
+} XrVector3f;
+
+typedef struct XrPosef {
+ XrQuaternionf orientation;
+ XrVector3f position;
+} XrPosef;
+
+typedef struct XrReferenceSpaceCreateInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrReferenceSpaceType referenceSpaceType;
+ XrPosef poseInReferenceSpace;
+} XrReferenceSpaceCreateInfo;
+
+typedef struct XrExtent2Df {
+ float width;
+ float height;
+} XrExtent2Df;
+
+typedef struct XrActionSpaceCreateInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrPath subactionPath;
+ XrPosef poseInActionSpace;
+} XrActionSpaceCreateInfo;
+
+typedef struct XrSpaceRelation {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrSpaceRelationFlags relationFlags;
+ XrTime time;
+ XrPosef pose;
+ XrVector3f linearVelocity;
+ XrVector3f angularVelocity;
+ XrVector3f linearAcceleration;
+ XrVector3f angularAcceleration;
+} XrSpaceRelation;
+
+typedef struct XrViewConfigurationProperties {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrViewConfigurationType viewConfigurationType;
+ XrBool32 fovMutable;
+} XrViewConfigurationProperties;
+
+typedef struct XrViewConfigurationView {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t recommendedImageRectWidth;
+ uint32_t maxImageRectWidth;
+ uint32_t recommendedImageRectHeight;
+ uint32_t maxImageRectHeight;
+ uint32_t recommendedSwapchainSampleCount;
+ uint32_t maxSwapchainSampleCount;
+} XrViewConfigurationView;
+
+typedef struct XrSwapchainCreateInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrSwapchainCreateFlags createFlags;
+ XrSwapchainUsageFlags usageFlags;
+ int64_t format;
+ uint32_t sampleCount;
+ uint32_t width;
+ uint32_t height;
+ uint32_t faceCount;
+ uint32_t arraySize;
+ uint32_t mipCount;
+} XrSwapchainCreateInfo;
+
+typedef struct XR_MAY_ALIAS XrSwapchainImageBaseHeader {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+} XrSwapchainImageBaseHeader;
+
+typedef struct XrSwapchainImageAcquireInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+} XrSwapchainImageAcquireInfo;
+
+typedef struct XrSwapchainImageWaitInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrDuration timeout;
+} XrSwapchainImageWaitInfo;
+
+typedef struct XrSwapchainImageReleaseInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+} XrSwapchainImageReleaseInfo;
+
+typedef struct XrSessionBeginInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrViewConfigurationType primaryViewConfigurationType;
+} XrSessionBeginInfo;
+
+typedef struct XrFrameWaitInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+} XrFrameWaitInfo;
+
+typedef struct XrFrameState {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrTime predictedDisplayTime;
+ XrDuration predictedDisplayPeriod;
+} XrFrameState;
+
+typedef struct XrFrameBeginInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+} XrFrameBeginInfo;
+
+typedef struct XR_MAY_ALIAS XrCompositionLayerBaseHeader {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrCompositionLayerFlags layerFlags;
+ XrSpace space;
+} XrCompositionLayerBaseHeader;
+
+typedef struct XrFrameEndInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrTime displayTime;
+ XrEnvironmentBlendMode environmentBlendMode;
+ uint32_t layerCount;
+ const XrCompositionLayerBaseHeader* const* layers;
+} XrFrameEndInfo;
+
+typedef struct XrViewLocateInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrTime displayTime;
+ XrSpace space;
+} XrViewLocateInfo;
+
+typedef struct XrViewState {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrViewStateFlags viewStateFlags;
+} XrViewState;
+
+typedef struct XrFovf {
+ float angleLeft;
+ float angleRight;
+ float angleUp;
+ float angleDown;
+} XrFovf;
+
+typedef struct XrView {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrPosef pose;
+ XrFovf fov;
+} XrView;
+
+typedef struct XrActionSetCreateInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ char actionSetName[XR_MAX_ACTION_SET_NAME_SIZE];
+ char localizedActionSetName[XR_MAX_LOCALIZED_ACTION_SET_NAME_SIZE];
+ uint32_t priority;
+} XrActionSetCreateInfo;
+
+typedef struct XrActionCreateInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ char actionName[XR_MAX_ACTION_NAME_SIZE];
+ XrActionType actionType;
+ uint32_t countSubactionPaths;
+ const XrPath* subactionPaths;
+ char localizedActionName[XR_MAX_LOCALIZED_ACTION_NAME_SIZE];
+} XrActionCreateInfo;
+
+typedef struct XrActionSuggestedBinding {
+ XrAction action;
+ XrPath binding;
+} XrActionSuggestedBinding;
+
+typedef struct XrInteractionProfileSuggestedBinding {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrPath interactionProfile;
+ uint32_t countSuggestedBindings;
+ const XrActionSuggestedBinding* suggestedBindings;
+} XrInteractionProfileSuggestedBinding;
+
+typedef struct XrInteractionProfileInfo {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrPath interactionProfile;
+} XrInteractionProfileInfo;
+
+typedef struct XrActionStateBoolean {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrBool32 currentState;
+ XrBool32 changedSinceLastSync;
+ XrTime lastChangeTime;
+ XrBool32 isActive;
+} XrActionStateBoolean;
+
+typedef struct XrActionStateVector1f {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ float currentState;
+ XrBool32 changedSinceLastSync;
+ XrTime lastChangeTime;
+ XrBool32 isActive;
+} XrActionStateVector1f;
+
+typedef struct XrVector2f {
+ float x;
+ float y;
+} XrVector2f;
+
+typedef struct XrActionStateVector2f {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrVector2f currentState;
+ XrBool32 changedSinceLastSync;
+ XrTime lastChangeTime;
+ XrBool32 isActive;
+} XrActionStateVector2f;
+
+typedef struct XrActionStatePose {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrBool32 isActive;
+} XrActionStatePose;
+
+typedef struct XrActiveActionSet {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrActionSet actionSet;
+ XrPath subactionPath;
+} XrActiveActionSet;
+
+typedef struct XR_MAY_ALIAS XrHapticBaseHeader {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+} XrHapticBaseHeader;
+
+typedef struct XR_MAY_ALIAS XrBaseInStructure {
+ XrStructureType type;
+ const struct XrBaseInStructure* next;
+} XrBaseInStructure;
+
+typedef struct XR_MAY_ALIAS XrBaseOutStructure {
+ XrStructureType type;
+ struct XrBaseOutStructure* next;
+} XrBaseOutStructure;
+
+typedef struct XrOffset2Di {
+ int32_t x;
+ int32_t y;
+} XrOffset2Di;
+
+typedef struct XrExtent2Di {
+ int32_t width;
+ int32_t height;
+} XrExtent2Di;
+
+typedef struct XrRect2Di {
+ XrOffset2Di offset;
+ XrExtent2Di extent;
+} XrRect2Di;
+
+typedef struct XrSwapchainSubImage {
+ XrSwapchain swapchain;
+ XrRect2Di imageRect;
+ uint32_t imageArrayIndex;
+} XrSwapchainSubImage;
+
+typedef struct XrCompositionLayerProjectionView {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrPosef pose;
+ XrFovf fov;
+ XrSwapchainSubImage subImage;
+} XrCompositionLayerProjectionView;
+
+typedef struct XrCompositionLayerProjection {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrCompositionLayerFlags layerFlags;
+ XrSpace space;
+ uint32_t viewCount;
+ const XrCompositionLayerProjectionView* views;
+} XrCompositionLayerProjection;
+
+typedef struct XrCompositionLayerQuad {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrCompositionLayerFlags layerFlags;
+ XrSpace space;
+ XrEyeVisibility eyeVisibility;
+ XrSwapchainSubImage subImage;
+ XrPosef pose;
+ XrVector2f size;
+} XrCompositionLayerQuad;
+
+typedef struct XR_MAY_ALIAS XrEventDataBaseHeader {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+} XrEventDataBaseHeader;
+
+typedef struct XrEventDataEventsLost {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ uint32_t lostEventCount;
+} XrEventDataEventsLost;
+
+typedef struct XrEventDataInstanceLossPending {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrTime lossTime;
+} XrEventDataInstanceLossPending;
+
+typedef struct XrEventDataSessionStateChanged {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrSession session;
+ XrSessionState state;
+ XrTime time;
+} XrEventDataSessionStateChanged;
+
+typedef struct XrEventDataReferenceSpaceChangePending {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrReferenceSpaceType referenceSpaceType;
+ XrTime changeTime;
+ XrBool32 poseValid;
+ XrPosef poseInPreviousSpace;
+} XrEventDataReferenceSpaceChangePending;
+
+typedef struct XrEventDataInteractionProfileChanged {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+} XrEventDataInteractionProfileChanged;
+
+typedef struct XrHapticVibration {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrDuration duration;
+ float frequency;
+ float amplitude;
+} XrHapticVibration;
+
+typedef struct XrOffset2Df {
+ float x;
+ float y;
+} XrOffset2Df;
+
+typedef struct XrRect2Df {
+ XrOffset2Df offset;
+ XrExtent2Df extent;
+} XrRect2Df;
+
+typedef struct XrVector4f {
+ float x;
+ float y;
+ float z;
+ float w;
+} XrVector4f;
+
+typedef struct XrColor4f {
+ float r;
+ float g;
+ float b;
+ float a;
+} XrColor4f;
+
+typedef XrResult (XRAPI_PTR *PFN_xrGetInstanceProcAddr)(XrInstance instance, const char* name, PFN_xrVoidFunction* function);
+typedef XrResult (XRAPI_PTR *PFN_xrEnumerateApiLayerProperties)(uint32_t propertyCapacityInput, uint32_t* propertyCountOutput, XrApiLayerProperties* properties);
+typedef XrResult (XRAPI_PTR *PFN_xrEnumerateInstanceExtensionProperties)(const char* layerName, uint32_t propertyCapacityInput, uint32_t* propertyCountOutput, XrExtensionProperties* properties);
+typedef XrResult (XRAPI_PTR *PFN_xrCreateInstance)(const XrInstanceCreateInfo* createInfo, XrInstance* instance);
+typedef XrResult (XRAPI_PTR *PFN_xrDestroyInstance)(XrInstance instance);
+typedef XrResult (XRAPI_PTR *PFN_xrGetInstanceProperties)(XrInstance instance, XrInstanceProperties* instanceProperties);
+typedef XrResult (XRAPI_PTR *PFN_xrPollEvent)(XrInstance instance, XrEventDataBuffer* eventData);
+typedef XrResult (XRAPI_PTR *PFN_xrResultToString)(XrInstance instance, XrResult value, char buffer[XR_MAX_RESULT_STRING_SIZE]);
+typedef XrResult (XRAPI_PTR *PFN_xrStructureTypeToString)(XrInstance instance, XrStructureType value, char buffer[XR_MAX_STRUCTURE_NAME_SIZE]);
+typedef XrResult (XRAPI_PTR *PFN_xrGetSystem)(XrInstance instance, const XrSystemGetInfo* getInfo, XrSystemId* systemId);
+typedef XrResult (XRAPI_PTR *PFN_xrGetSystemProperties)(XrInstance instance, XrSystemId systemId, XrSystemProperties* properties);
+typedef XrResult (XRAPI_PTR *PFN_xrEnumerateEnvironmentBlendModes)(XrInstance instance, XrSystemId systemId, uint32_t environmentBlendModeCapacityInput, uint32_t* environmentBlendModeCountOutput, XrEnvironmentBlendMode* environmentBlendModes);
+typedef XrResult (XRAPI_PTR *PFN_xrCreateSession)(XrInstance instance, const XrSessionCreateInfo* createInfo, XrSession* session);
+typedef XrResult (XRAPI_PTR *PFN_xrDestroySession)(XrSession session);
+typedef XrResult (XRAPI_PTR *PFN_xrEnumerateReferenceSpaces)(XrSession session, uint32_t spaceCapacityInput, uint32_t* spaceCountOutput, XrReferenceSpaceType* spaces);
+typedef XrResult (XRAPI_PTR *PFN_xrCreateReferenceSpace)(XrSession session, const XrReferenceSpaceCreateInfo* createInfo, XrSpace* space);
+typedef XrResult (XRAPI_PTR *PFN_xrGetReferenceSpaceBoundsRect)(XrSession session, XrReferenceSpaceType referenceSpaceType, XrExtent2Df* bounds);
+typedef XrResult (XRAPI_PTR *PFN_xrCreateActionSpace)(XrAction action, const XrActionSpaceCreateInfo* createInfo, XrSpace* space);
+typedef XrResult (XRAPI_PTR *PFN_xrLocateSpace)(XrSpace space, XrSpace baseSpace, XrTime time, XrSpaceRelation* relation);
+typedef XrResult (XRAPI_PTR *PFN_xrDestroySpace)(XrSpace space);
+typedef XrResult (XRAPI_PTR *PFN_xrEnumerateViewConfigurations)(XrInstance instance, XrSystemId systemId, uint32_t viewConfigurationTypeCapacityInput, uint32_t* viewConfigurationTypeCountOutput, XrViewConfigurationType* viewConfigurationTypes);
+typedef XrResult (XRAPI_PTR *PFN_xrGetViewConfigurationProperties)(XrInstance instance, XrSystemId systemId, XrViewConfigurationType viewConfigurationType, XrViewConfigurationProperties* configurationProperties);
+typedef XrResult (XRAPI_PTR *PFN_xrEnumerateViewConfigurationViews)(XrInstance instance, XrSystemId systemId, XrViewConfigurationType viewConfigurationType, uint32_t viewCapacityInput, uint32_t* viewCountOutput, XrViewConfigurationView* views);
+typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSwapchainFormats)(XrSession session, uint32_t formatCapacityInput, uint32_t* formatCountOutput, int64_t* formats);
+typedef XrResult (XRAPI_PTR *PFN_xrCreateSwapchain)(XrSession session, const XrSwapchainCreateInfo* createInfo, XrSwapchain* swapchain);
+typedef XrResult (XRAPI_PTR *PFN_xrDestroySwapchain)(XrSwapchain swapchain);
+typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSwapchainImages)(XrSwapchain swapchain, uint32_t imageCapacityInput, uint32_t* imageCountOutput, XrSwapchainImageBaseHeader* images);
+typedef XrResult (XRAPI_PTR *PFN_xrAcquireSwapchainImage)(XrSwapchain swapchain, const XrSwapchainImageAcquireInfo* acquireInfo, uint32_t* index);
+typedef XrResult (XRAPI_PTR *PFN_xrWaitSwapchainImage)(XrSwapchain swapchain, const XrSwapchainImageWaitInfo* waitInfo);
+typedef XrResult (XRAPI_PTR *PFN_xrReleaseSwapchainImage)(XrSwapchain swapchain, const XrSwapchainImageReleaseInfo* releaseInfo);
+typedef XrResult (XRAPI_PTR *PFN_xrBeginSession)(XrSession session, const XrSessionBeginInfo* beginInfo);
+typedef XrResult (XRAPI_PTR *PFN_xrEndSession)(XrSession session);
+typedef XrResult (XRAPI_PTR *PFN_xrWaitFrame)(XrSession session, const XrFrameWaitInfo* frameWaitInfo, XrFrameState* frameState);
+typedef XrResult (XRAPI_PTR *PFN_xrBeginFrame)(XrSession session, const XrFrameBeginInfo* frameBeginInfo);
+typedef XrResult (XRAPI_PTR *PFN_xrEndFrame)(XrSession session, const XrFrameEndInfo* frameEndInfo);
+typedef XrResult (XRAPI_PTR *PFN_xrLocateViews)(XrSession session, const XrViewLocateInfo* viewLocateInfo, XrViewState* viewState, uint32_t viewCapacityInput, uint32_t* viewCountOutput, XrView* views);
+typedef XrResult (XRAPI_PTR *PFN_xrStringToPath)(XrInstance instance, const char* pathString, XrPath* path);
+typedef XrResult (XRAPI_PTR *PFN_xrPathToString)(XrInstance instance, XrPath path, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, char* buffer);
+typedef XrResult (XRAPI_PTR *PFN_xrCreateActionSet)(XrSession session, const XrActionSetCreateInfo* createInfo, XrActionSet* actionSet);
+typedef XrResult (XRAPI_PTR *PFN_xrDestroyActionSet)(XrActionSet actionSet);
+typedef XrResult (XRAPI_PTR *PFN_xrCreateAction)(XrActionSet actionSet, const XrActionCreateInfo* createInfo, XrAction* action);
+typedef XrResult (XRAPI_PTR *PFN_xrDestroyAction)(XrAction action);
+typedef XrResult (XRAPI_PTR *PFN_xrSetInteractionProfileSuggestedBindings)(XrSession session, const XrInteractionProfileSuggestedBinding* suggestedBindings);
+typedef XrResult (XRAPI_PTR *PFN_xrGetCurrentInteractionProfile)(XrSession session, XrPath topLevelUserPath, XrInteractionProfileInfo* interactionProfile);
+typedef XrResult (XRAPI_PTR *PFN_xrGetActionStateBoolean)(XrAction action, uint32_t countSubactionPaths, const XrPath* subactionPaths, XrActionStateBoolean* data);
+typedef XrResult (XRAPI_PTR *PFN_xrGetActionStateVector1f)(XrAction action, uint32_t countSubactionPaths, const XrPath* subactionPaths, XrActionStateVector1f* data);
+typedef XrResult (XRAPI_PTR *PFN_xrGetActionStateVector2f)(XrAction action, uint32_t countSubactionPaths, const XrPath* subactionPaths, XrActionStateVector2f* data);
+typedef XrResult (XRAPI_PTR *PFN_xrGetActionStatePose)(XrAction action, XrPath subactionPath, XrActionStatePose* data);
+typedef XrResult (XRAPI_PTR *PFN_xrSyncActionData)(XrSession session, uint32_t countActionSets, const XrActiveActionSet* actionSets);
+typedef XrResult (XRAPI_PTR *PFN_xrGetBoundSourcesForAction)(XrAction action, uint32_t sourceCapacityInput, uint32_t* sourceCountOutput, XrPath* sources);
+typedef XrResult (XRAPI_PTR *PFN_xrGetInputSourceLocalizedName)(XrSession session, XrPath source, XrInputSourceLocalizedNameFlags whichComponents, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, char* buffer);
+typedef XrResult (XRAPI_PTR *PFN_xrApplyHapticFeedback)(XrAction hapticAction, uint32_t countSubactionPaths, const XrPath* subactionPaths, const XrHapticBaseHeader* hapticEvent);
+typedef XrResult (XRAPI_PTR *PFN_xrStopHapticFeedback)(XrAction hapticAction, uint32_t countSubactionPaths, const XrPath* subactionPaths);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrGetInstanceProcAddr(
+ XrInstance instance,
+ const char* name,
+ PFN_xrVoidFunction* function);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateApiLayerProperties(
+ uint32_t propertyCapacityInput,
+ uint32_t* propertyCountOutput,
+ XrApiLayerProperties* properties);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateInstanceExtensionProperties(
+ const char* layerName,
+ uint32_t propertyCapacityInput,
+ uint32_t* propertyCountOutput,
+ XrExtensionProperties* properties);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateInstance(
+ const XrInstanceCreateInfo* createInfo,
+ XrInstance* instance);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrDestroyInstance(
+ XrInstance instance);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetInstanceProperties(
+ XrInstance instance,
+ XrInstanceProperties* instanceProperties);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrPollEvent(
+ XrInstance instance,
+ XrEventDataBuffer* eventData);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrResultToString(
+ XrInstance instance,
+ XrResult value,
+ char buffer[XR_MAX_RESULT_STRING_SIZE]);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrStructureTypeToString(
+ XrInstance instance,
+ XrStructureType value,
+ char buffer[XR_MAX_STRUCTURE_NAME_SIZE]);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetSystem(
+ XrInstance instance,
+ const XrSystemGetInfo* getInfo,
+ XrSystemId* systemId);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetSystemProperties(
+ XrInstance instance,
+ XrSystemId systemId,
+ XrSystemProperties* properties);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateEnvironmentBlendModes(
+ XrInstance instance,
+ XrSystemId systemId,
+ uint32_t environmentBlendModeCapacityInput,
+ uint32_t* environmentBlendModeCountOutput,
+ XrEnvironmentBlendMode* environmentBlendModes);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateSession(
+ XrInstance instance,
+ const XrSessionCreateInfo* createInfo,
+ XrSession* session);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrDestroySession(
+ XrSession session);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateReferenceSpaces(
+ XrSession session,
+ uint32_t spaceCapacityInput,
+ uint32_t* spaceCountOutput,
+ XrReferenceSpaceType* spaces);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateReferenceSpace(
+ XrSession session,
+ const XrReferenceSpaceCreateInfo* createInfo,
+ XrSpace* space);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetReferenceSpaceBoundsRect(
+ XrSession session,
+ XrReferenceSpaceType referenceSpaceType,
+ XrExtent2Df* bounds);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateActionSpace(
+ XrAction action,
+ const XrActionSpaceCreateInfo* createInfo,
+ XrSpace* space);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrLocateSpace(
+ XrSpace space,
+ XrSpace baseSpace,
+ XrTime time,
+ XrSpaceRelation* relation);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpace(
+ XrSpace space);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateViewConfigurations(
+ XrInstance instance,
+ XrSystemId systemId,
+ uint32_t viewConfigurationTypeCapacityInput,
+ uint32_t* viewConfigurationTypeCountOutput,
+ XrViewConfigurationType* viewConfigurationTypes);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetViewConfigurationProperties(
+ XrInstance instance,
+ XrSystemId systemId,
+ XrViewConfigurationType viewConfigurationType,
+ XrViewConfigurationProperties* configurationProperties);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateViewConfigurationViews(
+ XrInstance instance,
+ XrSystemId systemId,
+ XrViewConfigurationType viewConfigurationType,
+ uint32_t viewCapacityInput,
+ uint32_t* viewCountOutput,
+ XrViewConfigurationView* views);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSwapchainFormats(
+ XrSession session,
+ uint32_t formatCapacityInput,
+ uint32_t* formatCountOutput,
+ int64_t* formats);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateSwapchain(
+ XrSession session,
+ const XrSwapchainCreateInfo* createInfo,
+ XrSwapchain* swapchain);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrDestroySwapchain(
+ XrSwapchain swapchain);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSwapchainImages(
+ XrSwapchain swapchain,
+ uint32_t imageCapacityInput,
+ uint32_t* imageCountOutput,
+ XrSwapchainImageBaseHeader* images);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrAcquireSwapchainImage(
+ XrSwapchain swapchain,
+ const XrSwapchainImageAcquireInfo* acquireInfo,
+ uint32_t* index);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrWaitSwapchainImage(
+ XrSwapchain swapchain,
+ const XrSwapchainImageWaitInfo* waitInfo);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrReleaseSwapchainImage(
+ XrSwapchain swapchain,
+ const XrSwapchainImageReleaseInfo* releaseInfo);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrBeginSession(
+ XrSession session,
+ const XrSessionBeginInfo* beginInfo);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrEndSession(
+ XrSession session);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrWaitFrame(
+ XrSession session,
+ const XrFrameWaitInfo* frameWaitInfo,
+ XrFrameState* frameState);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrBeginFrame(
+ XrSession session,
+ const XrFrameBeginInfo* frameBeginInfo);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrEndFrame(
+ XrSession session,
+ const XrFrameEndInfo* frameEndInfo);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrLocateViews(
+ XrSession session,
+ const XrViewLocateInfo* viewLocateInfo,
+ XrViewState* viewState,
+ uint32_t viewCapacityInput,
+ uint32_t* viewCountOutput,
+ XrView* views);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrStringToPath(
+ XrInstance instance,
+ const char* pathString,
+ XrPath* path);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrPathToString(
+ XrInstance instance,
+ XrPath path,
+ uint32_t bufferCapacityInput,
+ uint32_t* bufferCountOutput,
+ char* buffer);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateActionSet(
+ XrSession session,
+ const XrActionSetCreateInfo* createInfo,
+ XrActionSet* actionSet);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrDestroyActionSet(
+ XrActionSet actionSet);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateAction(
+ XrActionSet actionSet,
+ const XrActionCreateInfo* createInfo,
+ XrAction* action);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrDestroyAction(
+ XrAction action);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrSetInteractionProfileSuggestedBindings(
+ XrSession session,
+ const XrInteractionProfileSuggestedBinding* suggestedBindings);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetCurrentInteractionProfile(
+ XrSession session,
+ XrPath topLevelUserPath,
+ XrInteractionProfileInfo* interactionProfile);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetActionStateBoolean(
+ XrAction action,
+ uint32_t countSubactionPaths,
+ const XrPath* subactionPaths,
+ XrActionStateBoolean* data);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetActionStateVector1f(
+ XrAction action,
+ uint32_t countSubactionPaths,
+ const XrPath* subactionPaths,
+ XrActionStateVector1f* data);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetActionStateVector2f(
+ XrAction action,
+ uint32_t countSubactionPaths,
+ const XrPath* subactionPaths,
+ XrActionStateVector2f* data);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetActionStatePose(
+ XrAction action,
+ XrPath subactionPath,
+ XrActionStatePose* data);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrSyncActionData(
+ XrSession session,
+ uint32_t countActionSets,
+ const XrActiveActionSet* actionSets);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetBoundSourcesForAction(
+ XrAction action,
+ uint32_t sourceCapacityInput,
+ uint32_t* sourceCountOutput,
+ XrPath* sources);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetInputSourceLocalizedName(
+ XrSession session,
+ XrPath source,
+ XrInputSourceLocalizedNameFlags whichComponents,
+ uint32_t bufferCapacityInput,
+ uint32_t* bufferCountOutput,
+ char* buffer);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrApplyHapticFeedback(
+ XrAction hapticAction,
+ uint32_t countSubactionPaths,
+ const XrPath* subactionPaths,
+ const XrHapticBaseHeader* hapticEvent);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrStopHapticFeedback(
+ XrAction hapticAction,
+ uint32_t countSubactionPaths,
+ const XrPath* subactionPaths);
+#endif
+
+
+#define XR_KHR_composition_layer_cube 1
+#define XR_KHR_composition_layer_cube_SPEC_VERSION 8
+#define XR_KHR_COMPOSITION_LAYER_CUBE_EXTENSION_NAME "XR_KHR_composition_layer_cube"
+typedef struct XrCompositionLayerCubeKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrCompositionLayerFlags layerFlags;
+ XrSpace space;
+ XrEyeVisibility eyeVisibility;
+ XrSwapchain swapchain;
+ uint32_t imageArrayIndex;
+ XrQuaternionf orientation;
+ XrVector3f offset;
+} XrCompositionLayerCubeKHR;
+
+
+
+#define XR_KHR_composition_layer_depth 1
+#define XR_KHR_composition_layer_depth_SPEC_VERSION 5
+#define XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME "XR_KHR_composition_layer_depth"
+typedef struct XrCompositionLayerDepthInfoKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrSwapchainSubImage subImage;
+ float minDepth;
+ float maxDepth;
+ float nearZ;
+ float farZ;
+} XrCompositionLayerDepthInfoKHR;
+
+
+
+#define XR_KHR_headless 1
+#define XR_KHR_headless_SPEC_VERSION 2
+#define XR_KHR_HEADLESS_EXTENSION_NAME "XR_KHR_headless"
+
+
+#define XR_KHR_composition_layer_cylinder 1
+#define XR_KHR_composition_layer_cylinder_SPEC_VERSION 4
+#define XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME "XR_KHR_composition_layer_cylinder"
+typedef struct XrCompositionLayerCylinderKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrCompositionLayerFlags layerFlags;
+ XrSpace space;
+ XrEyeVisibility eyeVisibility;
+ XrSwapchainSubImage subImage;
+ XrPosef pose;
+ float radius;
+ float centralAngle;
+ float aspectRatio;
+} XrCompositionLayerCylinderKHR;
+
+
+
+#define XR_KHR_composition_layer_equirect 1
+#define XR_KHR_composition_layer_equirect_SPEC_VERSION 3
+#define XR_KHR_COMPOSITION_LAYER_EQUIRECT_EXTENSION_NAME "XR_KHR_composition_layer_equirect"
+typedef struct XrCompositionLayerEquirectKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrCompositionLayerFlags layerFlags;
+ XrSpace space;
+ XrEyeVisibility eyeVisibility;
+ XrSwapchainSubImage subImage;
+ XrPosef pose;
+ XrVector3f offset;
+ XrVector2f scale;
+ XrVector2f bias;
+} XrCompositionLayerEquirectKHR;
+
+
+
+#define XR_KHR_visibility_mask 1
+#define XR_KHR_visibility_mask_SPEC_VERSION 1
+#define XR_KHR_VISIBILITY_MASK_EXTENSION_NAME "XR_KHR_visibility_mask"
+
+typedef enum XrVisibilityMaskTypeKHR {
+ XR_VISIBILITY_MASK_TYPE_HIDDEN_TRIANGLE_MESH_KHR = 1,
+ XR_VISIBILITY_MASK_TYPE_VISIBLE_TRIANGLE_MESH_KHR = 2,
+ XR_VISIBILITY_MASK_TYPE_LINE_LOOP_KHR = 3,
+ XR_VISIBILITY_MASK_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF
+} XrVisibilityMaskTypeKHR;
+typedef struct XrVisibilityMaskKHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t vertexCount;
+ XrVector2f* vertices;
+ uint32_t indexCount;
+ uint32_t* indices;
+} XrVisibilityMaskKHR;
+
+typedef struct XrEventDataVisibilityMaskChangedKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrViewConfigurationType viewConfigurationType;
+ uint32_t viewIndex;
+} XrEventDataVisibilityMaskChangedKHR;
+
+typedef XrResult (XRAPI_PTR *PFN_xrGetVisibilityMaskKHR)(XrSession session, XrViewConfigurationType viewConfigurationType, uint32_t viewIndex, XrVisibilityMaskTypeKHR visibilityMaskType, XrVisibilityMaskKHR* visibilityMask);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrGetVisibilityMaskKHR(
+ XrSession session,
+ XrViewConfigurationType viewConfigurationType,
+ uint32_t viewIndex,
+ XrVisibilityMaskTypeKHR visibilityMaskType,
+ XrVisibilityMaskKHR* visibilityMask);
+#endif
+
+
+#define XR_EXT_performance_settings 1
+#define XR_EXT_performance_settings_SPEC_VERSION 1
+#define XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME "XR_EXT_performance_settings"
+
+typedef enum XrPerfSettingsDomainEXT {
+ XR_PERF_SETTINGS_DOMAIN_CPU_EXT = 1,
+ XR_PERF_SETTINGS_DOMAIN_GPU_EXT = 2,
+ XR_PERF_SETTINGS_DOMAIN_MAX_ENUM_EXT = 0x7FFFFFFF
+} XrPerfSettingsDomainEXT;
+
+typedef enum XrPerfSettingsSubDomainEXT {
+ XR_PERF_SETTINGS_SUB_DOMAIN_COMPOSITING_EXT = 1,
+ XR_PERF_SETTINGS_SUB_DOMAIN_RENDERING_EXT = 2,
+ XR_PERF_SETTINGS_SUB_DOMAIN_THERMAL_EXT = 3,
+ XR_PERF_SETTINGS_SUB_DOMAIN_MAX_ENUM_EXT = 0x7FFFFFFF
+} XrPerfSettingsSubDomainEXT;
+
+typedef enum XrPerfSettingsLevelEXT {
+ XR_PERF_SETTINGS_LEVEL_POWER_SAVINGS_EXT = 0,
+ XR_PERF_SETTINGS_LEVEL_SUSTAINED_LOW_EXT = 25,
+ XR_PERF_SETTINGS_LEVEL_SUSTAINED_HIGH_EXT = 50,
+ XR_PERF_SETTINGS_LEVEL_BOOST_EXT = 75,
+ XR_PERF_SETTINGS_LEVEL_MAX_ENUM_EXT = 0x7FFFFFFF
+} XrPerfSettingsLevelEXT;
+
+typedef enum XrPerfSettingsNotificationLevelEXT {
+ XR_PERF_SETTINGS_NOTIF_LEVEL_NORMAL_EXT = 0,
+ XR_PERF_SETTINGS_NOTIF_LEVEL_WARNING_EXT = 25,
+ XR_PERF_SETTINGS_NOTIF_LEVEL_IMPAIRED_EXT = 75,
+ XR_PERF_SETTINGS_NOTIFICATION_LEVEL_MAX_ENUM_EXT = 0x7FFFFFFF
+} XrPerfSettingsNotificationLevelEXT;
+typedef struct XrEventDataPerfSettingsEXT {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrPerfSettingsDomainEXT domain;
+ XrPerfSettingsSubDomainEXT subDomain;
+ XrPerfSettingsNotificationLevelEXT fromLevel;
+ XrPerfSettingsNotificationLevelEXT toLevel;
+} XrEventDataPerfSettingsEXT;
+
+typedef XrResult (XRAPI_PTR *PFN_xrPerfSettingsSetPerformanceLevelEXT)(XrSession session, XrPerfSettingsDomainEXT domain, XrPerfSettingsLevelEXT level);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrPerfSettingsSetPerformanceLevelEXT(
+ XrSession session,
+ XrPerfSettingsDomainEXT domain,
+ XrPerfSettingsLevelEXT level);
+#endif
+
+
+#define XR_EXT_thermal_query 1
+#define XR_EXT_thermal_query_SPEC_VERSION 1
+#define XR_EXT_THERMAL_QUERY_EXTENSION_NAME "XR_EXT_thermal_query"
+typedef XrResult (XRAPI_PTR *PFN_xrThermalGetTemperatureTrendEXT)(XrSession session, XrPerfSettingsDomainEXT domain, XrPerfSettingsNotificationLevelEXT* notificationLevel, float* tempHeadroom, float* tempSlope);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrThermalGetTemperatureTrendEXT(
+ XrSession session,
+ XrPerfSettingsDomainEXT domain,
+ XrPerfSettingsNotificationLevelEXT* notificationLevel,
+ float* tempHeadroom,
+ float* tempSlope);
+#endif
+
+
+#define XR_EXT_debug_utils 1
+XR_DEFINE_HANDLE(XrDebugUtilsMessengerEXT)
+#define XR_EXT_debug_utils_SPEC_VERSION 2
+#define XR_EXT_DEBUG_UTILS_EXTENSION_NAME "XR_EXT_debug_utils"
+typedef XrFlags64 XrDebugUtilsMessageSeverityFlagsEXT;
+
+// Flag bits for XrDebugUtilsMessageSeverityFlagsEXT
+static const XrDebugUtilsMessageSeverityFlagsEXT XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT = 0x00000001;
+static const XrDebugUtilsMessageSeverityFlagsEXT XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT = 0x00000010;
+static const XrDebugUtilsMessageSeverityFlagsEXT XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT = 0x00000100;
+static const XrDebugUtilsMessageSeverityFlagsEXT XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT = 0x00001000;
+
+typedef XrFlags64 XrDebugUtilsMessageTypeFlagsEXT;
+
+// Flag bits for XrDebugUtilsMessageTypeFlagsEXT
+static const XrDebugUtilsMessageTypeFlagsEXT XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT = 0x00000001;
+static const XrDebugUtilsMessageTypeFlagsEXT XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT = 0x00000002;
+static const XrDebugUtilsMessageTypeFlagsEXT XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT = 0x00000004;
+
+typedef struct XrDebugUtilsObjectNameInfoEXT {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrObjectType objectType;
+ uint64_t objectHandle;
+ const char* objectName;
+} XrDebugUtilsObjectNameInfoEXT;
+
+typedef struct XrDebugUtilsLabelEXT {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ const char* labelName;
+} XrDebugUtilsLabelEXT;
+
+typedef struct XrDebugUtilsMessengerCallbackDataEXT {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ const char* messageId;
+ const char* functionName;
+ const char* message;
+ uint32_t objectCount;
+ XrDebugUtilsObjectNameInfoEXT* objects;
+ uint32_t sessionLabelCount;
+ XrDebugUtilsLabelEXT* sessionLabels;
+} XrDebugUtilsMessengerCallbackDataEXT;
+
+typedef XrBool32 (XRAPI_PTR *PFN_xrDebugUtilsMessengerCallbackEXT)(
+ XrDebugUtilsMessageSeverityFlagsEXT messageSeverity,
+ XrDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const XrDebugUtilsMessengerCallbackDataEXT* callbackData,
+ void* userData);
+
+
+typedef struct XrDebugUtilsMessengerCreateInfoEXT {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrDebugUtilsMessageSeverityFlagsEXT messageSeverities;
+ XrDebugUtilsMessageTypeFlagsEXT messageTypes;
+ PFN_xrDebugUtilsMessengerCallbackEXT userCallback;
+ void* XR_MAY_ALIAS userData;
+} XrDebugUtilsMessengerCreateInfoEXT;
+
+typedef XrResult (XRAPI_PTR *PFN_xrSetDebugUtilsObjectNameEXT)(XrInstance instance, const XrDebugUtilsObjectNameInfoEXT* nameInfo);
+typedef XrResult (XRAPI_PTR *PFN_xrCreateDebugUtilsMessengerEXT)(XrInstance instance, const XrDebugUtilsMessengerCreateInfoEXT* createInfo, XrDebugUtilsMessengerEXT* messenger);
+typedef XrResult (XRAPI_PTR *PFN_xrDestroyDebugUtilsMessengerEXT)(XrDebugUtilsMessengerEXT messenger);
+typedef XrResult (XRAPI_PTR *PFN_xrSubmitDebugUtilsMessageEXT)(XrInstance instance, XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, XrDebugUtilsMessageTypeFlagsEXT messageTypes, const XrDebugUtilsMessengerCallbackDataEXT* callbackData);
+typedef XrResult (XRAPI_PTR *PFN_xrSessionBeginDebugUtilsLabelRegionEXT)(XrSession session, const XrDebugUtilsLabelEXT* labelInfo);
+typedef XrResult (XRAPI_PTR *PFN_xrSessionEndDebugUtilsLabelRegionEXT)(XrSession session);
+typedef XrResult (XRAPI_PTR *PFN_xrSessionInsertDebugUtilsLabelEXT)(XrSession session, const XrDebugUtilsLabelEXT* labelInfo);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrSetDebugUtilsObjectNameEXT(
+ XrInstance instance,
+ const XrDebugUtilsObjectNameInfoEXT* nameInfo);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateDebugUtilsMessengerEXT(
+ XrInstance instance,
+ const XrDebugUtilsMessengerCreateInfoEXT* createInfo,
+ XrDebugUtilsMessengerEXT* messenger);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrDestroyDebugUtilsMessengerEXT(
+ XrDebugUtilsMessengerEXT messenger);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrSubmitDebugUtilsMessageEXT(
+ XrInstance instance,
+ XrDebugUtilsMessageSeverityFlagsEXT messageSeverity,
+ XrDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const XrDebugUtilsMessengerCallbackDataEXT* callbackData);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrSessionBeginDebugUtilsLabelRegionEXT(
+ XrSession session,
+ const XrDebugUtilsLabelEXT* labelInfo);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrSessionEndDebugUtilsLabelRegionEXT(
+ XrSession session);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrSessionInsertDebugUtilsLabelEXT(
+ XrSession session,
+ const XrDebugUtilsLabelEXT* labelInfo);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/external/openxr_includes/openxr_platform.h b/src/external/openxr_includes/openxr_platform.h
new file mode 100644
index 000000000..e0db2a047
--- /dev/null
+++ b/src/external/openxr_includes/openxr_platform.h
@@ -0,0 +1,415 @@
+#ifndef OPENXR_PLATFORM_H_
+#define OPENXR_PLATFORM_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2017-2019 The Khronos Group Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/*
+** This header is generated from the Khronos OpenXR XML API Registry.
+**
+*/
+
+
+#ifdef XR_USE_PLATFORM_ANDROID
+
+#define XR_KHR_android_thread_settings 1
+#define XR_KHR_android_thread_settings_SPEC_VERSION 4
+#define XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME "XR_KHR_android_thread_settings"
+
+typedef enum XrAndroidThreadTypeKHR {
+ XR_ANDROID_THREAD_TYPE_APPLICATION_MAIN_KHR = 1,
+ XR_ANDROID_THREAD_TYPE_APPLICATION_WORKER_KHR = 2,
+ XR_ANDROID_THREAD_TYPE_RENDERER_MAIN_KHR = 3,
+ XR_ANDROID_THREAD_TYPE_RENDERER_WORKER_KHR = 4,
+ XR_ANDROID_THREAD_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF
+} XrAndroidThreadTypeKHR;
+typedef XrResult (XRAPI_PTR *PFN_xrSetAndroidApplicationThreadKHR)(XrSession session, XrAndroidThreadTypeKHR threadType, uint32_t threadId);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrSetAndroidApplicationThreadKHR(
+ XrSession session,
+ XrAndroidThreadTypeKHR threadType,
+ uint32_t threadId);
+#endif
+#endif /* XR_USE_PLATFORM_ANDROID */
+
+#ifdef XR_USE_PLATFORM_ANDROID
+
+#define XR_KHR_android_surface_swapchain 1
+#define XR_KHR_android_surface_swapchain_SPEC_VERSION 4
+#define XR_KHR_ANDROID_SURFACE_SWAPCHAIN_EXTENSION_NAME "XR_KHR_android_surface_swapchain"
+typedef XrResult (XRAPI_PTR *PFN_xrCreateSwapchainAndroidSurfaceKHR)(XrSession session, const XrSwapchainCreateInfo* info, XrSwapchain* swapchain, jobject* surface);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateSwapchainAndroidSurfaceKHR(
+ XrSession session,
+ const XrSwapchainCreateInfo* info,
+ XrSwapchain* swapchain,
+ jobject* surface);
+#endif
+#endif /* XR_USE_PLATFORM_ANDROID */
+
+#ifdef XR_USE_PLATFORM_ANDROID
+
+#define XR_KHR_android_create_instance 1
+#define XR_KHR_android_create_instance_SPEC_VERSION 2
+#define XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME "XR_KHR_android_create_instance"
+typedef struct XrInstanceCreateInfoAndroidKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ void* XR_MAY_ALIAS applicationVM;
+ void* XR_MAY_ALIAS applicationActivity;
+} XrInstanceCreateInfoAndroidKHR;
+
+#endif /* XR_USE_PLATFORM_ANDROID */
+
+#ifdef XR_USE_GRAPHICS_API_VULKAN
+
+#define XR_KHR_vulkan_swapchain_format_list 1
+#define XR_KHR_vulkan_swapchain_format_list_SPEC_VERSION 1
+#define XR_KHR_VULKAN_SWAPCHAIN_FORMAT_LIST_EXTENSION_NAME "XR_KHR_vulkan_swapchain_format_list"
+typedef struct XrVulkanSwapchainFormatListCreateInfoKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ uint32_t viewFormatCount;
+ const VkFormat* viewFormats;
+} XrVulkanSwapchainFormatListCreateInfoKHR;
+
+#endif /* XR_USE_GRAPHICS_API_VULKAN */
+
+#ifdef XR_USE_GRAPHICS_API_OPENGL
+
+#define XR_KHR_opengl_enable 1
+#define XR_KHR_opengl_enable_SPEC_VERSION 1
+#define XR_KHR_OPENGL_ENABLE_EXTENSION_NAME "XR_KHR_opengl_enable"
+#ifdef XR_USE_PLATFORM_WIN32
+typedef struct XrGraphicsBindingOpenGLWin32KHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ HDC hDC;
+ HGLRC hGLRC;
+} XrGraphicsBindingOpenGLWin32KHR;
+#endif // XR_USE_PLATFORM_WIN32
+
+#ifdef XR_USE_PLATFORM_XLIB
+typedef struct XrGraphicsBindingOpenGLXlibKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ Display* xDisplay;
+ uint32_t visualid;
+ GLXFBConfig glxFBConfig;
+ GLXDrawable glxDrawable;
+ GLXContext glxContext;
+} XrGraphicsBindingOpenGLXlibKHR;
+#endif // XR_USE_PLATFORM_XLIB
+
+#ifdef XR_USE_PLATFORM_XCB
+typedef struct XrGraphicsBindingOpenGLXcbKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ xcb_connection_t* connection;
+ uint32_t screen_number;
+ xcb_glx_fbconfig_t fbconfigid;
+ xcb_visualid_t visualid;
+ xcb_glx_drawable_t glxDrawable;
+ xcb_glx_context_t glxContext;
+} XrGraphicsBindingOpenGLXcbKHR;
+#endif // XR_USE_PLATFORM_XCB
+
+#ifdef XR_USE_PLATFORM_WAYLAND
+typedef struct XrGraphicsBindingOpenGLWaylandKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ struct wl_display* display;
+} XrGraphicsBindingOpenGLWaylandKHR;
+#endif // XR_USE_PLATFORM_WAYLAND
+
+typedef struct XrSwapchainImageOpenGLKHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t image;
+} XrSwapchainImageOpenGLKHR;
+
+typedef struct XrGraphicsRequirementsOpenGLKHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t minApiVersionSupported;
+ uint32_t maxApiVersionSupported;
+} XrGraphicsRequirementsOpenGLKHR;
+
+typedef XrResult (XRAPI_PTR *PFN_xrGetOpenGLGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsOpenGLKHR* graphicsRequirements);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrGetOpenGLGraphicsRequirementsKHR(
+ XrInstance instance,
+ XrSystemId systemId,
+ XrGraphicsRequirementsOpenGLKHR* graphicsRequirements);
+#endif
+#endif /* XR_USE_GRAPHICS_API_OPENGL */
+
+#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
+
+#define XR_KHR_opengl_es_enable 1
+#define XR_KHR_opengl_es_enable_SPEC_VERSION 1
+#define XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME "XR_KHR_opengl_es_enable"
+#ifdef XR_USE_PLATFORM_ANDROID
+typedef struct XrGraphicsBindingOpenGLESAndroidKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ EGLDisplay display;
+ EGLConfig config;
+ EGLContext context;
+} XrGraphicsBindingOpenGLESAndroidKHR;
+#endif // XR_USE_PLATFORM_ANDROID
+
+typedef struct XrSwapchainImageOpenGLESKHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t image;
+} XrSwapchainImageOpenGLESKHR;
+
+typedef struct XrGraphicsRequirementsOpenGLESKHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t minApiVersionSupported;
+ uint32_t maxApiVersionSupported;
+} XrGraphicsRequirementsOpenGLESKHR;
+
+typedef XrResult (XRAPI_PTR *PFN_xrGetOpenGLESGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsOpenGLESKHR* graphicsRequirements);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrGetOpenGLESGraphicsRequirementsKHR(
+ XrInstance instance,
+ XrSystemId systemId,
+ XrGraphicsRequirementsOpenGLESKHR* graphicsRequirements);
+#endif
+#endif /* XR_USE_GRAPHICS_API_OPENGL_ES */
+
+#ifdef XR_USE_GRAPHICS_API_VULKAN
+
+#define XR_KHR_vulkan_enable 1
+#define XR_KHR_vulkan_enable_SPEC_VERSION 6
+#define XR_KHR_VULKAN_ENABLE_EXTENSION_NAME "XR_KHR_vulkan_enable"
+typedef struct XrGraphicsBindingVulkanKHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ VkInstance instance;
+ VkPhysicalDevice physicalDevice;
+ VkDevice device;
+ uint32_t queueFamilyIndex;
+ uint32_t queueIndex;
+} XrGraphicsBindingVulkanKHR;
+
+typedef struct XrSwapchainImageVulkanKHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ VkImage image;
+} XrSwapchainImageVulkanKHR;
+
+typedef struct XrGraphicsRequirementsVulkanKHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ uint32_t minApiVersionSupported;
+ uint32_t maxApiVersionSupported;
+} XrGraphicsRequirementsVulkanKHR;
+
+typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanInstanceExtensionsKHR)(XrInstance instance, XrSystemId systemId, uint32_t namesCapacityInput, uint32_t* namesCountOutput, char* namesString);
+typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanDeviceExtensionsKHR)(XrInstance instance, XrSystemId systemId, uint32_t namesCapacityInput, uint32_t* namesCountOutput, char* namesString);
+typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsDeviceKHR)(XrInstance instance, XrSystemId systemId, VkInstance vkInstance, VkPhysicalDevice* vkPhysicalDevice);
+typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsVulkanKHR* graphicsRequirements);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanInstanceExtensionsKHR(
+ XrInstance instance,
+ XrSystemId systemId,
+ uint32_t namesCapacityInput,
+ uint32_t* namesCountOutput,
+ char* namesString);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanDeviceExtensionsKHR(
+ XrInstance instance,
+ XrSystemId systemId,
+ uint32_t namesCapacityInput,
+ uint32_t* namesCountOutput,
+ char* namesString);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsDeviceKHR(
+ XrInstance instance,
+ XrSystemId systemId,
+ VkInstance vkInstance,
+ VkPhysicalDevice* vkPhysicalDevice);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsRequirementsKHR(
+ XrInstance instance,
+ XrSystemId systemId,
+ XrGraphicsRequirementsVulkanKHR* graphicsRequirements);
+#endif
+#endif /* XR_USE_GRAPHICS_API_VULKAN */
+
+#ifdef XR_USE_GRAPHICS_API_D3D10
+
+#define XR_KHR_D3D10_enable 1
+#define XR_KHR_D3D10_enable_SPEC_VERSION 1
+#define XR_KHR_D3D10_ENABLE_EXTENSION_NAME "XR_KHR_D3D10_enable"
+typedef struct XrGraphicsBindingD3D10KHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ ID3D10Device* device;
+} XrGraphicsBindingD3D10KHR;
+
+typedef struct XrSwapchainImageD3D10KHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ ID3D10Texture2D* texture;
+} XrSwapchainImageD3D10KHR;
+
+typedef struct XrGraphicsRequirementsD3D10KHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ LUID adapterLuid;
+ D3D10_FEATURE_LEVEL1 minFeatureLevel;
+} XrGraphicsRequirementsD3D10KHR;
+
+typedef XrResult (XRAPI_PTR *PFN_xrGetD3D10GraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsD3D10KHR* graphicsRequirements);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D10GraphicsRequirementsKHR(
+ XrInstance instance,
+ XrSystemId systemId,
+ XrGraphicsRequirementsD3D10KHR* graphicsRequirements);
+#endif
+#endif /* XR_USE_GRAPHICS_API_D3D10 */
+
+#ifdef XR_USE_GRAPHICS_API_D3D11
+
+#define XR_KHR_D3D11_enable 1
+#define XR_KHR_D3D11_enable_SPEC_VERSION 1
+#define XR_KHR_D3D11_ENABLE_EXTENSION_NAME "XR_KHR_D3D11_enable"
+typedef struct XrGraphicsBindingD3D11KHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ ID3D11Device* device;
+} XrGraphicsBindingD3D11KHR;
+
+typedef struct XrSwapchainImageD3D11KHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ ID3D11Texture2D* texture;
+} XrSwapchainImageD3D11KHR;
+
+typedef struct XrGraphicsRequirementsD3D11KHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ LUID adapterLuid;
+ D3D_FEATURE_LEVEL minFeatureLevel;
+} XrGraphicsRequirementsD3D11KHR;
+
+typedef XrResult (XRAPI_PTR *PFN_xrGetD3D11GraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsD3D11KHR* graphicsRequirements);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D11GraphicsRequirementsKHR(
+ XrInstance instance,
+ XrSystemId systemId,
+ XrGraphicsRequirementsD3D11KHR* graphicsRequirements);
+#endif
+#endif /* XR_USE_GRAPHICS_API_D3D11 */
+
+#ifdef XR_USE_GRAPHICS_API_D3D12
+
+#define XR_KHR_D3D12_enable 1
+#define XR_KHR_D3D12_enable_SPEC_VERSION 1
+#define XR_KHR_D3D12_ENABLE_EXTENSION_NAME "XR_KHR_D3D12_enable"
+typedef struct XrGraphicsBindingD3D12KHR {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ ID3D12Device* device;
+ ID3D12CommandQueue* queue;
+} XrGraphicsBindingD3D12KHR;
+
+typedef struct XrSwapchainImageD3D12KHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ ID3D12Resource* texture;
+} XrSwapchainImageD3D12KHR;
+
+typedef struct XrGraphicsRequirementsD3D12KHR {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ LUID adapterLuid;
+ D3D_FEATURE_LEVEL minFeatureLevel;
+} XrGraphicsRequirementsD3D12KHR;
+
+typedef XrResult (XRAPI_PTR *PFN_xrGetD3D12GraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsD3D12KHR* graphicsRequirements);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D12GraphicsRequirementsKHR(
+ XrInstance instance,
+ XrSystemId systemId,
+ XrGraphicsRequirementsD3D12KHR* graphicsRequirements);
+#endif
+#endif /* XR_USE_GRAPHICS_API_D3D12 */
+
+#ifdef XR_USE_PLATFORM_WIN32
+
+#define XR_KHR_win32_convert_performance_counter_time 1
+#define XR_KHR_win32_convert_performance_counter_time_SPEC_VERSION 1
+#define XR_KHR_WIN32_CONVERT_PERFORMANCE_COUNTER_TIME_EXTENSION_NAME "XR_KHR_win32_convert_performance_counter_time"
+typedef XrResult (XRAPI_PTR *PFN_xrConvertWin32PerformanceCounterToTimeKHR)(XrInstance instance, const LARGE_INTEGER* performanceCounter, XrTime* time);
+typedef XrResult (XRAPI_PTR *PFN_xrConvertTimeToWin32PerformanceCounterKHR)(XrInstance instance, XrTime time, LARGE_INTEGER* performanceCounter);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrConvertWin32PerformanceCounterToTimeKHR(
+ XrInstance instance,
+ const LARGE_INTEGER* performanceCounter,
+ XrTime* time);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimeToWin32PerformanceCounterKHR(
+ XrInstance instance,
+ XrTime time,
+ LARGE_INTEGER* performanceCounter);
+#endif
+#endif /* XR_USE_PLATFORM_WIN32 */
+
+#ifdef XR_USE_TIMESPEC
+
+#define XR_KHR_convert_timespec_time 1
+#define XR_KHR_convert_timespec_time_SPEC_VERSION 1
+#define XR_KHR_CONVERT_TIMESPEC_TIME_EXTENSION_NAME "XR_KHR_convert_timespec_time"
+typedef XrResult (XRAPI_PTR *PFN_xrConvertTimespecTimeToTimeKHR)(XrInstance instance, const struct timespec* timespecTime, XrTime* time);
+typedef XrResult (XRAPI_PTR *PFN_xrConvertTimeToTimespecTimeKHR)(XrInstance instance, XrTime time, struct timespec* timespecTime);
+
+#ifndef XR_NO_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimespecTimeToTimeKHR(
+ XrInstance instance,
+ const struct timespec* timespecTime,
+ XrTime* time);
+
+XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimeToTimespecTimeKHR(
+ XrInstance instance,
+ XrTime time,
+ struct timespec* timespecTime);
+#endif
+#endif /* XR_USE_TIMESPEC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/external/openxr_includes/openxr_platform_defines.h b/src/external/openxr_includes/openxr_platform_defines.h
new file mode 100644
index 000000000..f2ba2ab37
--- /dev/null
+++ b/src/external/openxr_includes/openxr_platform_defines.h
@@ -0,0 +1,120 @@
+/*
+** Copyright (c) 2017-2019 The Khronos Group Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef OPENXR_PLATFORM_DEFINES_H_
+#define OPENXR_PLATFORM_DEFINES_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Platform-specific calling convention macros.
+ *
+ * Platforms should define these so that OpenXR clients call OpenXR functions
+ * with the same calling conventions that the OpenXR implementation expects.
+ *
+ * XRAPI_ATTR - Placed before the return type in function declarations.
+ * Useful for C++11 and GCC/Clang-style function attribute syntax.
+ * XRAPI_CALL - Placed after the return type in function declarations.
+ * Useful for MSVC-style calling convention syntax.
+ * XRAPI_PTR - Placed between the '(' and '*' in function pointer types.
+ *
+ * Function declaration: XRAPI_ATTR void XRAPI_CALL xrFunction(void);
+ * Function pointer type: typedef void (XRAPI_PTR *PFN_xrFunction)(void);
+ */
+#if defined(_WIN32)
+// On Windows, functions use the stdcall convention
+#define XRAPI_ATTR
+#define XRAPI_CALL __stdcall
+#define XRAPI_PTR XRAPI_CALL
+#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
+#error "API not supported for the 'armeabi' NDK ABI"
+#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
+// On Android 32-bit ARM targets, functions use the "hardfloat"
+// calling convention, i.e. float parameters are passed in registers. This
+// is true even if the rest of the application passes floats on the stack,
+// as it does by default when compiling for the armeabi-v7a NDK ABI.
+#define XRAPI_ATTR __attribute__((pcs("aapcs-vfp")))
+#define XRAPI_CALL
+#define XRAPI_PTR XRAPI_ATTR
+#else
+// On other platforms, use the default calling convention
+#define XRAPI_ATTR
+#define XRAPI_CALL
+#define XRAPI_PTR
+#endif
+
+#include
+
+#if !defined(XR_NO_STDINT_H)
+#if defined(_MSC_VER) && (_MSC_VER < 1600)
+typedef signed __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef signed __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef signed __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+#include
+#endif
+#endif // !defined( XR_NO_STDINT_H )
+
+// XR_PTR_SIZE (in bytes)
+#if (defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__))
+#define XR_PTR_SIZE 8
+#else
+#define XR_PTR_SIZE 4
+#endif
+
+// Needed so we can use clang __has_feature portably.
+#if !defined(XR_COMPILER_HAS_FEATURE)
+#if defined(__clang__)
+#define XR_COMPILER_HAS_FEATURE(x) __has_feature(x)
+#else
+#define XR_COMPILER_HAS_FEATURE(x) 0
+#endif
+#endif
+
+// Identifies if the current compiler has C++11 support enabled.
+// Does not by itself identify if any given C++11 feature is present.
+#if !defined(XR_CPP11_ENABLED) && defined(__cplusplus)
+#if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
+#define XR_CPP11_ENABLED 1
+#elif defined(_MSC_VER) && (_MSC_VER >= 1600)
+#define XR_CPP11_ENABLED 1
+#elif (__cplusplus >= 201103L) // 201103 is the first C++11 version.
+#define XR_CPP11_ENABLED 1
+#endif
+#endif
+
+// Identifies if the current compiler supports C++11 nullptr.
+#if !defined(XR_CPP_NULLPTR_SUPPORTED)
+#if defined(XR_CPP11_ENABLED) && \
+ ((defined(__clang__) && XR_COMPILER_HAS_FEATURE(cxx_nullptr)) || \
+ (defined(__GNUC__) && (((__GNUC__ * 1000) + __GNUC_MINOR__) >= 4006)) || \
+ (defined(_MSC_VER) && (_MSC_VER >= 1600)) || \
+ (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403)))
+#define XR_CPP_NULLPTR_SUPPORTED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/xrt/.clang-format b/src/xrt/.clang-format
new file mode 100644
index 000000000..e1666781b
--- /dev/null
+++ b/src/xrt/.clang-format
@@ -0,0 +1,48 @@
+---
+Language: Cpp
+BasedOnStyle: LLVM
+Standard: Auto
+
+# Includes
+SortIncludes: false
+
+# Spacing and Blank Lines
+DerivePointerAlignment: true
+PointerAlignment: Right
+#AlignEscapedNewlines: DontAlign
+#AlignConsecutiveDeclarations: false
+#AlignConsecutiveAssignments: false
+MaxEmptyLinesToKeep: 3
+
+# Indentation
+IndentWidth: 8
+TabWidth: 8
+UseTab: ForIndentation
+AccessModifierOffset: -8
+IndentCaseLabels: false
+NamespaceIndentation: Inner
+
+# Line length/reflow
+ColumnLimit: 80
+ReflowComments: true
+
+
+# Line breaks
+AlwaysBreakAfterReturnType: All
+AllowShortFunctionsOnASingleLine: Empty
+AllowShortIfStatementsOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: true
+AlwaysBreakBeforeMultilineStrings: true
+BreakBeforeBraces: Custom
+BraceWrapping:
+ AfterEnum: true
+ AfterStruct: true
+ AfterClass: true
+ SplitEmptyFunction: false
+ AfterFunction: true
+ AfterNamespace: false
+
+# false means either "all on one line" or "each on their own",
+# won't put more than one on a line if they don't all fit.
+BinPackArguments: true
+BinPackParameters: false
diff --git a/src/xrt/CMakeLists.txt b/src/xrt/CMakeLists.txt
new file mode 100644
index 000000000..e97bf6d5f
--- /dev/null
+++ b/src/xrt/CMakeLists.txt
@@ -0,0 +1,8 @@
+# Copyright 2019, Collabora, Ltd.
+# SPDX-License-Identifier: BSL-1.0
+
+add_subdirectory(auxiliary)
+add_subdirectory(drivers)
+add_subdirectory(compositor)
+add_subdirectory(state_trackers)
+add_subdirectory(targets)
diff --git a/src/xrt/auxiliary/CMakeLists.txt b/src/xrt/auxiliary/CMakeLists.txt
new file mode 100644
index 000000000..8ba74c589
--- /dev/null
+++ b/src/xrt/auxiliary/CMakeLists.txt
@@ -0,0 +1,42 @@
+# Copyright 2019, Collabora, Ltd.
+# SPDX-License-Identifier: BSL-1.0
+
+set(MATH_SOURCE_FILES
+ math/m_api.h
+ math/m_base.cpp
+ math/m_optics.c
+ math/m_eigen_interop.h
+ math/m_quatexpmap.cpp
+ )
+
+set(SOURCE_FILES
+ util/u_misc.c
+ util/u_misc.h
+ util/u_debug.c
+ util/u_debug.h
+ util/u_device.c
+ util/u_device.h
+ util/u_time.cpp
+ util/u_time.h
+ )
+
+# Common includes
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../include
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+
+# Use OBJECT to not create a archive, since it just gets in the way.
+add_library(aux_util OBJECT ${SOURCE_FILES})
+
+set_property(TARGET aux_util PROPERTY POSITION_INDEPENDENT_CODE ON)
+
+
+# Math library has different includes.
+add_library(aux_math OBJECT ${MATH_SOURCE_FILES})
+
+target_include_directories(aux_math SYSTEM
+ PRIVATE ${EIGEN3_INCLUDE_DIR}
+ )
+
+set_property(TARGET aux_math PROPERTY POSITION_INDEPENDENT_CODE ON)
diff --git a/src/xrt/auxiliary/math/m_api.h b/src/xrt/auxiliary/math/m_api.h
new file mode 100644
index 000000000..0119f295a
--- /dev/null
+++ b/src/xrt/auxiliary/math/m_api.h
@@ -0,0 +1,250 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief C interface to math library.
+ * @author Jakob Bornecrantz
+ *
+ * @see xrt_vec3
+ * @see xrt_quat
+ * @see xrt_pose
+ * @see xrt_space_relation
+ */
+
+#pragma once
+
+#include "xrt/xrt_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*!
+ * @dir auxiliary/math
+ *
+ * @brief C interface to some transform-related math functions.
+ */
+
+/*
+ *
+ * Vector functions
+ *
+ */
+
+/*!
+ * Accumulate a vector by adding in-place.
+ *
+ * Logically, *inAndOut += *additional
+ * OK if the two arguments are the same addresses.
+ *
+ * @relates xrt_vec3
+ */
+void
+math_vec3_accum(const struct xrt_vec3 *additional, struct xrt_vec3 *inAndOut);
+
+/*
+ *
+ * Quat functions.
+ *
+ */
+
+/*!
+ * Rotate a vector.
+ *
+ * @relates xrt_quat
+ * @relatesalso xrt_vec3
+ */
+void
+math_quat_rotate_vec3(const struct xrt_quat *left,
+ const struct xrt_vec3 *right,
+ struct xrt_vec3 *result);
+
+/*!
+ * Rotate a quaternion (compose rotations).
+ *
+ * @relates xrt_quat
+ */
+void
+math_quat_rotate(const struct xrt_quat *left,
+ const struct xrt_quat *right,
+ struct xrt_quat *result);
+
+
+/*!
+ * Integrate an angular velocity vector (exponential map) and apply to a
+ * quaternion.
+ *
+ * velocity and dt should share the same units of time, and the angular velocity
+ * vector should be in radians per unit of time.
+ *
+ * @relates xrt_quat
+ * @relatesalso xrt_vec3
+ */
+void
+math_quat_integrate_velocity(const struct xrt_quat *quat,
+ const struct xrt_vec3 *ang_vel,
+ const float dt,
+ struct xrt_quat *result);
+/*
+ *
+ * Pose functions.
+ *
+ */
+
+/*!
+ * Check if this pose can be used in transformation operations.
+ *
+ * @relates xrt_pose
+ */
+bool
+math_pose_validate(const struct xrt_pose *pose);
+
+/*!
+ * Invert pose.
+ *
+ * OK if input and output are the same addresses.
+ *
+ * @relates xrt_pose
+ */
+void
+math_pose_invert(const struct xrt_pose *pose, struct xrt_pose *outPose);
+
+/*!
+ * Apply a rigid-body transformation to a pose.
+ *
+ * OK if input and output are the same addresses.
+ *
+ * @relates xrt_pose
+ */
+void
+math_pose_transform(const struct xrt_pose *transform,
+ const struct xrt_pose *pose,
+ struct xrt_pose *outPose);
+
+/*!
+ * Combine the poses of the target and base space with the relative pose of
+ * those spaces. In a way that OpenXR specifies in the function xrLocateSpace.
+ *
+ * Performs roughly outPose = spacePose * relativePose * baseSpacePose^-1
+ *
+ * OK if input and output are the same addresses.
+ *
+ * @relates xrt_pose
+ */
+void
+math_pose_openxr_locate(const struct xrt_pose *space_pose,
+ const struct xrt_pose *relative_pose,
+ const struct xrt_pose *base_space_pose,
+ struct xrt_pose *result);
+
+/*
+ *
+ * Space relation functions
+ *
+ */
+
+/*!
+ * Reset a relation to zero velocity, located at origin, and all validity flags.
+ *
+ * @relates xrt_space_relation
+ */
+void
+math_relation_reset(struct xrt_space_relation *out);
+
+/*!
+ * Apply a static pose on top of an existing relation.
+ *
+ * Updates all valid pose and derivative fields. Does not modify the validity
+ * mask. Treats both position and orientation of transform as valid.
+ *
+ * @relates xrt_space_relation
+ * @see xrt_pose
+ */
+void
+math_relation_accumulate_transform(const struct xrt_pose *transform,
+ struct xrt_space_relation *in_out_relation);
+
+/*!
+ * Apply another step of space relation on top of an existing relation.
+ *
+ * Updates all valid pose and derivative fields, as well as the validity mask.
+ *
+ * @relates xrt_space_relation
+ */
+void
+math_relation_accumulate_relation(
+ const struct xrt_space_relation *additional_relation,
+ struct xrt_space_relation *in_out_relation);
+
+/*!
+ * Combine the poses of the target and base space with the relative relation of
+ * those spaces. In a way that OpenXR specifies in the function xrLocateSpace.
+ *
+ * Performs roughly `out_relation->pose = space_pose * relative_relation->pose *
+ * base_space_pose^-1` for the poses, and appropriate rotation
+ *
+ * OK if input and output are the same addresses.
+ *
+ * @relates xrt_space_relation
+ * @see xrt_pose
+ */
+void
+math_relation_openxr_locate(const struct xrt_pose *space_pose,
+ const struct xrt_space_relation *relative_relation,
+ const struct xrt_pose *base_space_pose,
+ struct xrt_space_relation *result);
+
+/*!
+ * Perform the computations from
+ * "Computing Half-Fields-Of-View from Simpler Display Models",
+ * to get half-FOVs from things we can retrieve from other APIs.
+ * The origin is in the lower-left corner of the display, so w_1 is the width to
+ * the left of CoP, and h_1 is the height below CoP.
+ *
+ * If vertfov_total is set to 0, it will be computed from h_total.
+ *
+ * Distances are in arbitrary but consistent units. Angles are in radians.
+ *
+ *
+ * In the diagram below, treating it like a FOV for horizontal,
+ * the top angle is horizfov_total, the length of the bottom
+ * is w_total, and the distance between the vertical line and the left corner is
+ * w_1. Vertical is similar - h_1 is above the center line.
+ * The triangle need not be symmetrical, despite how the diagram looks.
+ *
+ * ```
+ * horizfov_total
+ * *
+ * angle_left (neg) -> / | \ <- angle_right
+ * / | \
+ * / | \
+ * / | \
+ * -------------
+ * [ w_1 ]
+ * [ --- w --- ]
+ *
+ * ------- --- |\
+ * | \
+ * h_1 | \ angle_up
+ * h_total ___ |-------* vertfov_total
+ * | / angle_down (neg)
+ * | /
+ * | /
+ * ------- |/
+ * ```
+ *
+ * @return true if successful.
+ */
+bool
+math_compute_fovs(double w_total,
+ double w_1,
+ double horizfov_total,
+ double h_total,
+ double h_1,
+ double vertfov_total,
+ struct xrt_fov *fov);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/auxiliary/math/m_base.cpp b/src/xrt/auxiliary/math/m_base.cpp
new file mode 100644
index 000000000..ca3a248db
--- /dev/null
+++ b/src/xrt/auxiliary/math/m_base.cpp
@@ -0,0 +1,430 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Base implementations for math library.
+ * @author Jakob Bornecrantz
+ * @author Ryan Pavlik
+ */
+
+#include
+#include
+
+#include
+
+#include "math/m_api.h"
+#include "math/m_eigen_interop.h"
+
+/*
+ *
+ * Copy helpers.
+ *
+ */
+
+static inline Eigen::Quaternionf
+copy(const struct xrt_quat& q)
+{
+ // Eigen constructor order is different from XRT, OpenHMD and OpenXR!
+ // Eigen: `float w, x, y, z`.
+ // OpenXR: `float x, y, z, w`.
+ return Eigen::Quaternionf(q.w, q.x, q.y, q.z);
+}
+
+static inline Eigen::Quaternionf
+copy(const struct xrt_quat* q)
+{
+ return copy(*q);
+}
+
+static inline Eigen::Vector3f
+copy(const struct xrt_vec3& v)
+{
+ return Eigen::Vector3f(v.x, v.y, v.z);
+}
+
+static inline Eigen::Vector3f
+copy(const struct xrt_vec3* v)
+{
+ return copy(*v);
+}
+
+
+/*
+ *
+ * Exported vector functions.
+ *
+ */
+void
+math_vec3_accum(const struct xrt_vec3* additional, struct xrt_vec3* inAndOut)
+{
+ assert(additional != NULL);
+ assert(inAndOut != NULL);
+
+ map_vec3(*inAndOut) += map_vec3(*additional);
+}
+
+/*
+ *
+ * Exported quaternion functions.
+ *
+ */
+
+void
+math_quat_rotate(const struct xrt_quat* left,
+ const struct xrt_quat* right,
+ struct xrt_quat* result)
+{
+ assert(left != NULL);
+ assert(right != NULL);
+ assert(result != NULL);
+
+ auto l = copy(left);
+ auto r = copy(right);
+
+ auto q = l * r;
+
+ map_quat(*result) = q;
+}
+
+void
+math_quat_rotate_vec3(const struct xrt_quat* left,
+ const struct xrt_vec3* right,
+ struct xrt_vec3* result)
+{
+ assert(left != NULL);
+ assert(right != NULL);
+ assert(result != NULL);
+
+ auto l = copy(left);
+ auto r = copy(right);
+
+ auto v = l * r;
+
+ map_vec3(*result) = v;
+}
+
+
+/*
+ *
+ * Exported pose functions.
+ *
+ */
+
+bool
+math_pose_validate(const struct xrt_pose* pose)
+{
+ assert(pose != NULL);
+
+ const float FLOAT_EPSILON = Eigen::NumTraits::epsilon();
+ auto norm = orientation(*pose).squaredNorm();
+ if (norm > 1.0f + FLOAT_EPSILON || norm < 1.0f - FLOAT_EPSILON) {
+ return false;
+ }
+
+ // Technically not yet a required check, but easier to stop problems
+ // now than once denormalized numbers pollute the rest of our state.
+ // see https://gitlab.khronos.org/openxr/openxr/issues/922
+ if (!orientation(*pose).coeffs().allFinite()) {
+ return false;
+ }
+ if (!position(*pose).allFinite()) {
+ return false;
+ }
+ return true;
+}
+
+void
+math_pose_invert(const struct xrt_pose* pose, struct xrt_pose* outPose)
+{
+ assert(pose != NULL);
+ assert(outPose != NULL);
+
+ // store results to temporary locals so we can do this "in-place"
+ // (pose == outPose) if desired.
+ Eigen::Vector3f newPosition = -position(*pose);
+ // Conjugate legal here since pose must be normalized/unit length.
+ Eigen::Quaternionf newOrientation = orientation(*pose).conjugate();
+
+ position(*outPose) = newPosition;
+ orientation(*outPose) = newOrientation;
+}
+
+/*!
+ * Return the result of transforming a point by a pose/transform.
+ */
+static inline Eigen::Vector3f
+transform_point(const xrt_pose& transform, const xrt_vec3& point)
+{
+ return orientation(transform) * map_vec3(point) + position(transform);
+}
+
+/*!
+ * Return the result of transforming a pose by a pose/transform.
+ */
+static inline xrt_pose
+transform_pose(const xrt_pose& transform, const xrt_pose& pose)
+{
+ xrt_pose ret;
+ position(ret) = transform_point(transform, pose.position);
+ orientation(ret) = orientation(transform) * orientation(pose);
+ return ret;
+}
+
+void
+math_pose_transform(const struct xrt_pose* transform,
+ const struct xrt_pose* pose,
+ struct xrt_pose* outPose)
+{
+ assert(pose != NULL);
+ assert(transform != NULL);
+ assert(outPose != NULL);
+
+ xrt_pose newPose = transform_pose(*transform, *pose);
+ memcpy(outPose, &newPose, sizeof(xrt_pose));
+}
+
+void
+math_pose_openxr_locate(const struct xrt_pose* space_pose,
+ const struct xrt_pose* relative_pose,
+ const struct xrt_pose* base_space_pose,
+ struct xrt_pose* result)
+{
+ assert(space_pose != NULL);
+ assert(relative_pose != NULL);
+ assert(base_space_pose != NULL);
+ assert(result != NULL);
+
+ // Compilers are slighty better optimizing
+ // if we copy the arguments in one go.
+ const auto bsp = *base_space_pose;
+ const auto rel = *relative_pose;
+ const auto spc = *space_pose;
+ struct xrt_pose pose;
+
+ // Apply the invert of the base space to identity.
+ math_pose_invert(&bsp, &pose);
+
+ // Apply the pure pose from the space relation.
+ math_pose_transform(&pose, &rel, &pose);
+
+ // Apply the space pose.
+ math_pose_transform(&pose, &spc, &pose);
+
+ *result = pose;
+}
+
+/*!
+ * Return the result of rotating a derivative vector by a matrix.
+ *
+ * This is a differential transform.
+ */
+static inline Eigen::Vector3f
+rotate_deriv(Eigen::Matrix3f const& rotation,
+ const xrt_vec3& derivativeVector,
+ Eigen::Matrix3f const& rotationInverse)
+{
+ return ((rotation * map_vec3(derivativeVector)).transpose() *
+ rotationInverse)
+ .transpose();
+}
+
+#ifndef XRT_DOXYGEN
+
+#define MAKE_REL_FLAG_CHECK(NAME, MASK) \
+ static inline bool NAME(xrt_space_relation_flags flags) \
+ { \
+ return ((flags & (MASK)) != 0); \
+ }
+
+MAKE_REL_FLAG_CHECK(has_some_pose_component,
+ XRT_SPACE_RELATION_POSITION_VALID_BIT |
+ XRT_SPACE_RELATION_ORIENTATION_VALID_BIT)
+MAKE_REL_FLAG_CHECK(has_position, XRT_SPACE_RELATION_POSITION_VALID_BIT)
+MAKE_REL_FLAG_CHECK(has_orientation, XRT_SPACE_RELATION_ORIENTATION_VALID_BIT)
+MAKE_REL_FLAG_CHECK(has_lin_vel, XRT_SPACE_RELATION_LINEAR_VELOCITY_VALID_BIT)
+MAKE_REL_FLAG_CHECK(has_ang_vel, XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT)
+MAKE_REL_FLAG_CHECK(has_lin_acc,
+ XRT_SPACE_RELATION_LINEAR_ACCELERATION_VALID_BIT)
+MAKE_REL_FLAG_CHECK(has_ang_acc,
+ XRT_SPACE_RELATION_ANGULAR_ACCELERATION_VALID_BIT)
+MAKE_REL_FLAG_CHECK(has_some_derivative,
+ XRT_SPACE_RELATION_LINEAR_VELOCITY_VALID_BIT |
+ XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT |
+ XRT_SPACE_RELATION_LINEAR_ACCELERATION_VALID_BIT |
+ XRT_SPACE_RELATION_ANGULAR_ACCELERATION_VALID_BIT)
+
+#undef MAKE_REL_FLAG_CHECK
+
+#endif // !XRT_DOXYGEN
+
+/*!
+ * Apply a transform to a space relation.
+ */
+static inline void
+transform_accumulate_pose(const xrt_pose& transform,
+ xrt_space_relation& relation,
+ bool do_translation = true,
+ bool do_rotation = true)
+{
+ assert(do_translation || do_rotation);
+
+ // Save the quat in case we are self-transforming.
+ Eigen::Quaternionf quat = orientation(transform);
+
+ auto flags = relation.relation_flags;
+ // so code looks similar
+ auto in_out_relation = &relation;
+
+ // transform (rotate and translate) the pose, if applicable.
+ if (has_some_pose_component(flags)) {
+ // Zero out transform parts we don't want to use,
+ // because math_pose_transform doesn't take flags.
+ xrt_pose transform_copy = transform;
+ if (!do_translation) {
+ position(transform_copy) = Eigen::Vector3f::Zero();
+ }
+ if (!do_rotation) {
+ orientation(transform_copy) =
+ Eigen::Quaternionf::Identity();
+ }
+
+ math_pose_transform(&in_out_relation->pose, &transform,
+ &in_out_relation->pose);
+ }
+
+ if (do_rotation && has_some_derivative(flags)) {
+
+ // prepare matrices required for rotating derivatives from the
+ // saved quat.
+ Eigen::Matrix3f rot = quat.toRotationMatrix();
+ Eigen::Matrix3f rotInverse = rot.inverse();
+
+ // Rotate derivatives, if applicable.
+ if (has_lin_vel(flags)) {
+ map_vec3(in_out_relation->linear_velocity) =
+ rotate_deriv(rot, in_out_relation->linear_velocity,
+ rotInverse);
+ }
+
+ if (has_ang_vel(flags)) {
+ map_vec3(in_out_relation->angular_velocity) =
+ rotate_deriv(rot, in_out_relation->angular_velocity,
+ rotInverse);
+ }
+
+ if (has_lin_acc(flags)) {
+ map_vec3(in_out_relation->linear_acceleration) =
+ rotate_deriv(rot,
+ in_out_relation->linear_acceleration,
+ rotInverse);
+ }
+
+ if (has_ang_acc(flags)) {
+ map_vec3(in_out_relation->angular_acceleration) =
+ rotate_deriv(rot,
+ in_out_relation->angular_acceleration,
+ rotInverse);
+ }
+ }
+}
+
+static const struct xrt_space_relation BLANK_RELATION = {
+ XRT_SPACE_RELATION_BITMASK_ALL,
+ {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+};
+
+void
+math_relation_reset(struct xrt_space_relation* out)
+{
+ *out = BLANK_RELATION;
+}
+
+void
+math_relation_accumulate_transform(const struct xrt_pose* transform,
+ struct xrt_space_relation* in_out_relation)
+{
+ assert(transform != nullptr);
+ assert(in_out_relation != nullptr);
+
+ // No modifying the validity flags here.
+ transform_accumulate_pose(*transform, *in_out_relation);
+}
+
+
+void
+math_relation_accumulate_relation(
+ const struct xrt_space_relation* additional_relation,
+ struct xrt_space_relation* in_out_relation)
+{
+ assert(additional_relation != NULL);
+ assert(in_out_relation != NULL);
+
+ // Update the flags.
+ xrt_space_relation_flags flags = (enum xrt_space_relation_flags)(
+ in_out_relation->relation_flags &
+ additional_relation->relation_flags);
+ in_out_relation->relation_flags = flags;
+
+ if (has_some_pose_component(flags)) {
+ // First, just do the pose part (including rotating
+ // derivatives, if applicable).
+ transform_accumulate_pose(additional_relation->pose,
+ *in_out_relation, has_position(flags),
+ has_orientation(flags));
+ }
+
+ // Then, accumulate the derivatives, if required.
+ if (has_lin_vel(flags)) {
+ map_vec3(in_out_relation->linear_velocity) +=
+ map_vec3(additional_relation->linear_velocity);
+ }
+
+ if (has_ang_vel(flags)) {
+ map_vec3(in_out_relation->angular_velocity) +=
+ map_vec3(additional_relation->angular_velocity);
+ }
+
+ if (has_lin_acc(flags)) {
+ map_vec3(in_out_relation->linear_acceleration) +=
+ map_vec3(additional_relation->linear_acceleration);
+ }
+
+ if (has_ang_acc(flags)) {
+ map_vec3(in_out_relation->angular_acceleration) +=
+ map_vec3(additional_relation->angular_acceleration);
+ }
+}
+
+void
+math_relation_openxr_locate(const struct xrt_pose* space_pose,
+ const struct xrt_space_relation* relative_relation,
+ const struct xrt_pose* base_space_pose,
+ struct xrt_space_relation* result)
+{
+ assert(space_pose != NULL);
+ assert(relative_relation != NULL);
+ assert(base_space_pose != NULL);
+ assert(result != NULL);
+
+ // Compilers are slighty better optimizing
+ // if we copy the arguments in one go.
+ const auto bsp = *base_space_pose;
+ const auto spc = *space_pose;
+ struct xrt_space_relation accumulating_relation = BLANK_RELATION;
+
+ // Apply the invert of the base space to identity.
+ math_pose_invert(&bsp, &accumulating_relation.pose);
+
+ // Apply the pure relation between spaces.
+ math_relation_accumulate_relation(relative_relation,
+ &accumulating_relation);
+
+ // Apply the space pose.
+ math_relation_accumulate_transform(&spc, &accumulating_relation);
+
+ *result = accumulating_relation;
+}
diff --git a/src/xrt/auxiliary/math/m_eigen_interop.h b/src/xrt/auxiliary/math/m_eigen_interop.h
new file mode 100644
index 000000000..8ea1c1748
--- /dev/null
+++ b/src/xrt/auxiliary/math/m_eigen_interop.h
@@ -0,0 +1,111 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Interoperability helpers connecting internal math types and Eigen.
+ * @author Ryan Pavlik
+ */
+
+#pragma once
+
+#ifndef __cplusplus
+#error "This header only usable from C++"
+#endif
+
+#include "math/m_api.h"
+
+#include
+#include
+
+/*!
+ * @brief Wrap an internal quaternion struct in an Eigen type, const overload.
+ *
+ * Permits zero-overhead manipulation of `const xrt_quat&` by Eigen routines as
+ * if it were a `const Eigen::Quaternionf&`.
+ */
+static inline Eigen::Map
+map_quat(const struct xrt_quat& q)
+{
+ return Eigen::Map{&q.x};
+}
+
+/*!
+ * @brief Wrap an internal quaternion struct in an Eigen type, non-const
+ * overload.
+ *
+ * Permits zero-overhead manipulation of `xrt_quat&` by Eigen routines as if it
+ * were a `Eigen::Quaternionf&`.
+ */
+static inline Eigen::Map
+map_quat(struct xrt_quat& q)
+{
+ return Eigen::Map{&q.x};
+}
+
+
+/*!
+ * @brief Wrap an internal 3D vector struct in an Eigen type, const overload.
+ *
+ * Permits zero-overhead manipulation of `const xrt_vec3&` by Eigen routines as
+ * if it were a `const Eigen::Vector3f&`.
+ */
+static inline Eigen::Map
+map_vec3(const struct xrt_vec3& v)
+{
+ return Eigen::Map{&v.x};
+}
+
+/*!
+ * @brief Wrap an internal 3D vector struct in an Eigen type, non-const
+ * overload.
+ *
+ * Permits zero-overhead manipulation of `xrt_vec3&` by Eigen routines as
+ * if it were a `Eigen::Vector3f&`.
+ */
+static inline Eigen::Map
+map_vec3(struct xrt_vec3& v)
+{
+ return Eigen::Map{&v.x};
+}
+
+/*
+ *
+ * Pose deconstruction helpers.
+ *
+ */
+
+/*!
+ * Return a Eigen type wrapping a pose's orientation (const).
+ */
+static inline Eigen::Map
+orientation(const struct xrt_pose& pose)
+{
+ return map_quat(pose.orientation);
+}
+
+/*!
+ * Return a Eigen type wrapping a pose's orientation.
+ */
+static inline Eigen::Map
+orientation(struct xrt_pose& pose)
+{
+ return map_quat(pose.orientation);
+}
+
+/*!
+ * Return a Eigen type wrapping a pose's position (const).
+ */
+static inline Eigen::Map
+position(const struct xrt_pose& pose)
+{
+ return map_vec3(pose.position);
+}
+
+/*!
+ * Return a Eigen type wrapping a pose's position.
+ */
+static inline Eigen::Map
+position(struct xrt_pose& pose)
+{
+ return map_vec3(pose.position);
+}
diff --git a/src/xrt/auxiliary/math/m_optics.c b/src/xrt/auxiliary/math/m_optics.c
new file mode 100644
index 000000000..fb1efae79
--- /dev/null
+++ b/src/xrt/auxiliary/math/m_optics.c
@@ -0,0 +1,167 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Functions related to field-of-view.
+ * @author Ryan Pavlik
+ */
+
+
+#include "m_api.h"
+#include "util/u_debug.h"
+#include
+#include
+#include
+
+DEBUG_GET_ONCE_BOOL_OPTION(views, "MATH_DEBUG_VIEWS", false)
+
+/*!
+ * Perform some of the computations from
+ * "Computing Half-Fields-Of-View from Simpler Display Models",
+ * to solve for the half-angles for a triangle where we know the center and
+ * total angle but not the "distance".
+ *
+ * In the diagram below, the top angle is theta_total, the length of the bottom
+ * is w_total, and the distance between the vertical line and the left corner is
+ * w_1.
+ * out_theta_1 is the angle at the top of the left-most right triangle,
+ * out_theta_2 is the angle at the top of the right-most right triangle,
+ * and out_d is the length of that center vertical line, a logical "distance".
+ *
+ * Any outparams that are NULL will simply not be set.
+ *
+ * The triangle need not be symmetrical, despite how the diagram looks.
+ *
+ * ```
+ * theta_total
+ * *
+ * theta_1 -> / | \ <- theta_2
+ * / | \
+ * / |d \
+ * / | \
+ * -------------
+ * [ w_1 ][ w_2 ]
+ *
+ * [ --- w --- ]
+ * ```
+ *
+ * Distances are in arbitrary but consistent units. Angles are in radians.
+ *
+ * @return true if successful.
+ */
+static bool
+math_solve_triangle(double w_total,
+ double w_1,
+ double theta_total,
+ double *out_theta_1,
+ double *out_theta_2,
+ double *out_d)
+{
+ /* should have at least one out-variable */
+ assert(out_theta_1 || out_theta_2 || out_d);
+ const double w_2 = w_total - w_1;
+
+ const double u = w_2 / w_1;
+ const double v = tan(theta_total);
+
+ /* Parts of the quadratic formula solution */
+ const double b = u + 1.0;
+ const double root = sqrt(b + 4 * u * v * v);
+ const double two_a = 2 * v;
+
+ /* The two possible solutions. */
+ const double tan_theta_2_plus = (-b + root) / two_a;
+ const double tan_theta_2_minus = (-b - root) / two_a;
+ const double theta_2_plus = atan(tan_theta_2_plus);
+ const double theta_2_minus = atan(tan_theta_2_minus);
+
+ /* Pick the solution that is in the right range. */
+ double tan_theta_2 = 0;
+ double theta_2 = 0;
+ if (theta_2_plus > 0.f && theta_2_plus < theta_total) {
+ // OH_DEBUG(ohd, "Using the + solution to the quadratic.");
+ tan_theta_2 = tan_theta_2_plus;
+ theta_2 = theta_2_plus;
+ } else if (theta_2_minus > 0.f && theta_2_minus < theta_total) {
+ // OH_DEBUG(ohd, "Using the - solution to the quadratic.");
+ tan_theta_2 = tan_theta_2_minus;
+ theta_2 = theta_2_minus;
+ } else {
+ // OH_ERROR(ohd, "NEITHER QUADRATIC SOLUTION APPLIES!");
+ return false;
+ }
+#define METERS_FORMAT "%0.4fm"
+#define DEG_FORMAT "%0.1f deg"
+ if (debug_get_bool_option_views()) {
+ const double rad_to_deg = M_1_PI * 180.0;
+ // comments are to force wrapping
+ fprintf(stderr,
+ "w=" METERS_FORMAT " theta=" DEG_FORMAT
+ " w1=" METERS_FORMAT " theta1=" DEG_FORMAT
+ " w2=" METERS_FORMAT " theta2=" DEG_FORMAT
+ " d=" METERS_FORMAT "\n",
+ w_total, theta_total * rad_to_deg, //
+ w_1, (theta_total - theta_2) * rad_to_deg, //
+ w_2, theta_2 * rad_to_deg, //
+ w_2 / tan_theta_2);
+ }
+ if (out_theta_2) {
+ *out_theta_2 = theta_2;
+ }
+
+ if (out_theta_1) {
+ *out_theta_1 = theta_total - theta_2;
+ }
+ if (out_d) {
+ *out_d = w_2 / tan_theta_2;
+ }
+ return true;
+}
+
+
+bool
+math_compute_fovs(double w_total,
+ double w_1,
+ double horizfov_total,
+ double h_total,
+ double h_1,
+ double vertfov_total,
+ struct xrt_fov *fov)
+{
+ double d = 0;
+ double theta_1 = 0;
+ double theta_2 = 0;
+ if (!math_solve_triangle(w_total, w_1, horizfov_total, &theta_1,
+ &theta_2, &d)) {
+ /* failure is contagious */
+ return false;
+ }
+
+ fov->angle_left = -theta_1;
+ fov->angle_right = theta_2;
+
+ double phi_1 = 0;
+ double phi_2 = 0;
+ if (vertfov_total == 0) {
+ phi_1 = atan(h_1 / d);
+
+ /* h_2 is "up".
+ * so the corresponding phi_2 is naturally positive.
+ */
+ const double h_2 = h_total - h_1;
+ phi_2 = atan(h_2 / d);
+ } else {
+ /* Run the same algorithm again for vertical. */
+ if (!math_solve_triangle(h_total, h_1, vertfov_total, &phi_1,
+ &phi_2, NULL)) {
+ /* failure is contagious */
+ return false;
+ }
+ }
+
+ /* phi_1 is "down" so we record this as negative. */
+ fov->angle_down = phi_1 * -1.0;
+ fov->angle_up = phi_2;
+
+ return true;
+}
diff --git a/src/xrt/auxiliary/math/m_quatexpmap.cpp b/src/xrt/auxiliary/math/m_quatexpmap.cpp
new file mode 100644
index 000000000..8b19cc471
--- /dev/null
+++ b/src/xrt/auxiliary/math/m_quatexpmap.cpp
@@ -0,0 +1,148 @@
+// Copyright 2019, Collabora, Ltd.
+// Copyright 2016, Sensics, Inc.
+// SPDX-License-Identifier: Apache-2.0
+/*!
+ * @file
+ * @brief Base implementations for math library.
+ * @author Ryan Pavlik
+ *
+ * Based in part on inc/osvr/Util/EigenQuatExponentialMap.h in OSVR-Core
+ */
+
+#include
+#include
+
+#include
+
+#include "math/m_api.h"
+#include "math/m_eigen_interop.h"
+
+// anonymous namespace for internal types
+namespace {
+template struct FourthRootMachineEps;
+template <> struct FourthRootMachineEps
+{
+ /// machine epsilon is 1e-53, so fourth root is roughly 1e-13
+ static double
+ get()
+ {
+ return 1.e-13;
+ }
+};
+template <> struct FourthRootMachineEps
+{
+ /// machine epsilon is 1e-24, so fourth root is 1e-6
+ static float
+ get()
+ {
+ return 1.e-6f;
+ }
+};
+/// Computes the "historical" (un-normalized) sinc(Theta)
+/// (sine(theta)/theta for theta != 0, defined as the limit value of 0
+/// at theta = 0)
+template
+inline Scalar
+sinc(Scalar theta)
+{
+ /// fourth root of machine epsilon is recommended cutoff for taylor
+ /// series expansion vs. direct computation per
+ /// Grassia, F. S. (1998). Practical Parameterization of Rotations
+ /// Using the Exponential Map. Journal of Graphics Tools, 3(3),
+ /// 29-48. http://doi.org/10.1080/10867651.1998.10487493
+ Scalar ret;
+ if (theta < FourthRootMachineEps::get()) {
+ // taylor series expansion.
+ ret = Scalar(1.f) - theta * theta / Scalar(6.f);
+ return ret;
+ }
+ // direct computation.
+ ret = std::sin(theta) / theta;
+ return ret;
+}
+
+/// fully-templated free function for quaternion expontiation
+template
+inline Eigen::Quaternion
+quat_exp(Eigen::MatrixBase const &vec)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived, 3);
+ using Scalar = typename Derived::Scalar;
+ /// Implementation inspired by
+ /// Grassia, F. S. (1998). Practical Parameterization of Rotations
+ /// Using the Exponential Map. Journal of Graphics Tools, 3(3),
+ /// 29–48. http://doi.org/10.1080/10867651.1998.10487493
+ ///
+ /// However, that work introduced a factor of 1/2 which I could not
+ /// derive from the definition of quaternion exponentiation and
+ /// whose absence thus distinguishes this implementation. Without
+ /// that factor of 1/2, the exp and ln functions successfully
+ /// round-trip and match other implementations.
+ Scalar theta = vec.norm();
+ Scalar vecscale = sinc(theta);
+ Eigen::Quaternion ret;
+ ret.vec() = vecscale * vec;
+ ret.w() = std::cos(theta);
+ return ret.normalized();
+}
+
+/// Taylor series expansion of theta over sin(theta), aka cosecant, for
+/// use near 0 when you want continuity and validity at 0.
+template
+inline Scalar
+cscTaylorExpansion(Scalar theta)
+{
+ return Scalar(1) +
+ // theta ^ 2 / 6
+ (theta * theta) / Scalar(6) +
+ // 7 theta^4 / 360
+ (Scalar(7) * theta * theta * theta * theta) / Scalar(360) +
+ // 31 theta^6/15120
+ (Scalar(31) * theta * theta * theta * theta * theta * theta) /
+ Scalar(15120);
+}
+
+/// fully-templated free function for quaternion log map.
+///
+/// Assumes a unit quaternion.
+template
+inline Eigen::Matrix
+quat_ln(Eigen::Quaternion const &quat)
+{
+ // ln q = ( (phi)/(norm of vec) vec, ln(norm of quat))
+ // When we assume a unit quaternion, ln(norm of quat) = 0
+ // so then we just scale the vector part by phi/sin(phi) to get the
+ // result (i.e., ln(qv, qw) = (phi/sin(phi)) * qv )
+ Scalar vecnorm = quat.vec().norm();
+
+ // "best for numerical stability" vs asin or acos
+ Scalar phi = std::atan2(vecnorm, quat.w());
+
+ // Here is where we compute the coefficient to scale the vector part
+ // by, which is nominally phi / std::sin(phi).
+ // When the angle approaches zero, we compute the coefficient
+ // differently, since it gets a bit like sinc in that we want it
+ // continuous but 0 is undefined.
+ Scalar phiOverSin = vecnorm < 1e-4 ? cscTaylorExpansion(phi)
+ : (phi / std::sin(phi));
+ return quat.vec() * phiOverSin;
+}
+
+} // namespace
+
+void
+math_quat_integrate_velocity(const struct xrt_quat *quat,
+ const struct xrt_vec3 *ang_vel,
+ const float dt,
+ struct xrt_quat *result)
+{
+ assert(quat != NULL);
+ assert(ang_vel != NULL);
+ assert(result != NULL);
+
+
+ Eigen::Quaternionf q = map_quat(*quat);
+ Eigen::Quaternionf incremental_rotation =
+ quat_exp(map_vec3(*ang_vel) * dt * 0.5f).normalized();
+ map_quat(*result) = q * incremental_rotation;
+}
diff --git a/src/xrt/auxiliary/util/u_debug.c b/src/xrt/auxiliary/util/u_debug.c
new file mode 100644
index 000000000..96805e964
--- /dev/null
+++ b/src/xrt/auxiliary/util/u_debug.c
@@ -0,0 +1,139 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Small debug helpers.
+ * @author Jakob Bornecrantz
+ *
+ * Debug get option helpers heavily inspired from mesa ones.
+ */
+
+#include
+#include
+#include
+
+#include "util/u_debug.h"
+
+
+
+DEBUG_GET_ONCE_BOOL_OPTION(print, "XRT_PRINT_OPTIONS", false)
+
+static const char *
+os_getenv(const char *name)
+{
+ return getenv(name);
+}
+
+const char *
+debug_get_option(const char *name, const char *_default)
+{
+ const char *raw = getenv(name);
+ const char *ret;
+
+ if (raw == NULL) {
+ ret = _default;
+ } else {
+ ret = raw;
+ }
+
+ if (debug_get_bool_option_print()) {
+ fprintf(stderr, "%s=%s (%s)\n", name, ret,
+ raw == NULL ? "nil" : raw);
+ }
+
+ return ret;
+}
+
+bool
+debug_get_bool_option(const char *name, bool _default)
+{
+ const char *raw = os_getenv(name);
+ bool ret;
+
+ if (raw == NULL) {
+ ret = _default;
+ } else if (!strcmp(raw, "false")) {
+ ret = false;
+ } else if (!strcmp(raw, "FALSE")) {
+ ret = false;
+ } else if (!strcmp(raw, "off")) {
+ ret = false;
+ } else if (!strcmp(raw, "OFF")) {
+ ret = false;
+ } else if (!strcmp(raw, "no")) {
+ ret = false;
+ } else if (!strcmp(raw, "NO")) {
+ ret = false;
+ } else if (!strcmp(raw, "n")) {
+ ret = false;
+ } else if (!strcmp(raw, "N")) {
+ ret = false;
+ } else if (!strcmp(raw, "f")) {
+ ret = false;
+ } else if (!strcmp(raw, "F")) {
+ ret = false;
+ } else if (!strcmp(raw, "0")) {
+ ret = false;
+ } else {
+ ret = true;
+ }
+
+ if (debug_get_bool_option_print()) {
+ fprintf(stderr, "%s=%s (%s)\n", name, ret ? "TRUE" : "FALSE",
+ raw == NULL ? "nil" : raw);
+ }
+
+ return ret;
+}
+
+long
+debug_get_num_option(const char *name, long _default)
+{
+ const char *raw = os_getenv(name);
+ long ret;
+
+ if (raw == NULL) {
+ ret = _default;
+ } else {
+ char *endptr;
+
+ ret = strtol(raw, &endptr, 0);
+ // Restore the default value when no digits were found.
+ if (raw == endptr) {
+ ret = _default;
+ }
+ }
+
+ if (debug_get_bool_option_print()) {
+ fprintf(stderr, "%s=%li (%s)\n", name, ret,
+ raw == NULL ? "nil" : raw);
+ }
+
+ return ret;
+}
+
+float
+debug_get_float_option(const char *name, float _default)
+{
+ const char *raw = os_getenv(name);
+ float ret;
+
+ if (raw == NULL) {
+ ret = _default;
+ } else {
+ char *endptr;
+
+ ret = strtof(raw, &endptr);
+ // Restore the default value when no digits were found.
+ if (raw == endptr) {
+ ret = _default;
+ }
+ }
+
+ if (debug_get_bool_option_print()) {
+ fprintf(stderr, "%s=%f (%s)\n", name, ret,
+ raw == NULL ? "nil" : raw);
+ }
+
+ return ret;
+}
diff --git a/src/xrt/auxiliary/util/u_debug.h b/src/xrt/auxiliary/util/u_debug.h
new file mode 100644
index 000000000..e9dd7c2d3
--- /dev/null
+++ b/src/xrt/auxiliary/util/u_debug.h
@@ -0,0 +1,81 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Small debug helpers.
+ * @author Jakob Bornecrantz
+ *
+ * Debug get option helpers heavily inspired from mesa ones.
+ */
+
+#pragma once
+
+#include "xrt/xrt_compiler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+const char *
+debug_get_option(const char *name, const char *_default);
+
+bool
+debug_get_bool_option(const char *name, bool _default);
+
+long
+debug_get_num_option(const char *name, long _default);
+
+float
+debug_get_float_option(const char *name, float _default);
+
+#define DEBUG_GET_ONCE_OPTION(suffix, name, _default) \
+ static const char *debug_get_option_##suffix() \
+ { \
+ static bool gotten = false; \
+ static const char *stored; \
+ if (!gotten) { \
+ gotten = true; \
+ stored = debug_get_option(name, _default); \
+ } \
+ return stored; \
+ }
+
+#define DEBUG_GET_ONCE_BOOL_OPTION(suffix, name, _default) \
+ static bool debug_get_bool_option_##suffix() \
+ { \
+ static bool gotten = false; \
+ static bool stored; \
+ if (!gotten) { \
+ gotten = true; \
+ stored = debug_get_bool_option(name, _default); \
+ } \
+ return stored; \
+ }
+
+#define DEBUG_GET_ONCE_NUM_OPTION(suffix, name, _default) \
+ static long debug_get_num_option_##suffix() \
+ { \
+ static long gotten = false; \
+ static long stored; \
+ if (!gotten) { \
+ gotten = true; \
+ stored = debug_get_num_option(name, _default); \
+ } \
+ return stored; \
+ }
+
+#define DEBUG_GET_ONCE_FLOAT_OPTION(suffix, name, _default) \
+ static long debug_get_float_option_##suffix() \
+ { \
+ static long gotten = false; \
+ static long stored; \
+ if (!gotten) { \
+ gotten = true; \
+ stored = debug_get_float_option(name, _default); \
+ } \
+ return stored; \
+ }
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/auxiliary/util/u_device.c b/src/xrt/auxiliary/util/u_device.c
new file mode 100644
index 000000000..ed4274d5c
--- /dev/null
+++ b/src/xrt/auxiliary/util/u_device.c
@@ -0,0 +1,126 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Misc helpers for device drivers.
+ * @author Jakob Bornecrantz
+ */
+
+#include
+#include
+#include
+
+#include "util/u_device.h"
+
+
+/*
+ *
+ * Matricies.
+ *
+ */
+
+const struct xrt_matrix_2x2 u_device_rotation_right = {{
+ .vecs =
+ {
+ {0, 1},
+ {-1, 0},
+ },
+}};
+
+
+const struct xrt_matrix_2x2 u_device_rotation_left = {{
+ .vecs =
+ {
+ {0, -1},
+ {1, 0},
+ },
+}};
+
+const struct xrt_matrix_2x2 u_device_rotation_ident = {{
+ .vecs =
+ {
+ {1, 0},
+ {0, 1},
+ },
+}};
+
+const struct xrt_matrix_2x2 u_device_rotation_180 = {{
+ .vecs =
+ {
+ {-1, 0},
+ {0, -1},
+ },
+}};
+
+/*
+ *
+ * Print helpers.
+ *
+ */
+
+#define PRINT(...) fprintf(stderr, __VA_ARGS__)
+
+#define PRINT_STR(name, val) PRINT("\t%s = %s\n", name, val)
+
+#define PRINT_INT(name, val) PRINT("\t%s = %u\n", name, val)
+
+#define PRINT_MM(name, val) \
+ PRINT("\t%s = %f (%i.%02imm)\n", name, val, (int32_t)(val * 1000.f), \
+ abs((int32_t)(val * 100000.f)) % 100)
+
+#define PRINT_ANGLE(name, val) \
+ PRINT("\t%s = %f (%i°)\n", name, val, (int32_t)(val * (180 / M_PI)))
+
+#define PRINT_MAT2X2(name, rot) \
+ PRINT("\t%s = {%f, %f} {%f, %f}\n", name, rot.v[0], rot.v[1], \
+ rot.v[2], rot.v[3])
+
+/*!
+ * Dump the device config to stderr.
+ */
+void
+u_device_dump_config(struct xrt_device* xdev,
+ const char* prefix,
+ const char* prod)
+{
+ // clang-format off
+ fprintf(stderr, "%s - device_setup\n", prefix);
+ PRINT_STR( "prod", prod);
+ PRINT_INT( "screens[0].w_pixels ", xdev->screens[0].w_pixels);
+ PRINT_INT( "screens[0].h_pixels ", xdev->screens[0].h_pixels);
+// PRINT_MM( "info.display.w_meters", info.display.w_meters);
+// PRINT_MM( "info.display.h_meters", info.display.h_meters);
+ PRINT_INT( "views[0].viewport.x_pixels ", xdev->views[0].viewport.x_pixels);
+ PRINT_INT( "views[0].viewport.y_pixels ", xdev->views[0].viewport.y_pixels);
+ PRINT_INT( "views[0].viewport.w_pixels ", xdev->views[0].viewport.w_pixels);
+ PRINT_INT( "views[0].viewport.h_pixels ", xdev->views[0].viewport.h_pixels);
+ PRINT_INT( "views[0].display.w_pixels ", xdev->views[0].display.w_pixels);
+ PRINT_INT( "views[0].display.h_pixels ", xdev->views[0].display.h_pixels);
+ PRINT_MM( "views[0].display.w_meters ", xdev->views[0].display.w_meters);
+ PRINT_MM( "views[0].display.h_meters ", xdev->views[0].display.h_meters);
+ PRINT_MM( "views[0].lens_center.x_meters", xdev->views[0].lens_center.x_meters);
+ PRINT_MM( "views[0].lens_center.y_meters", xdev->views[0].lens_center.y_meters);
+ PRINT_MAT2X2("views[0].rot ", xdev->views[0].rot);
+ PRINT_ANGLE( "views[0].fov.angle_left ", xdev->views[0].fov.angle_left);
+ PRINT_ANGLE( "views[0].fov.angle_right", xdev->views[0].fov.angle_right);
+ PRINT_ANGLE( "views[0].fov.angle_up ", xdev->views[0].fov.angle_up);
+ PRINT_ANGLE( "views[0].fov.angle_down ", xdev->views[0].fov.angle_down);
+// PRINT_ANGLE( "info.views[0].fov ", info.views[0].fov);
+ PRINT_INT( "views[1].viewport.x_pixels ", xdev->views[1].viewport.x_pixels);
+ PRINT_INT( "views[1].viewport.y_pixels ", xdev->views[1].viewport.y_pixels);
+ PRINT_INT( "views[1].viewport.w_pixels ", xdev->views[1].viewport.w_pixels);
+ PRINT_INT( "views[1].viewport.h_pixels ", xdev->views[1].viewport.h_pixels);
+ PRINT_INT( "views[1].display.w_pixels ", xdev->views[1].display.w_pixels);
+ PRINT_INT( "views[1].display.h_pixels ", xdev->views[1].display.h_pixels);
+ PRINT_MM( "views[1].display.w_meters ", xdev->views[1].display.w_meters);
+ PRINT_MM( "views[1].display.h_meters ", xdev->views[1].display.h_meters);
+ PRINT_MM( "views[1].lens_center.x_meters", xdev->views[1].lens_center.x_meters);
+ PRINT_MM( "views[1].lens_center.y_meters", xdev->views[1].lens_center.y_meters);
+ PRINT_MAT2X2("views[1].rot ", xdev->views[1].rot);
+ PRINT_ANGLE( "views[1].fov.angle_left ", xdev->views[1].fov.angle_left);
+ PRINT_ANGLE( "views[1].fov.angle_right", xdev->views[1].fov.angle_right);
+ PRINT_ANGLE( "views[1].fov.angle_up ", xdev->views[1].fov.angle_up);
+ PRINT_ANGLE( "views[1].fov.angle_down ", xdev->views[1].fov.angle_down);
+// PRINT_ANGLE( "info.views[1].fov ", info.views[0].fov);
+ // clang-format on
+}
diff --git a/src/xrt/auxiliary/util/u_device.h b/src/xrt/auxiliary/util/u_device.h
new file mode 100644
index 000000000..645092604
--- /dev/null
+++ b/src/xrt/auxiliary/util/u_device.h
@@ -0,0 +1,35 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Misc helpers for device drivers.
+ * @author Jakob Bornecrantz
+ */
+
+#pragma once
+
+#include "xrt/xrt_compiler.h"
+#include "xrt/xrt_device.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern const struct xrt_matrix_2x2 u_device_rotation_right;
+extern const struct xrt_matrix_2x2 u_device_rotation_left;
+extern const struct xrt_matrix_2x2 u_device_rotation_ident;
+extern const struct xrt_matrix_2x2 u_device_rotation_180;
+
+/*!
+ * Dump the device config to stderr.
+ */
+void
+u_device_dump_config(struct xrt_device* xdev,
+ const char* prefix,
+ const char* prod);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/auxiliary/util/u_misc.c b/src/xrt/auxiliary/util/u_misc.c
new file mode 100644
index 000000000..72bdd15d7
--- /dev/null
+++ b/src/xrt/auxiliary/util/u_misc.c
@@ -0,0 +1,16 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Very small misc utils.
+ * @author Jakob Bornecrantz
+ */
+
+#include "util/u_misc.h"
+
+
+int
+u_silence_pedantic_warning()
+{
+ return 42;
+}
diff --git a/src/xrt/auxiliary/util/u_misc.h b/src/xrt/auxiliary/util/u_misc.h
new file mode 100644
index 000000000..d149ffa39
--- /dev/null
+++ b/src/xrt/auxiliary/util/u_misc.h
@@ -0,0 +1,19 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Very small misc utils.
+ * @author Jakob Bornecrantz
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/auxiliary/util/u_time.cpp b/src/xrt/auxiliary/util/u_time.cpp
new file mode 100644
index 000000000..64e580cd6
--- /dev/null
+++ b/src/xrt/auxiliary/util/u_time.cpp
@@ -0,0 +1,135 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Implementation of a steady, convertible clock.
+ * @author Ryan Pavlik
+ */
+
+#include "u_time.h"
+
+#include
+#include
+#include
+#include
+
+using namespace std::chrono;
+
+struct MatchingTimePoints
+{
+ system_clock::time_point sys;
+ steady_clock::time_point steady;
+ // high_resolution_clock::time_point highRes;
+
+ //! Initializes to "right now" in all clocks
+ MatchingTimePoints();
+
+ timepoint_ns
+ getTimestamp(time_state const& prevState);
+};
+
+struct time_state
+{
+ MatchingTimePoints lastTimePoints;
+ timepoint_ns lastTime;
+};
+
+MatchingTimePoints::MatchingTimePoints()
+ : sys(system_clock::now()), steady(steady_clock::now())
+{}
+
+timepoint_ns
+MatchingTimePoints::getTimestamp(time_state const& prevState)
+{
+ //! @todo right now just doing steady clock for simplicity.
+ //! @todo Eventually need to make the high-res clock steady.
+ auto elapsed = steady - prevState.lastTimePoints.steady;
+ return prevState.lastTime + duration_cast(elapsed).count();
+}
+
+struct time_state*
+time_state_create()
+{
+
+ time_state* state = new (std::nothrow) time_state;
+ return state;
+}
+
+void
+time_state_destroy(struct time_state* state)
+{
+ delete state;
+}
+
+timepoint_ns
+time_state_get_now(struct time_state const* state)
+{
+ assert(state != NULL);
+ auto now = MatchingTimePoints();
+
+ return now.getTimestamp(*state);
+}
+
+timepoint_ns
+time_state_get_now_and_update(struct time_state* state)
+{
+ assert(state != NULL);
+ auto now = MatchingTimePoints();
+
+ auto timestamp = now.getTimestamp(*state);
+
+ // Update the state
+ state->lastTimePoints = now;
+ state->lastTime = timestamp;
+
+ return timestamp;
+}
+
+void
+time_state_to_timespec(struct time_state const* state,
+ timepoint_ns timestamp,
+ struct timespec* out)
+{
+ assert(state != NULL);
+ assert(out != NULL);
+ // Subject to some jitter, roughly up to the magnitude of the actual
+ // resolution difference between the used time source and the system
+ // clock, as well as the non-simultaneity of the calls in
+ // MatchingTimePoints::getNow()
+ auto sinceLastUpdate = nanoseconds{timestamp - state->lastTime};
+ auto equivSystemTimepoint = state->lastTimePoints.sys + sinceLastUpdate;
+
+ // System clock epoch is same as unix epoch for all known
+ // implementations, but not strictly standard-required yet, see
+ // wg21.link/p0355
+ auto sinceEpoch = equivSystemTimepoint.time_since_epoch();
+ auto secondsSinceEpoch = duration_cast(sinceEpoch);
+ sinceEpoch -= secondsSinceEpoch;
+ out->tv_sec = secondsSinceEpoch.count();
+ out->tv_nsec = duration_cast(sinceEpoch).count();
+}
+
+
+timepoint_ns
+time_state_from_timespec(struct time_state const* state,
+ const struct timespec* timespecTime)
+{
+ assert(state != NULL);
+ assert(timespecTime != NULL);
+ auto sinceEpoch =
+ seconds{timespecTime->tv_sec} + nanoseconds{timespecTime->tv_nsec};
+
+
+ // System clock epoch is same as unix epoch for all known
+ // implementations, but not strictly standard-required yet, see
+ // wg21.link/p0355
+ auto systemTimePoint = time_point{
+ duration_cast(sinceEpoch)};
+
+ // duration between last update and the supplied timespec
+ auto sinceLastUpdate = state->lastTimePoints.sys - systemTimePoint;
+
+ // Offset the last timestamp by that duration.
+ return state->lastTime +
+ duration_cast(sinceLastUpdate).count();
+}
\ No newline at end of file
diff --git a/src/xrt/auxiliary/util/u_time.h b/src/xrt/auxiliary/util/u_time.h
new file mode 100644
index 000000000..bc284eae3
--- /dev/null
+++ b/src/xrt/auxiliary/util/u_time.h
@@ -0,0 +1,106 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Time-keeping: a clock that is steady, convertible to system time, and
+ * ideally high-resolution.
+ * @author Ryan Pavlik
+ *
+ * @see time_state
+ */
+
+#pragma once
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * Integer timestamp type.
+ *
+ * @see time_state
+ */
+typedef int64_t timepoint_ns;
+
+/*!
+ * @struct time_state util/u_time.h
+ * @brief Time-keeping state structure.
+ *
+ * Exposed as an opaque pointer.
+ *
+ * @see timepoint_ns
+ */
+struct time_state;
+
+/*!
+ * Create a struct time_state.
+ *
+ * @public @memberof time_state
+ */
+struct time_state*
+time_state_create();
+
+
+/*!
+ * Destroy a struct time_state.
+ *
+ * Should not be called simultaneously with any other time_state function.
+ *
+ * @public @memberof time_state
+ */
+void
+time_state_destroy(struct time_state* state);
+
+/*!
+ * Get the current time as an integer timestamp.
+ *
+ * Does not update internal state for timekeeping.
+ * Should not be called simultaneously with time_state_get_now_and_update.
+ *
+ * @public @memberof time_state
+ */
+timepoint_ns
+time_state_get_now(struct time_state const* state);
+
+/*!
+ * Get the current time as an integer timestamp and update internal state.
+ *
+ * This should be called regularly, but only from one thread.
+ * It updates the association between the timing sources.
+ *
+ * Should not be called simultaneously with any other time_state function.
+ *
+ * @public @memberof time_state
+ */
+timepoint_ns
+time_state_get_now_and_update(struct time_state* state);
+
+/*!
+ * Convert an integer timestamp to a struct timespec (system time).
+ *
+ * Should not be called simultaneously with time_state_get_now_and_update.
+ *
+ * @public @memberof time_state
+ */
+void
+time_state_to_timespec(struct time_state const* state,
+ timepoint_ns timestamp,
+ struct timespec* out);
+
+/*!
+ * Convert a struct timespec (system time) to an integer timestamp.
+ *
+ * Should not be called simultaneously with time_state_get_now_and_update.
+ *
+ * @public @memberof time_state
+ */
+timepoint_ns
+time_state_from_timespec(struct time_state const* state,
+ const struct timespec* timespecTime);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/compositor/CMakeLists.txt b/src/xrt/compositor/CMakeLists.txt
new file mode 100644
index 000000000..406d55041
--- /dev/null
+++ b/src/xrt/compositor/CMakeLists.txt
@@ -0,0 +1,62 @@
+# Copyright 2019, Collabora, Ltd.
+# SPDX-License-Identifier: BSL-1.0
+
+spirv_shaders(SHADER_HEADERS
+ shaders/distortion.vert
+ shaders/none.frag
+ shaders/panotools.frag
+ shaders/vive.frag
+ )
+
+set(GL_SOURCE_FILES
+ ${SHADER_HEADERS}
+ client/comp_gl_api.c
+ client/comp_gl_api.h
+ client/comp_gl_client.c
+ client/comp_gl_client.h
+ client/comp_vk_client.c
+ client/comp_vk_client.h
+ client/comp_xlib_client.c
+ common/comp_vk.c
+ common/comp_vk.h
+ common/comp_vk_swapchain.h
+ common/comp_vk_swapchain.c
+ main/comp_client_interface.h
+ main/comp_compositor.c
+ main/comp_compositor.h
+ main/comp_distortion.c
+ main/comp_distortion.h
+ main/comp_glue_gl.c
+ main/comp_glue_vk.c
+ main/comp_glue_xlib.c
+ main/comp_renderer.c
+ main/comp_renderer.h
+ main/comp_settings.c
+ main/comp_settings.h
+ main/comp_swapchain.c
+ main/comp_window.h
+ main/comp_window_direct_mode.cpp
+ main/comp_window_wayland.cpp
+ main/comp_window_xcb.cpp
+ )
+
+if (${XCB_FOUND})
+ add_definitions(-DVK_USE_PLATFORM_XCB_KHR)
+ add_definitions(-DVK_USE_PLATFORM_XLIB_XRANDR_EXT)
+endif()
+
+# Use OBJECT to not create a archive, since it just gets in the way.
+add_library(comp OBJECT ${GL_SOURCE_FILES})
+set_property(TARGET comp PROPERTY POSITION_INDEPENDENT_CODE ON)
+target_include_directories(comp
+ PRIVATE
+ ${XCB_INCLUDE_DIRS}
+ ${VULKAN_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../auxiliary
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../external
+ ${CMAKE_CURRENT_BINARY_DIR}
+ )
+
+add_subdirectory(shaders)
diff --git a/src/xrt/compositor/client/comp_gl_api.c b/src/xrt/compositor/client/comp_gl_api.c
new file mode 100644
index 000000000..62f2fef4e
--- /dev/null
+++ b/src/xrt/compositor/client/comp_gl_api.c
@@ -0,0 +1,10 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief OpenGL API wrapper.
+ * @author Jakob Bornecrantz
+ * @ingroup comp_client
+ */
+
+#include "glad/gl.c"
diff --git a/src/xrt/compositor/client/comp_gl_api.h b/src/xrt/compositor/client/comp_gl_api.h
new file mode 100644
index 000000000..6a6b9b091
--- /dev/null
+++ b/src/xrt/compositor/client/comp_gl_api.h
@@ -0,0 +1,12 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief OpenGL API wrapper header.
+ * @author Jakob Bornecrantz
+ * @ingroup comp_client
+ */
+
+#pragma once
+
+#include "glad/gl.h"
diff --git a/src/xrt/compositor/client/comp_gl_client.c b/src/xrt/compositor/client/comp_gl_client.c
new file mode 100644
index 000000000..f738daff3
--- /dev/null
+++ b/src/xrt/compositor/client/comp_gl_client.c
@@ -0,0 +1,242 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief OpenGL client side glue to compositor implementation.
+ * @author Jakob Bornecrantz
+ * @ingroup comp_client
+ */
+
+#include
+#include
+#include
+
+#include "client/comp_gl_api.h"
+#include "client/comp_gl_client.h"
+
+
+/*
+ *
+ * Swapchain functions.
+ *
+ */
+
+static void
+client_gl_swapchain_destroy(struct xrt_swapchain *xsc)
+{
+ struct client_gl_swapchain *sc = client_gl_swapchain(xsc);
+
+ uint32_t num_images = sc->base.base.num_images;
+ if (num_images > 0) {
+ glDeleteTextures(num_images, &sc->base.images[0]);
+ memset(sc->base.images, 0, sizeof(sc->base.images));
+ glDeleteMemoryObjectsEXT(num_images, &sc->base.memory[0]);
+ memset(sc->base.images, 0, sizeof(sc->base.memory));
+ sc->base.base.num_images = 0;
+ }
+
+ // Destroy the fd swapchain as well.
+ sc->xscfd->base.destroy(&sc->xscfd->base);
+
+ free(sc);
+}
+
+static bool
+client_gl_swapchain_acquire_image(struct xrt_swapchain *xsc, uint32_t *index)
+{
+ struct client_gl_swapchain *sc = client_gl_swapchain(xsc);
+
+ // Pipe down call into fd swapchain.
+ return sc->xscfd->base.acquire_image(&sc->xscfd->base, index);
+}
+
+static bool
+client_gl_swapchain_wait_image(struct xrt_swapchain *xsc,
+ uint64_t timeout,
+ uint32_t index)
+{
+ struct client_gl_swapchain *sc = client_gl_swapchain(xsc);
+
+ // Pipe down call into fd swapchain.
+ return sc->xscfd->base.wait_image(&sc->xscfd->base, timeout, index);
+}
+
+static bool
+client_gl_swapchain_release_image(struct xrt_swapchain *xsc, uint32_t index)
+{
+ struct client_gl_swapchain *sc = client_gl_swapchain(xsc);
+
+ // Pipe down call into fd swapchain.
+ return sc->xscfd->base.release_image(&sc->xscfd->base, index);
+}
+
+
+/*
+ *
+ * Compositor functions.
+ *
+ */
+
+static void
+client_gl_compositor_begin_session(struct xrt_compositor *xc,
+ enum xrt_view_type type)
+{
+ struct client_gl_compositor *c = client_gl_compositor(xc);
+ // Pipe down call into fd compositor.
+ c->xcfd->base.begin_session(&c->xcfd->base, type);
+}
+
+static void
+client_gl_compositor_end_session(struct xrt_compositor *xc)
+{
+ struct client_gl_compositor *c = client_gl_compositor(xc);
+ // Pipe down call into fd compositor.
+ c->xcfd->base.end_session(&c->xcfd->base);
+}
+
+static void
+client_gl_compositor_wait_frame(struct xrt_compositor *xc,
+ int64_t *predicted_display_time,
+ int64_t *predicted_display_period)
+{
+ struct client_gl_compositor *c = client_gl_compositor(xc);
+ // Pipe down call into fd compositor.
+ c->xcfd->base.wait_frame(&c->xcfd->base, predicted_display_time,
+ predicted_display_period);
+}
+
+static void
+client_gl_compositor_begin_frame(struct xrt_compositor *xc)
+{
+ struct client_gl_compositor *c = client_gl_compositor(xc);
+ // Pipe down call into fd compositor.
+ c->xcfd->base.begin_frame(&c->xcfd->base);
+}
+
+static void
+client_gl_compositor_discard_frame(struct xrt_compositor *xc)
+{
+ struct client_gl_compositor *c = client_gl_compositor(xc);
+ // Pipe down call into fd compositor.
+ c->xcfd->base.discard_frame(&c->xcfd->base);
+}
+
+static void
+client_gl_compositor_end_frame(struct xrt_compositor *xc,
+ enum xrt_blend_mode blend_mode,
+ struct xrt_swapchain **xscs,
+ uint32_t *acquired_index,
+ uint32_t num_swapchains)
+{
+ struct client_gl_compositor *c = client_gl_compositor(xc);
+ struct xrt_swapchain *internal[8];
+
+ if (num_swapchains > 8) {
+ fprintf(stderr, "ERROR! %s\n", __func__);
+ return;
+ }
+
+ for (uint32_t i = 0; i < num_swapchains; i++) {
+ struct client_gl_swapchain *sc = client_gl_swapchain(xscs[i]);
+ internal[i] = &sc->xscfd->base;
+ }
+
+ // Pipe down call into fd compositor.
+ c->xcfd->base.end_frame(&c->xcfd->base, blend_mode, internal,
+ acquired_index, num_swapchains);
+}
+
+static int64_t
+gl_format_to_vk(int64_t format)
+{
+ switch (format) {
+ case GL_RGBA8: return 37 /*VK_FORMAT_R8G8B8A8_UNORM*/;
+ default: return 0;
+ }
+}
+
+static struct xrt_swapchain *
+client_gl_swapchain_create(struct xrt_compositor *xc,
+ enum xrt_swapchain_create_flags create,
+ enum xrt_swapchain_usage_bits bits,
+ int64_t format,
+ uint32_t sample_count,
+ uint32_t width,
+ uint32_t height,
+ uint32_t face_count,
+ uint32_t array_size,
+ uint32_t mip_count)
+{
+ struct client_gl_compositor *c = client_gl_compositor(xc);
+ uint32_t num_images = 3;
+
+ int64_t vk_format = gl_format_to_vk(format);
+ if (vk_format == 0) {
+ fprintf(stderr, "%s - Invalid format!\n", __func__);
+ return NULL;
+ }
+
+ struct xrt_swapchain *xsc = c->xcfd->base.create_swapchain(
+ &c->xcfd->base, create, bits, vk_format, sample_count, width,
+ height, face_count, array_size, mip_count);
+
+ if (xsc == NULL) {
+ return NULL;
+ }
+
+ struct client_gl_swapchain *sc =
+ calloc(1, sizeof(struct client_gl_swapchain));
+ sc->base.base.destroy = client_gl_swapchain_destroy;
+ sc->base.base.acquire_image = client_gl_swapchain_acquire_image;
+ sc->base.base.wait_image = client_gl_swapchain_wait_image;
+ sc->base.base.release_image = client_gl_swapchain_release_image;
+ sc->base.base.num_images = num_images;
+ sc->xscfd = xrt_swapchain_fd(xsc);
+
+ glCreateTextures(GL_TEXTURE_2D, num_images, &sc->base.images[0]);
+ glCreateMemoryObjectsEXT(num_images, &sc->base.memory[0]);
+ for (uint32_t i = 0; i < num_images; i++) {
+ GLint dedicated = GL_TRUE;
+ glMemoryObjectParameterivEXT(sc->base.memory[i],
+ GL_DEDICATED_MEMORY_OBJECT_EXT,
+ &dedicated);
+ glImportMemoryFdEXT(
+ sc->base.memory[i], sc->xscfd->images[i].size,
+ GL_HANDLE_TYPE_OPAQUE_FD_EXT, sc->xscfd->images[i].fd);
+ glTextureStorageMem2DEXT(sc->base.images[i], mip_count,
+ (GLuint)format, width, height,
+ sc->base.memory[i], 0);
+ }
+
+ return &sc->base.base;
+}
+
+bool
+client_gl_compositor_init(struct client_gl_compositor *c,
+ struct xrt_compositor_fd *xcfd,
+ client_gl_get_procaddr get_gl_procaddr)
+{
+ c->base.base.create_swapchain = client_gl_swapchain_create;
+ c->base.base.begin_session = client_gl_compositor_begin_session;
+ c->base.base.end_session = client_gl_compositor_end_session;
+ c->base.base.wait_frame = client_gl_compositor_wait_frame;
+ c->base.base.begin_frame = client_gl_compositor_begin_frame;
+ c->base.base.discard_frame = client_gl_compositor_discard_frame;
+ c->base.base.end_frame = client_gl_compositor_end_frame;
+ c->base.base.formats[0] = GL_RGBA8;
+ c->base.base.num_formats = 1;
+ c->xcfd = xcfd;
+
+ gladLoadGL(get_gl_procaddr);
+
+ if (!GLAD_GL_EXT_memory_object_fd) {
+ // @todo log this to a proper logger.
+ fprintf(stderr,
+ "%s - Needed extension"
+ " GL_EXT_memory_object_fd not supported\n",
+ __func__);
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/xrt/compositor/client/comp_gl_client.h b/src/xrt/compositor/client/comp_gl_client.h
new file mode 100644
index 000000000..2c59cc5a1
--- /dev/null
+++ b/src/xrt/compositor/client/comp_gl_client.h
@@ -0,0 +1,91 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief OpenGL client side glue to compositor header.
+ * @author Jakob Bornecrantz
+ * @ingroup comp_client
+ */
+
+#pragma once
+
+#include "xrt/xrt_compositor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ *
+ * Structs
+ *
+ */
+
+/*!
+ * Wraps the real compositor swapchain providing a OpenGL based interface.
+ *
+ * Almost a one to one mapping to a OpenXR swapchain.
+ *
+ * @ingroup comp_client
+ */
+struct client_gl_swapchain
+{
+ struct xrt_swapchain_gl base;
+
+ struct xrt_swapchain_fd *xscfd;
+};
+
+/*!
+ * Wraps the real compositor providing a OpenGL based interface.
+ *
+ * @ingroup comp_client
+ */
+struct client_gl_compositor
+{
+ struct xrt_compositor_gl base;
+
+ struct xrt_compositor_fd *xcfd;
+};
+
+
+/*
+ *
+ * Functions and helpers.
+ *
+ */
+
+/*!
+ * Convinence function to convert a xrt_swapchain to a client_gl_swapchain.
+ */
+XRT_MAYBE_UNUSED static struct client_gl_swapchain *
+client_gl_swapchain(struct xrt_swapchain *xsc)
+{
+ return (struct client_gl_swapchain *)xsc;
+}
+
+/*!
+ * Convinence function to convert a xrt_compositor to a client_gl_compositor.
+ */
+XRT_MAYBE_UNUSED static struct client_gl_compositor *
+client_gl_compositor(struct xrt_compositor *xc)
+{
+ return (struct client_gl_compositor *)xc;
+}
+
+typedef void (*client_gl_void_ptr_func)();
+
+typedef client_gl_void_ptr_func (*client_gl_get_procaddr)(const char *name);
+
+/*!
+ * Fill in a client_gl_compositor and do common OpenGL sanity checking.
+ */
+bool
+client_gl_compositor_init(struct client_gl_compositor *c,
+ struct xrt_compositor_fd *xcfd,
+ client_gl_get_procaddr get_gl_procaddr);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/compositor/client/comp_vk_client.c b/src/xrt/compositor/client/comp_vk_client.c
new file mode 100644
index 000000000..ca9ae0964
--- /dev/null
+++ b/src/xrt/compositor/client/comp_vk_client.c
@@ -0,0 +1,276 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Vulkan client side glue to compositor implementation.
+ * @author Jakob Bornecrantz
+ * @author Lubosz Sarnecki
+ * @ingroup comp_client
+ */
+
+#include
+#include
+
+#include "comp_vk_client.h"
+
+
+/*
+ *
+ * Swapchain function.
+ *
+ */
+
+static void
+client_vk_swapchain_destroy(struct xrt_swapchain *xsc)
+{
+ struct client_vk_swapchain *sc = client_vk_swapchain(xsc);
+ struct client_vk_compositor *c = sc->c;
+
+ for (uint32_t i = 0; i < sc->base.base.num_images; i++) {
+ if (sc->base.images[i] != NULL) {
+ c->vk.vkDestroyImage(c->vk.device, sc->base.images[i],
+ NULL);
+ sc->base.images[i] = NULL;
+ }
+
+ if (sc->base.mems[i] != NULL) {
+ c->vk.vkFreeMemory(c->vk.device, sc->base.mems[i],
+ NULL);
+ sc->base.mems[i] = NULL;
+ }
+ }
+
+ // Destroy the fd swapchain as well.
+ sc->xscfd->base.destroy(&sc->xscfd->base);
+
+ free(sc);
+}
+
+static bool
+client_vk_swapchain_acquire_image(struct xrt_swapchain *xsc, uint32_t *index)
+{
+ struct client_vk_swapchain *sc = client_vk_swapchain(xsc);
+
+ // Pipe down call into fd swapchain.
+ return sc->xscfd->base.acquire_image(&sc->xscfd->base, index);
+}
+
+static bool
+client_vk_swapchain_wait_image(struct xrt_swapchain *xsc,
+ uint64_t timeout,
+ uint32_t index)
+{
+ struct client_vk_swapchain *sc = client_vk_swapchain(xsc);
+
+ // Pipe down call into fd swapchain.
+ return sc->xscfd->base.wait_image(&sc->xscfd->base, timeout, index);
+}
+
+static bool
+client_vk_swapchain_release_image(struct xrt_swapchain *xsc, uint32_t index)
+{
+ struct client_vk_swapchain *sc = client_vk_swapchain(xsc);
+
+ // Pipe down call into fd swapchain.
+ return sc->xscfd->base.release_image(&sc->xscfd->base, index);
+}
+
+
+/*
+ *
+ * Compositor functions.
+ *
+ */
+
+static void
+client_vk_compositor_destroy(struct xrt_compositor *xc)
+{
+ struct client_vk_compositor *c = client_vk_compositor(xc);
+ // Pipe down call into fd compositor.
+ c->xcfd->base.destroy(&c->xcfd->base);
+ free(c);
+}
+
+static void
+client_vk_compositor_begin_session(struct xrt_compositor *xc,
+ enum xrt_view_type type)
+{
+ struct client_vk_compositor *c = client_vk_compositor(xc);
+ // Pipe down call into fd compositor.
+ c->xcfd->base.begin_session(&c->xcfd->base, type);
+}
+
+static void
+client_vk_compositor_end_session(struct xrt_compositor *xc)
+{
+ struct client_vk_compositor *c = client_vk_compositor(xc);
+ // Pipe down call into fd compositor.
+ c->xcfd->base.end_session(&c->xcfd->base);
+}
+
+static void
+client_vk_compositor_wait_frame(struct xrt_compositor *xc,
+ int64_t *predicted_display_time,
+ int64_t *predicted_display_period)
+{
+ struct client_vk_compositor *c = client_vk_compositor(xc);
+ // Pipe down call into fd compositor.
+ c->xcfd->base.wait_frame(&c->xcfd->base, predicted_display_time,
+ predicted_display_period);
+}
+
+static void
+client_vk_compositor_begin_frame(struct xrt_compositor *xc)
+{
+ struct client_vk_compositor *c = client_vk_compositor(xc);
+ // Pipe down call into fd compositor.
+ c->xcfd->base.begin_frame(&c->xcfd->base);
+}
+
+static void
+client_vk_compositor_discard_frame(struct xrt_compositor *xc)
+{
+ struct client_vk_compositor *c = client_vk_compositor(xc);
+ // Pipe down call into fd compositor.
+ c->xcfd->base.discard_frame(&c->xcfd->base);
+}
+
+static void
+client_vk_compositor_end_frame(struct xrt_compositor *xc,
+ enum xrt_blend_mode blend_mode,
+ struct xrt_swapchain **xscs,
+ uint32_t *acquired_index,
+ uint32_t num_swapchains)
+{
+ struct client_vk_compositor *c = client_vk_compositor(xc);
+ struct xrt_swapchain *internal[8];
+
+ if (num_swapchains > 8) {
+ fprintf(stderr, "ERROR! %s\n", __func__);
+ return;
+ }
+
+ for (uint32_t i = 0; i < num_swapchains; i++) {
+ struct client_vk_swapchain *sc = client_vk_swapchain(xscs[i]);
+ internal[i] = &sc->xscfd->base;
+ }
+
+ // Pipe down call into fd compositor.
+ c->xcfd->base.end_frame(&c->xcfd->base, blend_mode, internal,
+ acquired_index, num_swapchains);
+}
+
+static struct xrt_swapchain *
+client_vk_swapchain_create(struct xrt_compositor *xc,
+ enum xrt_swapchain_create_flags create,
+ enum xrt_swapchain_usage_bits bits,
+ int64_t format,
+ uint32_t sample_count,
+ uint32_t width,
+ uint32_t height,
+ uint32_t face_count,
+ uint32_t array_size,
+ uint32_t mip_count)
+{
+ struct client_vk_compositor *c = client_vk_compositor(xc);
+ VkCommandBuffer cmd_buffer;
+ uint32_t num_images = 3;
+ VkResult ret;
+
+ struct xrt_swapchain *xsc = c->xcfd->base.create_swapchain(
+ &c->xcfd->base, create, bits, format, sample_count, width, height,
+ face_count, array_size, mip_count);
+
+ if (xsc == NULL) {
+ return NULL;
+ }
+
+ ret = vk_init_cmd_buffer(&c->vk, &cmd_buffer);
+ if (ret != VK_SUCCESS) {
+ return NULL;
+ }
+
+ VkImageSubresourceRange subresource_range = {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .baseMipLevel = 0,
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ .layerCount = 1,
+ };
+
+ struct client_vk_swapchain *sc =
+ calloc(1, sizeof(struct client_vk_swapchain));
+ sc->base.base.destroy = client_vk_swapchain_destroy;
+ sc->base.base.acquire_image = client_vk_swapchain_acquire_image;
+ sc->base.base.wait_image = client_vk_swapchain_wait_image;
+ sc->base.base.release_image = client_vk_swapchain_release_image;
+ sc->base.base.num_images = num_images;
+ sc->c = c;
+ sc->xscfd = xrt_swapchain_fd(xsc);
+
+ for (uint32_t i = 0; i < num_images; i++) {
+ ret = vk_create_image_from_fd(&c->vk, format, width, height,
+ mip_count, &sc->xscfd->images[i],
+ &sc->base.images[i],
+ &sc->base.mems[i]);
+ if (ret != VK_SUCCESS) {
+ return NULL;
+ }
+
+ vk_set_image_layout(&c->vk, cmd_buffer, sc->base.images[i], 0,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ subresource_range);
+ }
+
+ ret = vk_submit_cmd_buffer(&c->vk, cmd_buffer);
+ if (ret != VK_SUCCESS) {
+ return NULL;
+ }
+
+ return &sc->base.base;
+}
+
+struct client_vk_compositor *
+client_vk_compositor_create(struct xrt_compositor_fd *xcfd,
+ VkInstance instance,
+ PFN_vkGetInstanceProcAddr getProc,
+ VkPhysicalDevice physicalDevice,
+ VkDevice device,
+ uint32_t queueFamilyIndex,
+ uint32_t queueIndex)
+{
+ VkResult ret;
+ struct client_vk_compositor *c =
+ calloc(1, sizeof(struct client_vk_compositor));
+
+ c->base.base.create_swapchain = client_vk_swapchain_create;
+ c->base.base.begin_session = client_vk_compositor_begin_session;
+ c->base.base.end_session = client_vk_compositor_end_session;
+ c->base.base.wait_frame = client_vk_compositor_wait_frame;
+ c->base.base.begin_frame = client_vk_compositor_begin_frame;
+ c->base.base.discard_frame = client_vk_compositor_discard_frame;
+ c->base.base.end_frame = client_vk_compositor_end_frame;
+ c->base.base.destroy = client_vk_compositor_destroy;
+
+ c->base.base.formats[0] = VK_FORMAT_B8G8R8A8_SRGB;
+ c->base.base.formats[1] = VK_FORMAT_R8G8B8A8_SRGB;
+ c->base.base.formats[2] = VK_FORMAT_B8G8R8A8_UNORM;
+ c->base.base.formats[3] = VK_FORMAT_R8G8B8A8_UNORM;
+ c->base.base.num_formats = 4;
+
+ c->xcfd = xcfd;
+
+ ret = vk_init_from_given(&c->vk, getProc, instance, physicalDevice,
+ device, queueFamilyIndex, queueIndex);
+ if (ret != VK_SUCCESS) {
+ goto err_free;
+ }
+
+ return c;
+
+err_free:
+ free(c);
+ return NULL;
+}
diff --git a/src/xrt/compositor/client/comp_vk_client.h b/src/xrt/compositor/client/comp_vk_client.h
new file mode 100644
index 000000000..861daa779
--- /dev/null
+++ b/src/xrt/compositor/client/comp_vk_client.h
@@ -0,0 +1,103 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Vulkan client side glue to compositor header.
+ * @author Jakob Bornecrantz
+ * @author Lubosz Sarnecki
+ * @ingroup comp_client
+ */
+
+#pragma once
+
+#include "common/comp_vk.h"
+#include "xrt/xrt_gfx_vk.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ *
+ * Structs
+ *
+ */
+
+struct client_vk_compositor;
+
+/*!
+ * Wraps the real compositor swapchain providing a Vulkan based interface.
+ *
+ * Almost a one to one mapping to a OpenXR swapchain.
+ *
+ * @ingroup comp_client
+ */
+struct client_vk_swapchain
+{
+ struct xrt_swapchain_vk base;
+ struct xrt_swapchain_fd *xscfd;
+ struct client_vk_compositor *c;
+};
+
+/*!
+ * Wraps the real compositor providing a Vulkan based interface.
+ *
+ * @ingroup comp_client
+ */
+struct client_vk_compositor
+{
+ struct xrt_compositor_vk base;
+
+ struct xrt_compositor_fd *xcfd;
+
+ struct vk_bundle vk;
+};
+
+
+/*
+ *
+ * Functions and helpers.
+ *
+ */
+
+/*!
+ * Convinence function to convert a xrt_swapchain to a client_vk_swapchain.
+ *
+ * @ingroup comp_client
+ */
+XRT_MAYBE_UNUSED static struct client_vk_swapchain *
+client_vk_swapchain(struct xrt_swapchain *xsc)
+{
+ return (struct client_vk_swapchain *)xsc;
+}
+
+/*!
+ * Convinence function to convert a xrt_compositor to a client_vk_compositor.
+ *
+ * @ingroup comp_client
+ */
+XRT_MAYBE_UNUSED static struct client_vk_compositor *
+client_vk_compositor(struct xrt_compositor *xc)
+{
+ return (struct client_vk_compositor *)xc;
+}
+
+/*!
+ * Create a new client_vk_compositor.
+ *
+ * @ingroup comp_client
+ */
+struct client_vk_compositor *
+client_vk_compositor_create(struct xrt_compositor_fd *c,
+ VkInstance instance,
+ PFN_vkGetInstanceProcAddr getProc,
+ VkPhysicalDevice physicalDevice,
+ VkDevice device,
+ uint32_t queueFamilyIndex,
+ uint32_t queueIndex);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/compositor/client/comp_xlib_client.c b/src/xrt/compositor/client/comp_xlib_client.c
new file mode 100644
index 000000000..6e9a0ca45
--- /dev/null
+++ b/src/xrt/compositor/client/comp_xlib_client.c
@@ -0,0 +1,51 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Xlib client side glue to compositor implementation.
+ * @author Jakob Bornecrantz
+ * @ingroup comp_client
+ */
+
+#include
+#include
+
+#include "xrt/xrt_gfx_xlib.h"
+
+#include "client/comp_xlib_client.h"
+
+
+static void
+client_xlib_compositor_destroy(struct xrt_compositor *xc)
+{
+ struct client_xlib_compositor *c = client_xlib_compositor(xc);
+ // Pipe down call into fd compositor.
+ c->base.xcfd->base.destroy(&c->base.xcfd->base);
+ free(c);
+}
+
+typedef void (*void_ptr_func)();
+
+void_ptr_func
+glXGetProcAddress(const char *procName);
+
+struct client_xlib_compositor *
+client_xlib_compositor_create(struct xrt_compositor_fd *xcfd,
+ Display *xDisplay,
+ uint32_t visualid,
+ GLXFBConfig glxFBConfig,
+ GLXDrawable glxDrawable,
+ GLXContext glxContext)
+{
+ struct client_xlib_compositor *c =
+ calloc(1, sizeof(struct client_xlib_compositor));
+
+ if (!client_gl_compositor_init(&c->base, xcfd, glXGetProcAddress)) {
+ free(c);
+ return NULL;
+ }
+
+ c->base.base.base.destroy = client_xlib_compositor_destroy;
+
+ return c;
+}
diff --git a/src/xrt/compositor/client/comp_xlib_client.h b/src/xrt/compositor/client/comp_xlib_client.h
new file mode 100644
index 000000000..becd60ef2
--- /dev/null
+++ b/src/xrt/compositor/client/comp_xlib_client.h
@@ -0,0 +1,58 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Xlib client side glue to compositor header.
+ * @author Jakob Bornecrantz
+ * @ingroup comp_client
+ */
+
+#pragma once
+
+#include "xrt/xrt_gfx_xlib.h"
+#include "client/comp_gl_client.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*!
+ * A client facing xlib base compositor.
+ *
+ * @ingroup comp_client
+ */
+struct client_xlib_compositor
+{
+ //! OpenGL compositor wrapper base.
+ struct client_gl_compositor base;
+};
+
+/*!
+ * Convinence function to convert a xrt_compositor to a client_xlib_compositor.
+ *
+ * @ingroup comp_client
+ */
+XRT_MAYBE_UNUSED static struct client_xlib_compositor *
+client_xlib_compositor(struct xrt_compositor *xc)
+{
+ return (struct client_xlib_compositor *)xc;
+}
+
+/*!
+ * Create a new client_xlib_compositor_create.
+ *
+ * @ingroup comp_client
+ */
+struct client_xlib_compositor *
+client_xlib_compositor_create(struct xrt_compositor_fd *xcfd,
+ Display *xDisplay,
+ uint32_t visualid,
+ GLXFBConfig glxFBConfig,
+ GLXDrawable glxDrawable,
+ GLXContext glxContext);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/compositor/common/comp_vk.c b/src/xrt/compositor/common/comp_vk.c
new file mode 100644
index 000000000..f9ce1b845
--- /dev/null
+++ b/src/xrt/compositor/common/comp_vk.c
@@ -0,0 +1,1003 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Common Vulkan code.
+ * @author Jakob Bornecrantz
+ * @author Lubosz Sarnecki
+ * @ingroup comp_common
+ */
+
+#include
+#include
+#include
+
+#include "util/u_debug.h"
+#include "common/comp_vk.h"
+
+
+/*
+ *
+ * String helper functions.
+ *
+ */
+
+#define ENUM_TO_STR(r) \
+ case r: return #r
+
+const char *
+vk_result_string(VkResult code)
+{
+ switch (code) {
+ ENUM_TO_STR(VK_SUCCESS);
+ ENUM_TO_STR(VK_NOT_READY);
+ ENUM_TO_STR(VK_TIMEOUT);
+ ENUM_TO_STR(VK_EVENT_SET);
+ ENUM_TO_STR(VK_EVENT_RESET);
+ ENUM_TO_STR(VK_INCOMPLETE);
+ ENUM_TO_STR(VK_ERROR_OUT_OF_HOST_MEMORY);
+ ENUM_TO_STR(VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ ENUM_TO_STR(VK_ERROR_INITIALIZATION_FAILED);
+ ENUM_TO_STR(VK_ERROR_DEVICE_LOST);
+ ENUM_TO_STR(VK_ERROR_MEMORY_MAP_FAILED);
+ ENUM_TO_STR(VK_ERROR_LAYER_NOT_PRESENT);
+ ENUM_TO_STR(VK_ERROR_EXTENSION_NOT_PRESENT);
+ ENUM_TO_STR(VK_ERROR_FEATURE_NOT_PRESENT);
+ ENUM_TO_STR(VK_ERROR_INCOMPATIBLE_DRIVER);
+ ENUM_TO_STR(VK_ERROR_TOO_MANY_OBJECTS);
+ ENUM_TO_STR(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ ENUM_TO_STR(VK_ERROR_SURFACE_LOST_KHR);
+ ENUM_TO_STR(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR);
+ ENUM_TO_STR(VK_SUBOPTIMAL_KHR);
+ ENUM_TO_STR(VK_ERROR_OUT_OF_DATE_KHR);
+ ENUM_TO_STR(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR);
+ ENUM_TO_STR(VK_ERROR_VALIDATION_FAILED_EXT);
+ ENUM_TO_STR(VK_ERROR_INVALID_SHADER_NV);
+ ENUM_TO_STR(VK_ERROR_INVALID_EXTERNAL_HANDLE);
+ default: return "UNKNOWN RESULT";
+ }
+}
+
+const char *
+vk_color_format_string(VkFormat code)
+{
+ switch (code) {
+ ENUM_TO_STR(VK_FORMAT_B8G8R8A8_UNORM);
+ ENUM_TO_STR(VK_FORMAT_UNDEFINED);
+ ENUM_TO_STR(VK_FORMAT_R8G8B8A8_SRGB);
+ ENUM_TO_STR(VK_FORMAT_B8G8R8A8_SRGB);
+ ENUM_TO_STR(VK_FORMAT_R8G8B8_SRGB);
+ ENUM_TO_STR(VK_FORMAT_B8G8R8_SRGB);
+ ENUM_TO_STR(VK_FORMAT_R5G6B5_UNORM_PACK16);
+ ENUM_TO_STR(VK_FORMAT_B5G6R5_UNORM_PACK16);
+ ENUM_TO_STR(VK_FORMAT_D32_SFLOAT_S8_UINT);
+ ENUM_TO_STR(VK_FORMAT_D32_SFLOAT);
+ ENUM_TO_STR(VK_FORMAT_D24_UNORM_S8_UINT);
+ ENUM_TO_STR(VK_FORMAT_D16_UNORM_S8_UINT);
+ ENUM_TO_STR(VK_FORMAT_D16_UNORM);
+ default: return "UNKNOWN FORMAT";
+ }
+}
+
+const char *
+vk_present_mode_string(VkPresentModeKHR code)
+{
+ switch (code) {
+ ENUM_TO_STR(VK_PRESENT_MODE_FIFO_KHR);
+ ENUM_TO_STR(VK_PRESENT_MODE_MAILBOX_KHR);
+ ENUM_TO_STR(VK_PRESENT_MODE_IMMEDIATE_KHR);
+ ENUM_TO_STR(VK_PRESENT_MODE_FIFO_RELAXED_KHR);
+ ENUM_TO_STR(VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR);
+ ENUM_TO_STR(VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR);
+ default: return "UNKNOWN MODE";
+ }
+}
+
+const char *
+vk_power_state_string(VkDisplayPowerStateEXT code)
+{
+ switch (code) {
+ ENUM_TO_STR(VK_DISPLAY_POWER_STATE_OFF_EXT);
+ ENUM_TO_STR(VK_DISPLAY_POWER_STATE_SUSPEND_EXT);
+ ENUM_TO_STR(VK_DISPLAY_POWER_STATE_ON_EXT);
+ default: return "UNKNOWN MODE";
+ }
+}
+
+const char *
+vk_color_space_string(VkColorSpaceKHR code)
+{
+ switch (code) {
+ ENUM_TO_STR(VK_COLORSPACE_SRGB_NONLINEAR_KHR);
+ default: return "UNKNOWN COLOR SPACE";
+ }
+}
+
+
+/*
+ *
+ * Functions.
+ *
+ */
+
+bool
+vk_get_memory_type(struct vk_bundle *vk,
+ uint32_t type_bits,
+ VkMemoryPropertyFlags memory_props,
+ uint32_t *out_type_id)
+{
+
+ for (uint32_t i = 0; i < vk->device_memory_props.memoryTypeCount; i++) {
+ uint32_t propertyFlags =
+ vk->device_memory_props.memoryTypes[i].propertyFlags;
+ if ((type_bits & 1) == 1) {
+ if ((propertyFlags & memory_props) == memory_props) {
+ *out_type_id = i;
+ return true;
+ }
+ }
+ type_bits >>= 1;
+ }
+
+ VK_DEBUG(vk, "Could not find memory type!");
+
+ return false;
+}
+
+VkResult
+vk_create_image_simple(struct vk_bundle *vk,
+ uint32_t width,
+ uint32_t height,
+ VkFormat format,
+ VkDeviceMemory *out_mem,
+ VkImage *out_image)
+{
+ VkImageUsageFlags usage_flags;
+ VkDeviceMemory memory;
+ VkImage image;
+ VkResult ret;
+
+ usage_flags = 0;
+ usage_flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
+ usage_flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+
+ VkImageCreateInfo image_info = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ .imageType = VK_IMAGE_TYPE_2D,
+ .format = format,
+ .extent =
+ {
+ .width = width,
+ .height = height,
+ .depth = 1,
+ },
+ .mipLevels = 1,
+ .arrayLayers = 1,
+ .samples = VK_SAMPLE_COUNT_1_BIT,
+ .tiling = VK_IMAGE_TILING_LINEAR,
+ .usage = usage_flags,
+ .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
+ .queueFamilyIndexCount = 0,
+ .pQueueFamilyIndices = NULL,
+ .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
+ };
+
+ ret = vk->vkCreateImage(vk->device, &image_info, NULL, &image);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkCreateImage: %s", vk_result_string(ret));
+ goto err;
+ }
+
+ VkMemoryRequirements memory_requirements;
+ vk->vkGetImageMemoryRequirements(vk->device, image,
+ &memory_requirements);
+
+ uint32_t memory_type_index;
+ vk_get_memory_type(vk, memory_requirements.memoryTypeBits,
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+ &memory_type_index);
+
+ VkMemoryAllocateInfo alloc_info = {
+ .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+ .pNext = NULL,
+ .allocationSize = memory_requirements.size,
+ .memoryTypeIndex = memory_type_index,
+ };
+
+ ret = vk->vkAllocateMemory(vk->device, &alloc_info, NULL, &memory);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkAllocateMemory: %s", vk_result_string(ret));
+ goto err_image;
+ }
+
+ // Bind the memory to the image.
+ ret = vk->vkBindImageMemory(vk->device, image, memory, 0);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkBindImageMemory: %s", vk_result_string(ret));
+ goto err_mem;
+ }
+
+ *out_image = image;
+ *out_mem = memory;
+
+ return ret;
+
+err_mem:
+ vk->vkFreeMemory(vk->device, memory, NULL);
+err_image:
+ vk->vkDestroyImage(vk->device, image, NULL);
+err:
+ return ret;
+}
+
+VkResult
+vk_create_image_from_fd(struct vk_bundle *vk,
+ int64_t format,
+ uint32_t width,
+ uint32_t height,
+ uint32_t mip_count,
+ struct xrt_image_fd *image_fd,
+ VkImage *out_image,
+ VkDeviceMemory *out_mem)
+{
+ VkMemoryRequirements memory_requirements;
+ VkImageUsageFlagBits image_usage = 0;
+ VkDeviceMemory device_memory = NULL;
+ uint32_t memory_type_index = UINT32_MAX;
+ VkImage image = NULL;
+ VkResult ret = VK_SUCCESS;
+
+ VkExternalMemoryImageCreateInfoKHR external_memory_image_create_info = {
+ .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR,
+ .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
+ };
+
+ image_usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
+ image_usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+ image_usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+
+ VkImageCreateInfo info = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+ .pNext = &external_memory_image_create_info,
+ .imageType = VK_IMAGE_TYPE_2D,
+ .format = format,
+ .extent = {.width = width, .height = height, .depth = 1},
+ .mipLevels = mip_count,
+ .arrayLayers = 1,
+ .samples = VK_SAMPLE_COUNT_1_BIT,
+ .tiling = VK_IMAGE_TILING_OPTIMAL,
+ .usage = image_usage,
+ .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
+ .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
+ };
+
+ ret = vk->vkCreateImage(vk->device, &info, NULL, &image);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkCreateImage: %s", vk_result_string(ret));
+ goto err;
+ }
+
+ vk->vkGetImageMemoryRequirements(vk->device, image,
+ &memory_requirements);
+ if (memory_requirements.size > image_fd->size) {
+ VK_ERROR(vk,
+ "client_vk_swapchain - Got too little memory "
+ "%u vs %u\n",
+ (uint32_t)memory_requirements.size,
+ (uint32_t)image_fd->size);
+ }
+
+ if (!vk_get_memory_type(vk, memory_requirements.memoryTypeBits,
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+ &memory_type_index)) {
+ VK_ERROR(c, "vk_get_memory_type failed!");
+ ret = VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ goto err_image;
+ }
+
+ VkMemoryDedicatedAllocateInfoKHR dedicated_memory_info = {
+ .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
+ .pNext = NULL,
+ .image = image,
+ .buffer = VK_NULL_HANDLE,
+ };
+
+ VkImportMemoryFdInfoKHR import_memory_info = {
+ .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
+ .pNext = &dedicated_memory_info,
+ .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
+ .fd = image_fd->fd,
+ };
+
+ VkMemoryAllocateInfo alloc_info = {
+ .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+ .pNext = &import_memory_info,
+ .allocationSize = memory_requirements.size,
+ .memoryTypeIndex = memory_type_index,
+ };
+
+ ret =
+ vk->vkAllocateMemory(vk->device, &alloc_info, NULL, &device_memory);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkAllocateMemory: %s", vk_result_string(ret));
+ goto err_image;
+ }
+
+ // Bind the memory to the image.
+ ret = vk->vkBindImageMemory(vk->device, image, device_memory, 0);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkBindImageMemory: %s", vk_result_string(ret));
+ goto err_mem;
+ }
+
+ *out_image = image;
+ *out_mem = device_memory;
+
+ return ret;
+
+err_mem:
+ vk->vkFreeMemory(vk->device, device_memory, NULL);
+err_image:
+ vk->vkDestroyImage(vk->device, image, NULL);
+err:
+ return ret;
+}
+
+VkResult
+vk_create_sampler(struct vk_bundle *vk, VkSampler *out_sampler)
+{
+ VkSampler sampler;
+ VkResult ret;
+
+ VkSamplerCreateInfo info = {
+ .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ .magFilter = VK_FILTER_NEAREST,
+ .minFilter = VK_FILTER_NEAREST,
+ .mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR,
+ .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
+ .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
+ .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
+ .mipLodBias = 0.0f,
+ .anisotropyEnable = VK_FALSE,
+ .maxAnisotropy = 1.0f,
+ .compareEnable = VK_FALSE,
+ .compareOp = VK_COMPARE_OP_NEVER,
+ .minLod = 0.0f,
+ .maxLod = 1.0f,
+ .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
+ .unnormalizedCoordinates = VK_FALSE,
+ };
+
+ ret = vk->vkCreateSampler(vk->device, &info, NULL, &sampler);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkCreateSampler: %s", vk_result_string(ret));
+ return ret;
+ }
+
+ *out_sampler = sampler;
+
+ return VK_SUCCESS;
+}
+
+VkResult
+vk_create_view(struct vk_bundle *vk,
+ VkImage image,
+ VkFormat format,
+ VkImageView *out_view)
+{
+ VkImageView view;
+ VkResult ret;
+
+ VkImageViewCreateInfo imageView = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ .image = image,
+ .viewType = VK_IMAGE_VIEW_TYPE_2D,
+ .format = format,
+ .components =
+ {
+ .r = VK_COMPONENT_SWIZZLE_R,
+ .g = VK_COMPONENT_SWIZZLE_G,
+ .b = VK_COMPONENT_SWIZZLE_B,
+ .a = VK_COMPONENT_SWIZZLE_A,
+ },
+ .subresourceRange =
+ {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .baseMipLevel = 0,
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ .layerCount = 1,
+ },
+ };
+
+ ret = vk->vkCreateImageView(vk->device, &imageView, NULL, &view);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(c, "vkCreateImageView: %s", vk_result_string(ret));
+ return ret;
+ }
+
+ *out_view = view;
+
+ return VK_SUCCESS;
+}
+
+
+/*
+ *
+ * Command buffer code.
+ *
+ */
+
+VkResult
+vk_init_cmd_buffer(struct vk_bundle *vk, VkCommandBuffer *out_cmd_buffer)
+{
+ VkCommandBuffer cmd_buffer;
+ VkResult ret;
+
+ // Allocate the command buffer.
+ VkCommandBufferAllocateInfo cmd_buffer_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+ .commandPool = vk->cmd_pool,
+ .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+ .commandBufferCount = 1,
+ };
+
+ ret = vk->vkAllocateCommandBuffers(vk->device, &cmd_buffer_info,
+ &cmd_buffer);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkAllocateCommandBuffers: %s",
+ vk_result_string(ret));
+ goto err;
+ }
+
+ // Start the command buffer as well.
+ VkCommandBufferBeginInfo begin_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+ };
+ ret = vk->vkBeginCommandBuffer(cmd_buffer, &begin_info);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkBeginCommandBuffer: %s", vk_result_string(ret));
+ goto err_buffer;
+ }
+
+ *out_cmd_buffer = cmd_buffer;
+
+ return VK_SUCCESS;
+
+
+err_buffer:
+ vk->vkFreeCommandBuffers(vk->device, vk->cmd_pool, 1, &cmd_buffer);
+
+err:
+ return ret;
+}
+
+VkResult
+vk_set_image_layout(struct vk_bundle *vk,
+ VkCommandBuffer cmd_buffer,
+ VkImage image,
+ VkAccessFlags src_access_mask,
+ VkAccessFlags dst_access_mask,
+ VkImageLayout old_layout,
+ VkImageLayout new_layout,
+ VkImageSubresourceRange subresource_range)
+{
+ VkImageMemoryBarrier barrier = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+ .srcAccessMask = src_access_mask,
+ .dstAccessMask = dst_access_mask,
+ .oldLayout = old_layout,
+ .newLayout = new_layout,
+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .image = image,
+ .subresourceRange = subresource_range,
+ };
+
+ vk->vkCmdPipelineBarrier(cmd_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, NULL,
+ 0, NULL, 1, &barrier);
+
+ return VK_SUCCESS;
+}
+
+VkResult
+vk_submit_cmd_buffer(struct vk_bundle *vk, VkCommandBuffer cmd_buffer)
+{
+ VkResult ret = VK_SUCCESS;
+ VkQueue queue;
+ VkFence fence;
+
+ // Finish the command buffer first.
+ ret = vk->vkEndCommandBuffer(cmd_buffer);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkEndCommandBuffer: %s", vk_result_string(ret));
+ goto out;
+ }
+
+ // Get the queue.
+ vk->vkGetDeviceQueue(vk->device, vk->queue_family_index, 0, &queue);
+
+ // Create the fence.
+ VkFenceCreateInfo fence_info = {
+ .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+ };
+ ret = vk->vkCreateFence(vk->device, &fence_info, NULL, &fence);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkCreateFence: %s", vk_result_string(ret));
+ goto out;
+ }
+
+ // Do the actual submitting.
+ VkSubmitInfo submitInfo = {
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+ .commandBufferCount = 1,
+ .pCommandBuffers = &cmd_buffer,
+ };
+
+ ret = vk->vkQueueSubmit(queue, 1, &submitInfo, fence);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "Error: Could not submit queue.\n");
+ goto out_fence;
+ }
+
+ // Then wait for the fence.
+ ret = vk->vkWaitForFences(vk->device, 1, &fence, VK_TRUE, 1000000000);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkWaitForFences: %s", vk_result_string(ret));
+ goto out_fence;
+ }
+
+ // Yes fall through.
+
+out_fence:
+ vk->vkDestroyFence(vk->device, fence, NULL);
+out:
+ vk->vkFreeCommandBuffers(vk->device, vk->cmd_pool, 1, &cmd_buffer);
+
+ return ret;
+}
+
+VkResult
+vk_init_cmd_pool(struct vk_bundle *vk)
+{
+ VkCommandPoolCreateInfo cmd_pool_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+ .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
+ .queueFamilyIndex = vk->queue_family_index,
+ };
+
+ VkResult ret;
+ ret = vk->vkCreateCommandPool(vk->device, &cmd_pool_info, NULL,
+ &vk->cmd_pool);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkCreateCommandPool: %s", vk_result_string(ret));
+ }
+
+ return ret;
+}
+
+
+/*
+ *
+ * Debug code.
+ *
+ */
+
+#define ENUM_TO_STR(r) \
+ case r: return #r
+
+static const char *
+vk_debug_report_string(VkDebugReportFlagBitsEXT code)
+{
+ switch (code) {
+ ENUM_TO_STR(VK_DEBUG_REPORT_INFORMATION_BIT_EXT);
+ ENUM_TO_STR(VK_DEBUG_REPORT_WARNING_BIT_EXT);
+ ENUM_TO_STR(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT);
+ ENUM_TO_STR(VK_DEBUG_REPORT_ERROR_BIT_EXT);
+ ENUM_TO_STR(VK_DEBUG_REPORT_DEBUG_BIT_EXT);
+ ENUM_TO_STR(VK_DEBUG_REPORT_FLAG_BITS_MAX_ENUM_EXT);
+ }
+ return "UNKNOWN REPORT";
+}
+
+static VkBool32 VKAPI_PTR
+_validation_cb(VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT object_type,
+ uint64_t object,
+ size_t location,
+ int32_t message_code,
+ const char *layer_prefix,
+ const char *message,
+ void *user_data)
+{
+ fprintf(stderr, "%s %s %lu:%d: %s\n", vk_debug_report_string(flags),
+ layer_prefix, location, message_code, message);
+ return VK_FALSE;
+}
+
+DEBUG_GET_ONCE_BOOL_OPTION(vulkan_spew, "XRT_COMPOSITOR_VULKAN_SPEW", false)
+
+void
+vk_init_validation_callback(struct vk_bundle *vk)
+{
+ VkDebugReportFlagsEXT flags = 0;
+ flags |= VK_DEBUG_REPORT_ERROR_BIT_EXT;
+ flags |= VK_DEBUG_REPORT_WARNING_BIT_EXT;
+
+ if (debug_get_bool_option_vulkan_spew()) {
+ flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
+ flags |= VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
+ flags |= VK_DEBUG_REPORT_DEBUG_BIT_EXT;
+ }
+
+ VkDebugReportCallbackCreateInfoEXT info = {
+ .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT,
+ .flags = flags,
+ .pfnCallback = _validation_cb,
+ };
+
+ vk->vkCreateDebugReportCallbackEXT(vk->instance, &info, NULL,
+ &vk->debug_report_cb);
+}
+
+void
+vk_destroy_validation_callback(struct vk_bundle *vk)
+{
+ if (vk->debug_report_cb != VK_NULL_HANDLE) {
+ vk->vkDestroyDebugReportCallbackEXT(vk->instance,
+ vk->debug_report_cb, NULL);
+ vk->debug_report_cb = VK_NULL_HANDLE;
+ }
+}
+
+/*
+ *
+ * Function getting code.
+ *
+ */
+
+#define GET_PROC(vk, name) (PFN_##name) vk->vkGetInstanceProcAddr(NULL, #name);
+
+#define GET_INS_PROC(vk, name) \
+ (PFN_##name) vk->vkGetInstanceProcAddr(vk->instance, #name);
+
+#define GET_DEV_PROC(vk, name) \
+ (PFN_##name) vk->vkGetDeviceProcAddr(vk->device, #name);
+
+VkResult
+vk_get_instance_functions(struct vk_bundle *vk)
+{
+ // clang-format off
+ vk->vkDestroyInstance = GET_INS_PROC(vk, vkDestroyInstance);
+ vk->vkGetDeviceProcAddr = GET_INS_PROC(vk, vkGetDeviceProcAddr);
+ vk->vkCreateDevice = GET_INS_PROC(vk, vkCreateDevice);
+ vk->vkEnumeratePhysicalDevices = GET_INS_PROC(vk, vkEnumeratePhysicalDevices);
+ vk->vkGetPhysicalDeviceProperties = GET_INS_PROC(vk, vkGetPhysicalDeviceProperties);
+ vk->vkGetPhysicalDeviceMemoryProperties = GET_INS_PROC(vk, vkGetPhysicalDeviceMemoryProperties);
+ vk->vkGetPhysicalDeviceQueueFamilyProperties = GET_INS_PROC(vk, vkGetPhysicalDeviceQueueFamilyProperties);
+ vk->vkCreateDebugReportCallbackEXT = GET_INS_PROC(vk, vkCreateDebugReportCallbackEXT);
+ vk->vkDestroyDebugReportCallbackEXT = GET_INS_PROC(vk, vkDestroyDebugReportCallbackEXT);
+ vk->vkDestroySurfaceKHR = GET_INS_PROC(vk, vkDestroySurfaceKHR);
+ vk->vkGetPhysicalDeviceSurfaceCapabilitiesKHR = GET_INS_PROC(vk, vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
+ vk->vkGetPhysicalDeviceSurfaceFormatsKHR = GET_INS_PROC(vk, vkGetPhysicalDeviceSurfaceFormatsKHR);
+ vk->vkGetPhysicalDeviceSurfacePresentModesKHR = GET_INS_PROC(vk, vkGetPhysicalDeviceSurfacePresentModesKHR);
+ vk->vkGetPhysicalDeviceSurfaceSupportKHR = GET_INS_PROC(vk, vkGetPhysicalDeviceSurfaceSupportKHR);
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ vk->vkCreateXcbSurfaceKHR = GET_INS_PROC(vk, vkCreateXcbSurfaceKHR);
+#endif
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ vk->vkCreateWaylandSurfaceKHR = GET_INS_PROC(vk, vkCreateWaylandSurfaceKHR);
+#endif
+
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ vk->vkCreateDisplayPlaneSurfaceKHR = GET_INS_PROC(vk, vkCreateDisplayPlaneSurfaceKHR);
+ vk->vkGetDisplayPlaneCapabilitiesKHR = GET_INS_PROC(vk, vkGetDisplayPlaneCapabilitiesKHR);
+ vk->vkGetPhysicalDeviceDisplayPlanePropertiesKHR = GET_INS_PROC(vk, vkGetPhysicalDeviceDisplayPlanePropertiesKHR);
+ vk->vkGetDisplayModePropertiesKHR = GET_INS_PROC(vk, vkGetDisplayModePropertiesKHR);
+ vk->vkAcquireXlibDisplayEXT = GET_INS_PROC(vk, vkAcquireXlibDisplayEXT);
+ vk->vkReleaseDisplayEXT = GET_INS_PROC(vk, vkReleaseDisplayEXT);
+ vk->vkGetRandROutputDisplayEXT = GET_INS_PROC(vk, vkGetRandROutputDisplayEXT);
+#endif
+ // clang-format on
+
+ return VK_SUCCESS;
+}
+
+static VkResult
+vk_get_device_functions(struct vk_bundle *vk)
+{
+ // clang-format off
+ vk->vkDestroyDevice = GET_DEV_PROC(vk, vkDestroyDevice);
+ vk->vkDeviceWaitIdle = GET_DEV_PROC(vk, vkDeviceWaitIdle);
+ vk->vkAllocateMemory = GET_DEV_PROC(vk, vkAllocateMemory);
+ vk->vkFreeMemory = GET_DEV_PROC(vk, vkFreeMemory);
+ vk->vkMapMemory = GET_DEV_PROC(vk, vkMapMemory);
+ vk->vkUnmapMemory = GET_DEV_PROC(vk, vkUnmapMemory);
+ vk->vkGetMemoryFdKHR = GET_DEV_PROC(vk, vkGetMemoryFdKHR);
+ vk->vkCreateBuffer = GET_DEV_PROC(vk, vkCreateBuffer);
+ vk->vkDestroyBuffer = GET_DEV_PROC(vk, vkDestroyBuffer);
+ vk->vkBindBufferMemory = GET_DEV_PROC(vk, vkBindBufferMemory);
+ vk->vkGetBufferMemoryRequirements = GET_DEV_PROC(vk, vkGetBufferMemoryRequirements);
+ vk->vkCreateImage = GET_DEV_PROC(vk, vkCreateImage);
+ vk->vkGetImageMemoryRequirements = GET_DEV_PROC(vk, vkGetImageMemoryRequirements);
+ vk->vkBindImageMemory = GET_DEV_PROC(vk, vkBindImageMemory);
+ vk->vkDestroyImage = GET_DEV_PROC(vk, vkDestroyImage);
+ vk->vkCreateImageView = GET_DEV_PROC(vk, vkCreateImageView);
+ vk->vkDestroyImageView = GET_DEV_PROC(vk, vkDestroyImageView);
+ vk->vkCreateSampler = GET_DEV_PROC(vk, vkCreateSampler);
+ vk->vkDestroySampler = GET_DEV_PROC(vk, vkDestroySampler);
+ vk->vkCreateShaderModule = GET_DEV_PROC(vk, vkCreateShaderModule);
+ vk->vkDestroyShaderModule = GET_DEV_PROC(vk, vkDestroyShaderModule);
+ vk->vkCreateCommandPool = GET_DEV_PROC(vk, vkCreateCommandPool);
+ vk->vkDestroyCommandPool = GET_DEV_PROC(vk, vkDestroyCommandPool);
+ vk->vkAllocateCommandBuffers = GET_DEV_PROC(vk, vkAllocateCommandBuffers);
+ vk->vkBeginCommandBuffer = GET_DEV_PROC(vk, vkBeginCommandBuffer);
+ vk->vkCmdPipelineBarrier = GET_DEV_PROC(vk, vkCmdPipelineBarrier);
+ vk->vkCmdBeginRenderPass = GET_DEV_PROC(vk, vkCmdBeginRenderPass);
+ vk->vkCmdSetScissor = GET_DEV_PROC(vk, vkCmdSetScissor);
+ vk->vkCmdSetViewport = GET_DEV_PROC(vk, vkCmdSetViewport);
+ vk->vkCmdClearColorImage = GET_DEV_PROC(vk, vkCmdClearColorImage);
+ vk->vkCmdEndRenderPass = GET_DEV_PROC(vk, vkCmdEndRenderPass);
+ vk->vkCmdBindDescriptorSets = GET_DEV_PROC(vk, vkCmdBindDescriptorSets);
+ vk->vkCmdBindPipeline = GET_DEV_PROC(vk, vkCmdBindPipeline);
+ vk->vkCmdDraw = GET_DEV_PROC(vk, vkCmdDraw);
+ vk->vkEndCommandBuffer = GET_DEV_PROC(vk, vkEndCommandBuffer);
+ vk->vkFreeCommandBuffers = GET_DEV_PROC(vk, vkFreeCommandBuffers);
+ vk->vkCreateRenderPass = GET_DEV_PROC(vk, vkCreateRenderPass);
+ vk->vkDestroyRenderPass = GET_DEV_PROC(vk, vkDestroyRenderPass);
+ vk->vkCreateFramebuffer = GET_DEV_PROC(vk, vkCreateFramebuffer);
+ vk->vkDestroyFramebuffer = GET_DEV_PROC(vk, vkDestroyFramebuffer);
+ vk->vkCreatePipelineCache = GET_DEV_PROC(vk, vkCreatePipelineCache);
+ vk->vkDestroyPipelineCache = GET_DEV_PROC(vk, vkDestroyPipelineCache);
+ vk->vkCreateDescriptorPool = GET_DEV_PROC(vk, vkCreateDescriptorPool);
+ vk->vkDestroyDescriptorPool = GET_DEV_PROC(vk, vkDestroyDescriptorPool);
+ vk->vkAllocateDescriptorSets = GET_DEV_PROC(vk, vkAllocateDescriptorSets);
+ vk->vkCreateGraphicsPipelines = GET_DEV_PROC(vk, vkCreateGraphicsPipelines);
+ vk->vkDestroyPipeline = GET_DEV_PROC(vk, vkDestroyPipeline);
+ vk->vkCreatePipelineLayout = GET_DEV_PROC(vk, vkCreatePipelineLayout);
+ vk->vkDestroyPipelineLayout = GET_DEV_PROC(vk, vkDestroyPipelineLayout);
+ vk->vkCreateDescriptorSetLayout = GET_DEV_PROC(vk, vkCreateDescriptorSetLayout);
+ vk->vkUpdateDescriptorSets = GET_DEV_PROC(vk, vkUpdateDescriptorSets);
+ vk->vkDestroyDescriptorSetLayout = GET_DEV_PROC(vk, vkDestroyDescriptorSetLayout);
+ vk->vkGetDeviceQueue = GET_DEV_PROC(vk, vkGetDeviceQueue);
+ vk->vkQueueSubmit = GET_DEV_PROC(vk, vkQueueSubmit);
+ vk->vkQueueWaitIdle = GET_DEV_PROC(vk, vkQueueWaitIdle);
+ vk->vkCreateSemaphore = GET_DEV_PROC(vk, vkCreateSemaphore);
+ vk->vkDestroySemaphore = GET_DEV_PROC(vk, vkDestroySemaphore);
+ vk->vkCreateFence = GET_DEV_PROC(vk, vkCreateFence);
+ vk->vkWaitForFences = GET_DEV_PROC(vk, vkWaitForFences);
+ vk->vkDestroyFence = GET_DEV_PROC(vk, vkDestroyFence);
+ vk->vkCreateSwapchainKHR = GET_DEV_PROC(vk, vkCreateSwapchainKHR);
+ vk->vkDestroySwapchainKHR = GET_DEV_PROC(vk, vkDestroySwapchainKHR);
+ vk->vkGetSwapchainImagesKHR = GET_DEV_PROC(vk, vkGetSwapchainImagesKHR);
+ vk->vkAcquireNextImageKHR = GET_DEV_PROC(vk, vkAcquireNextImageKHR);
+ vk->vkQueuePresentKHR = GET_DEV_PROC(vk, vkQueuePresentKHR);
+ // clang-format on
+
+ return VK_SUCCESS;
+}
+
+
+/*
+ *
+ * Creation code.
+ *
+ */
+
+static VkResult
+vk_select_physical_device(struct vk_bundle *vk)
+{
+ VkPhysicalDevice physical_devices[16];
+ uint32_t gpu_count = ARRAY_SIZE(physical_devices);
+ VkResult ret;
+
+ ret = vk->vkEnumeratePhysicalDevices(vk->instance, &gpu_count,
+ physical_devices);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "vkEnumeratePhysicalDevices: %s",
+ vk_result_string(ret));
+ return ret;
+ }
+
+ if (gpu_count < 1) {
+ VK_DEBUG(vk, "No physical device found!");
+ return VK_ERROR_DEVICE_LOST;
+ }
+
+ if (gpu_count > 1) {
+ VK_DEBUG(vk, "Can not deal well with multiple devices.");
+ }
+
+ // as a first-step to 'intelligent' selection, prefer a 'discrete' gpu
+ // if it is present
+ uint32_t gpu_index = 0;
+ for (uint32_t i = 0; i < gpu_count; i++) {
+ VkPhysicalDeviceProperties pdp;
+ vk->vkGetPhysicalDeviceProperties(physical_devices[i], &pdp);
+ if (pdp.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
+ gpu_index = i;
+ }
+ }
+
+ vk->physical_device = physical_devices[gpu_index];
+
+
+ // Fill out the device memory props as well.
+ vk->vkGetPhysicalDeviceMemoryProperties(vk->physical_device,
+ &vk->device_memory_props);
+
+ return VK_SUCCESS;
+}
+
+static VkResult
+vk_find_graphics_queue(struct vk_bundle *vk, uint32_t *out_graphics_queue)
+{
+ /* Find the first graphics queue */
+ uint32_t num_queues = 0;
+ vk->vkGetPhysicalDeviceQueueFamilyProperties(vk->physical_device,
+ &num_queues, NULL);
+
+ VkQueueFamilyProperties *queue_family_props =
+ (VkQueueFamilyProperties *)malloc(sizeof(VkQueueFamilyProperties) *
+ num_queues);
+
+ vk->vkGetPhysicalDeviceQueueFamilyProperties(
+ vk->physical_device, &num_queues, queue_family_props);
+
+ if (num_queues == 0) {
+ VK_DEBUG(vk, "Failed to get queue properties");
+ goto err_free;
+ }
+
+ uint32_t i = 0;
+ for (i = 0; i < num_queues; i++) {
+ if (queue_family_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
+ break;
+ }
+ }
+
+ if (i >= num_queues) {
+ VK_DEBUG(vk, "No graphics queue found");
+ goto err_free;
+ }
+
+ *out_graphics_queue = i;
+
+ free(queue_family_props);
+
+ return VK_SUCCESS;
+
+err_free:
+ free(queue_family_props);
+ return VK_ERROR_INITIALIZATION_FAILED;
+}
+
+VkResult
+vk_create_device(struct vk_bundle *vk)
+{
+ VkResult ret;
+
+ ret = vk_select_physical_device(vk);
+ if (ret != VK_SUCCESS) {
+ return ret;
+ }
+
+ VkPhysicalDeviceFeatures *enabled_features = NULL;
+
+ float queue_priority = 0.0f;
+ VkDeviceQueueCreateInfo queue_create_info = {
+ .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
+ .queueCount = 1,
+ .pQueuePriorities = &queue_priority,
+ };
+
+ ret = vk_find_graphics_queue(vk, &queue_create_info.queueFamilyIndex);
+ if (ret != VK_SUCCESS) {
+ return ret;
+ }
+
+ const char *device_extensions[] = {
+ VK_KHR_SWAPCHAIN_EXTENSION_NAME,
+ VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
+ VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
+ // VK_EXT_DEBUG_MARKER_EXTENSION_NAME,
+ };
+
+ VkDeviceCreateInfo device_create_info = {
+ .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+ .queueCreateInfoCount = 1,
+ .pQueueCreateInfos = &queue_create_info,
+ .pEnabledFeatures = enabled_features,
+ .enabledExtensionCount = ARRAY_SIZE(device_extensions),
+ .ppEnabledExtensionNames = device_extensions,
+ };
+
+ ret = vk->vkCreateDevice(vk->physical_device, &device_create_info, NULL,
+ &vk->device);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "vkCreateDevice: %s", vk_result_string(ret));
+ return ret;
+ }
+
+ ret = vk_get_device_functions(vk);
+ if (ret != VK_SUCCESS) {
+ goto err_destroy;
+ }
+
+ return ret;
+
+err_destroy:
+ vk->vkDestroyDevice(vk->device, NULL);
+ vk->device = NULL;
+
+ return ret;
+}
+
+VkResult
+vk_init_from_given(struct vk_bundle *vk,
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr,
+ VkInstance instance,
+ VkPhysicalDevice physical_device,
+ VkDevice device,
+ uint32_t queue_family_index,
+ uint32_t queue_index)
+{
+ VkResult ret;
+
+ // First memset it clear.
+ memset(vk, 0, sizeof(*vk));
+
+ vk->vkGetInstanceProcAddr = vkGetInstanceProcAddr;
+ vk->instance = instance;
+ vk->physical_device = physical_device;
+ vk->device = device;
+ vk->queue_family_index = queue_family_index;
+ vk->queue_index = queue_index;
+
+ // Not really needed but just in case.
+ vk->vkCreateInstance = GET_PROC(vk, vkCreateInstance);
+
+ // Fill in all instance functions.
+ ret = vk_get_instance_functions(vk);
+ if (ret != VK_SUCCESS) {
+ goto err_memset;
+ }
+
+ // Fill out the device memory props here, as we are
+ // passed a vulkan context and do not call selectPhysicalDevice()
+ vk->vkGetPhysicalDeviceMemoryProperties(vk->physical_device,
+ &vk->device_memory_props);
+
+ // Fill in all device functions.
+ ret = vk_get_device_functions(vk);
+ if (ret != VK_SUCCESS) {
+ goto err_memset;
+ }
+
+ // Create the pool.
+ ret = vk_init_cmd_pool(vk);
+ if (ret != VK_SUCCESS) {
+ goto err_memset;
+ }
+
+ return VK_SUCCESS;
+
+err_memset:
+ memset(vk, 0, sizeof(*vk));
+ return ret;
+}
diff --git a/src/xrt/compositor/common/comp_vk.h b/src/xrt/compositor/common/comp_vk.h
new file mode 100644
index 000000000..d917e09c0
--- /dev/null
+++ b/src/xrt/compositor/common/comp_vk.h
@@ -0,0 +1,339 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Common Vulkan code header.
+ * @author Jakob Bornecrantz
+ * @author Lubosz Sarnecki
+ * @ingroup comp_common
+ */
+
+#pragma once
+
+#include "xrt/xrt_compositor.h"
+#include "xrt/xrt_vulkan_includes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ *
+ * Structs
+ *
+ */
+
+/*!
+ * A bundle of Vulkan functions and objects, shared between @ref comp and
+ * @ref comp_client.
+ *
+ * @ingroup comp_common
+ */
+struct vk_bundle
+{
+ bool print;
+
+ VkInstance instance;
+ VkPhysicalDevice physical_device;
+ VkDevice device;
+ uint32_t queue_family_index;
+ uint32_t queue_index;
+
+ VkDebugReportCallbackEXT debug_report_cb;
+
+ VkPhysicalDeviceMemoryProperties device_memory_props;
+
+ VkCommandPool cmd_pool;
+
+ // clang-format off
+ // Loader functions
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+ PFN_vkCreateInstance vkCreateInstance;
+
+ // Instance functions.
+ PFN_vkDestroyInstance vkDestroyInstance;
+ PFN_vkCreateDevice vkCreateDevice;
+ PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
+ PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
+ PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
+ PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
+#endif
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
+#endif
+
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR;
+ PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR;
+ PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR;
+ PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR;
+ PFN_vkAcquireXlibDisplayEXT vkAcquireXlibDisplayEXT;
+ PFN_vkReleaseDisplayEXT vkReleaseDisplayEXT;
+ PFN_vkGetRandROutputDisplayEXT vkGetRandROutputDisplayEXT;
+#endif
+
+
+ // Physical device functions.
+ PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
+ PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
+
+ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
+ PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
+ PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
+ PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
+
+
+ // Device functions.
+ PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
+ PFN_vkDestroyDevice vkDestroyDevice;
+ PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
+
+ PFN_vkAllocateMemory vkAllocateMemory;
+ PFN_vkFreeMemory vkFreeMemory;
+ PFN_vkMapMemory vkMapMemory;
+ PFN_vkUnmapMemory vkUnmapMemory;
+ PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR;
+
+ PFN_vkCreateBuffer vkCreateBuffer;
+ PFN_vkDestroyBuffer vkDestroyBuffer;
+ PFN_vkBindBufferMemory vkBindBufferMemory;
+ PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
+
+ PFN_vkCreateImage vkCreateImage;
+ PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
+ PFN_vkBindImageMemory vkBindImageMemory;
+ PFN_vkDestroyImage vkDestroyImage;
+ PFN_vkCreateImageView vkCreateImageView;
+ PFN_vkDestroyImageView vkDestroyImageView;
+
+ PFN_vkCreateSampler vkCreateSampler;
+ PFN_vkDestroySampler vkDestroySampler;
+
+ PFN_vkCreateShaderModule vkCreateShaderModule;
+ PFN_vkDestroyShaderModule vkDestroyShaderModule;
+
+ PFN_vkCreateCommandPool vkCreateCommandPool;
+ PFN_vkDestroyCommandPool vkDestroyCommandPool;
+ PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
+ PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
+ PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
+ PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
+ PFN_vkCmdSetScissor vkCmdSetScissor;
+ PFN_vkCmdSetViewport vkCmdSetViewport;
+ PFN_vkCmdClearColorImage vkCmdClearColorImage;
+ PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
+ PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
+ PFN_vkCmdBindPipeline vkCmdBindPipeline;
+ PFN_vkCmdDraw vkCmdDraw;
+ PFN_vkEndCommandBuffer vkEndCommandBuffer;
+ PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
+
+ PFN_vkCreateRenderPass vkCreateRenderPass;
+ PFN_vkDestroyRenderPass vkDestroyRenderPass;
+ PFN_vkCreateFramebuffer vkCreateFramebuffer;
+ PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
+ PFN_vkCreatePipelineCache vkCreatePipelineCache;
+ PFN_vkDestroyPipelineCache vkDestroyPipelineCache;
+ PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
+ PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
+ PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
+ PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
+ PFN_vkDestroyPipeline vkDestroyPipeline;
+ PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
+ PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
+ PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
+ PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
+ PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
+
+ PFN_vkGetDeviceQueue vkGetDeviceQueue;
+ PFN_vkQueueSubmit vkQueueSubmit;
+ PFN_vkQueueWaitIdle vkQueueWaitIdle;
+
+ PFN_vkCreateSemaphore vkCreateSemaphore;
+ PFN_vkDestroySemaphore vkDestroySemaphore;
+
+ PFN_vkCreateFence vkCreateFence;
+ PFN_vkWaitForFences vkWaitForFences;
+ PFN_vkDestroyFence vkDestroyFence;
+
+ PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
+ PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
+ PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
+ PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
+ PFN_vkQueuePresentKHR vkQueuePresentKHR;
+ // clang-format on
+};
+
+
+/*
+ *
+ * String helper functions.
+ *
+ */
+
+const char *
+vk_result_string(VkResult code);
+
+const char *
+vk_color_format_string(VkFormat code);
+
+const char *
+vk_present_mode_string(VkPresentModeKHR code);
+
+const char *
+vk_power_state_string(VkDisplayPowerStateEXT code);
+
+const char *
+vk_color_space_string(VkColorSpaceKHR code);
+
+
+/*
+ *
+ * Function and helpers.
+ *
+ */
+
+#define VK_DEBUG(vk, ...) \
+ do { \
+ if (vk->print) { \
+ fprintf(stderr, "%s - ", __func__); \
+ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+ } \
+ } while (false)
+
+#define VK_ERROR(vk, ...) \
+ do { \
+ fprintf(stderr, "%s - ", __func__); \
+ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+ } while (false)
+
+/*!
+ * @ingroup comp_common
+ */
+void
+vk_init_validation_callback(struct vk_bundle *vk);
+
+/*!
+ * @ingroup comp_common
+ */
+void
+vk_destroy_validation_callback(struct vk_bundle *vk);
+
+/*!
+ * @ingroup comp_common
+ */
+VkResult
+vk_get_instance_functions(struct vk_bundle *vk);
+
+/*!
+ * @ingroup comp_common
+ */
+VkResult
+vk_init_cmd_pool(struct vk_bundle *vk);
+
+/*!
+ * @ingroup comp_common
+ */
+VkResult
+vk_create_device(struct vk_bundle *vk);
+
+/*!
+ * Initialize a bundle with objects given to us by client code,
+ * used by @ref client_vk_compositor in @ref comp_client.
+ *
+ * @ingroup comp_common
+ */
+VkResult
+vk_init_from_given(struct vk_bundle *vk,
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr,
+ VkInstance instance,
+ VkPhysicalDevice physical_device,
+ VkDevice device,
+ uint32_t queue_family_index,
+ uint32_t queue_index);
+
+/*!
+ * @ingroup comp_common
+ */
+bool
+vk_get_memory_type(struct vk_bundle *vk,
+ uint32_t type_bits,
+ VkMemoryPropertyFlags memory_props,
+ uint32_t *out_type_id);
+
+/*!
+ * @ingroup comp_common
+ */
+VkResult
+vk_create_image_from_fd(struct vk_bundle *vk,
+ int64_t format,
+ uint32_t width,
+ uint32_t height,
+ uint32_t mip_count,
+ struct xrt_image_fd *image_fd,
+ VkImage *out_image,
+ VkDeviceMemory *out_mem);
+
+/*!
+ * @ingroup comp_common
+ */
+VkResult
+vk_create_image_simple(struct vk_bundle *vk,
+ uint32_t width,
+ uint32_t height,
+ VkFormat format,
+ VkDeviceMemory *out_mem,
+ VkImage *out_image);
+
+/*!
+ * @ingroup comp_common
+ */
+VkResult
+vk_create_sampler(struct vk_bundle *vk, VkSampler *out_sampler);
+
+/*!
+ * @ingroup comp_common
+ */
+VkResult
+vk_create_view(struct vk_bundle *vk,
+ VkImage image,
+ VkFormat format,
+ VkImageView *out_view);
+
+/*!
+ * @ingroup comp_common
+ */
+VkResult
+vk_init_cmd_buffer(struct vk_bundle *vk, VkCommandBuffer *out_cmd_buffer);
+
+/*!
+ * @ingroup comp_common
+ */
+VkResult
+vk_set_image_layout(struct vk_bundle *vk,
+ VkCommandBuffer cmd_buffer,
+ VkImage image,
+ VkAccessFlags src_access_mask,
+ VkAccessFlags dst_access_mask,
+ VkImageLayout old_layout,
+ VkImageLayout new_layout,
+ VkImageSubresourceRange subresource_range);
+
+/*!
+ * @ingroup comp_common
+ */
+VkResult
+vk_submit_cmd_buffer(struct vk_bundle *vk, VkCommandBuffer cmd_buffer);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/compositor/common/comp_vk_swapchain.c b/src/xrt/compositor/common/comp_vk_swapchain.c
new file mode 100644
index 000000000..1a6c95207
--- /dev/null
+++ b/src/xrt/compositor/common/comp_vk_swapchain.c
@@ -0,0 +1,389 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Vulkan swapchain code.
+ * @author Lubosz Sarnecki
+ * @author Jakob Bornecrantz
+ * @ingroup comp_client
+ */
+
+
+#include
+#include
+#include
+#include
+
+#include "comp_vk_swapchain.h"
+
+
+/*
+ *
+ * Pre declare functions.
+ *
+ */
+
+static void
+vk_swapchain_create_image_view(struct vk_bundle *vk,
+ VkImage image,
+ VkFormat format,
+ VkImageView *view);
+
+static void
+vk_swapchain_create_image_views(struct vk_swapchain *sc);
+
+static void
+vk_swapchain_destroy_old(struct vk_swapchain *sc, VkSwapchainKHR old);
+
+static VkExtent2D
+vk_swapchain_select_extent(struct vk_swapchain *sc,
+ VkSurfaceCapabilitiesKHR caps,
+ uint32_t width,
+ uint32_t height);
+
+static bool
+_find_surface_format(struct vk_swapchain *sc,
+ VkSurfaceKHR surface,
+ VkSurfaceFormatKHR *format);
+
+static bool
+_check_surface_present_mode(struct vk_bundle *vk,
+ VkSurfaceKHR surface,
+ VkPresentModeKHR present_mode);
+
+
+/*
+ *
+ * Functions!
+ *
+ */
+
+void
+vk_swapchain_init(struct vk_swapchain *sc,
+ struct vk_bundle *vk,
+ vk_swapchain_cb dimension_cb,
+ void *priv)
+{
+ sc->vk = vk;
+ sc->cb_priv = priv;
+ sc->dimension_cb = dimension_cb;
+}
+
+void
+vk_swapchain_create(struct vk_swapchain *sc,
+ uint32_t width,
+ uint32_t height,
+ VkFormat color_format,
+ VkColorSpaceKHR color_space,
+ VkPresentModeKHR present_mode)
+{
+ VkBool32 supported;
+ VkResult ret;
+
+ sc->image_count = 0;
+ sc->swap_chain = VK_NULL_HANDLE;
+ sc->color_format = color_format;
+ sc->color_space = color_space;
+ sc->present_mode = present_mode;
+
+ // Sanity check.
+ sc->vk->vkGetPhysicalDeviceSurfaceSupportKHR(sc->vk->physical_device, 0,
+ sc->surface, &supported);
+ if (!supported) {
+ VK_ERROR(sc->vk,
+ "vkGetPhysicalDeviceSurfaceSupportKHR: "
+ "surface not supported!");
+ }
+
+
+ // More sanity checks.
+ if (!_check_surface_present_mode(sc->vk, sc->surface,
+ sc->present_mode)) {
+ return;
+ }
+
+ // Find the correct format.
+ if (!_find_surface_format(sc, sc->surface, &sc->surface_format)) {
+ return;
+ }
+
+ // Get the caps first.
+ VkSurfaceCapabilitiesKHR surface_caps;
+ ret = sc->vk->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
+ sc->vk->physical_device, sc->surface, &surface_caps);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(sc->vk,
+ "vkGetPhysicalDeviceSurfaceCapabilitiesKHR: %s",
+ vk_result_string(ret));
+ return;
+ }
+
+
+ VkSwapchainKHR old_swap_chain = sc->swap_chain;
+ VkExtent2D extent =
+ vk_swapchain_select_extent(sc, surface_caps, width, height);
+
+ VkSwapchainCreateInfoKHR swap_chain_info = {
+ .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
+ .surface = sc->surface,
+ .minImageCount = surface_caps.minImageCount,
+ .imageFormat = sc->surface_format.format,
+ .imageColorSpace = sc->surface_format.colorSpace,
+ .imageExtent =
+ {
+ .width = extent.width,
+ .height = extent.height,
+ },
+ .imageArrayLayers = 1,
+ .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+ .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
+ .queueFamilyIndexCount = 0,
+ .preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
+ .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
+ .presentMode = sc->present_mode,
+ .clipped = VK_TRUE,
+ .oldSwapchain = old_swap_chain,
+ };
+
+ ret = sc->vk->vkCreateSwapchainKHR(sc->vk->device, &swap_chain_info,
+ NULL, &sc->swap_chain);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(sc->vk, "vkCreateSwapchainKHR: %s",
+ vk_result_string(ret));
+ return;
+ }
+
+ if (old_swap_chain != VK_NULL_HANDLE) {
+ vk_swapchain_destroy_old(sc, old_swap_chain);
+ }
+
+ vk_swapchain_create_image_views(sc);
+}
+
+static VkExtent2D
+vk_swapchain_select_extent(struct vk_swapchain *sc,
+ VkSurfaceCapabilitiesKHR caps,
+ uint32_t width,
+ uint32_t height)
+{
+ VkExtent2D extent;
+ memset(&extent, 0, sizeof(extent));
+
+ // If width (and height) equals the special value 0xFFFFFFFF,
+ // the size of the surface will be set by the swapchain
+ if (caps.currentExtent.width == (uint32_t)-1) {
+ extent.width = width;
+ extent.height = height;
+ } else {
+ extent = caps.currentExtent;
+ if (caps.currentExtent.width != width ||
+ caps.currentExtent.height != height) {
+ VK_DEBUG(sc->vk,
+ "Using swap chain extent dimensions %dx%d "
+ "instead of requested %dx%d.",
+ caps.currentExtent.width,
+ caps.currentExtent.height, width, height);
+ sc->dimension_cb(caps.currentExtent.width,
+ caps.currentExtent.height,
+ sc->cb_priv);
+ }
+ }
+ return extent;
+}
+
+static void
+vk_swapchain_destroy_old(struct vk_swapchain *sc, VkSwapchainKHR old)
+{
+ for (uint32_t i = 0; i < sc->image_count; i++) {
+ sc->vk->vkDestroyImageView(sc->vk->device, sc->buffers[i].view,
+ NULL);
+ }
+
+ sc->vk->vkDestroySwapchainKHR(sc->vk->device, old, NULL);
+}
+
+VkResult
+vk_swapchain_acquire_next_image(struct vk_swapchain *sc,
+ VkSemaphore semaphore,
+ uint32_t *index)
+{
+ return sc->vk->vkAcquireNextImageKHR(sc->vk->device, sc->swap_chain,
+ UINT64_MAX, semaphore,
+ VK_NULL_HANDLE, index);
+}
+
+VkResult
+vk_swapchain_present(struct vk_swapchain *sc,
+ VkQueue queue,
+ uint32_t index,
+ VkSemaphore semaphore)
+{
+ VkPresentInfoKHR presentInfo = {
+ .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+ .waitSemaphoreCount = 1,
+ .pWaitSemaphores = &semaphore,
+ .swapchainCount = 1,
+ .pSwapchains = &sc->swap_chain,
+ .pImageIndices = &index,
+ };
+
+ return sc->vk->vkQueuePresentKHR(queue, &presentInfo);
+}
+
+static bool
+_find_surface_format(struct vk_swapchain *sc,
+ VkSurfaceKHR surface,
+ VkSurfaceFormatKHR *format)
+{
+ uint32_t num_formats;
+ VkSurfaceFormatKHR *formats = NULL;
+ sc->vk->vkGetPhysicalDeviceSurfaceFormatsKHR(
+ sc->vk->physical_device, surface, &num_formats, NULL);
+
+ if (num_formats != 0) {
+ formats = (VkSurfaceFormatKHR *)malloc(
+ sizeof(VkSurfaceFormatKHR) * num_formats);
+ sc->vk->vkGetPhysicalDeviceSurfaceFormatsKHR(
+ sc->vk->physical_device, surface, &num_formats, formats);
+ } else {
+ VK_ERROR(sc->vk, "Could not enumerate surface formats.");
+ return false;
+ }
+
+ for (uint32_t i = 0; i < num_formats; i++) {
+ if (formats[i].format == sc->color_format &&
+ formats[i].colorSpace == sc->color_space) {
+ format->format = formats[i].format;
+ format->colorSpace = formats[i].colorSpace;
+ free(formats);
+ return true;
+ }
+ }
+
+ free(formats);
+ VK_ERROR(sc->vk, "Requested format not supported.");
+ return false;
+}
+
+static bool
+_check_surface_present_mode(struct vk_bundle *vk,
+ VkSurfaceKHR surface,
+ VkPresentModeKHR present_mode)
+{
+ uint32_t num_present_modes;
+ VkPresentModeKHR *present_modes;
+ vk->vkGetPhysicalDeviceSurfacePresentModesKHR(
+ vk->physical_device, surface, &num_present_modes, NULL);
+
+ if (num_present_modes != 0) {
+ present_modes = (VkPresentModeKHR *)malloc(
+ sizeof(VkPresentModeKHR) * num_present_modes);
+ vk->vkGetPhysicalDeviceSurfacePresentModesKHR(
+ vk->physical_device, surface, &num_present_modes,
+ present_modes);
+ } else {
+ VK_ERROR(vk, "Could not enumerate present modes.");
+ return false;
+ }
+
+ for (uint32_t i = 0; i < num_present_modes; i++) {
+ if (present_modes[i] == present_mode) {
+ free(present_modes);
+ return true;
+ }
+ }
+
+ free(present_modes);
+ VK_ERROR(vk, "Requested present mode not supported.\n");
+ return false;
+}
+
+static void
+vk_swapchain_create_image_views(struct vk_swapchain *sc)
+{
+ sc->vk->vkGetSwapchainImagesKHR(sc->vk->device, sc->swap_chain,
+ &sc->image_count, NULL);
+ assert(sc->image_count > 0);
+ VK_DEBUG(sc->vk, "Creating %d image views.", sc->image_count);
+
+ VkImage *images = (VkImage *)malloc(sizeof(VkImage) * sc->image_count);
+ sc->vk->vkGetSwapchainImagesKHR(sc->vk->device, sc->swap_chain,
+ &sc->image_count, images);
+
+ if (sc->buffers != NULL) {
+ free(sc->buffers);
+ }
+
+ sc->buffers = (struct vk_swapchain_buffer *)malloc(
+ sizeof(struct vk_swapchain_buffer) * sc->image_count);
+
+ for (uint32_t i = 0; i < sc->image_count; i++) {
+ sc->buffers[i].image = images[i];
+ vk_swapchain_create_image_view(sc->vk, sc->buffers[i].image,
+ sc->surface_format.format,
+ &sc->buffers[i].view);
+ }
+
+ free(images);
+}
+
+void
+vk_swapchain_cleanup(struct vk_swapchain *sc)
+{
+ for (uint32_t i = 0; i < sc->image_count; i++) {
+ if (sc->buffers[i].view) {
+ sc->vk->vkDestroyImageView(sc->vk->device,
+ sc->buffers[i].view, NULL);
+ sc->buffers[i].view = VK_NULL_HANDLE;
+ }
+ }
+
+
+ if (sc->swap_chain != VK_NULL_HANDLE) {
+ sc->vk->vkDestroySwapchainKHR(sc->vk->device, sc->swap_chain,
+ NULL);
+ sc->swap_chain = VK_NULL_HANDLE;
+ }
+
+ if (sc->surface != VK_NULL_HANDLE) {
+ sc->vk->vkDestroySurfaceKHR(sc->vk->instance, sc->surface,
+ NULL);
+ sc->swap_chain = VK_NULL_HANDLE;
+ }
+}
+
+static void
+vk_swapchain_create_image_view(struct vk_bundle *vk,
+ VkImage image,
+ VkFormat format,
+ VkImageView *view)
+{
+ VkResult ret;
+
+ VkImageViewCreateInfo view_create_info = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+ .image = image,
+ .viewType = VK_IMAGE_VIEW_TYPE_2D,
+ .format = format,
+ .components =
+ {
+ .r = VK_COMPONENT_SWIZZLE_R,
+ .g = VK_COMPONENT_SWIZZLE_G,
+ .b = VK_COMPONENT_SWIZZLE_B,
+ .a = VK_COMPONENT_SWIZZLE_A,
+ },
+ .subresourceRange =
+ {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .baseMipLevel = 0,
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ .layerCount = 1,
+ },
+ };
+
+ ret = vk->vkCreateImageView(vk->device, &view_create_info, NULL, view);
+ if (ret != VK_SUCCESS) {
+ VK_ERROR(vk, "vkCreateImageView: %s", vk_result_string(ret));
+ }
+}
diff --git a/src/xrt/compositor/common/comp_vk_swapchain.h b/src/xrt/compositor/common/comp_vk_swapchain.h
new file mode 100644
index 000000000..5e9d86b9f
--- /dev/null
+++ b/src/xrt/compositor/common/comp_vk_swapchain.h
@@ -0,0 +1,133 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Vulkan swapchain code header.
+ * @author Lubosz Sarnecki
+ * @author Jakob Bornecrantz
+ * @ingroup comp_client
+ */
+
+#pragma once
+
+#include "common/comp_vk.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ *
+ * Structs.
+ *
+ */
+
+/*!
+ * Callback when a @ref vk_swapchain changes size.
+ *
+ * @ingroup comp_common
+ */
+typedef void (*vk_swapchain_cb)(uint32_t width, uint32_t height, void *priv);
+
+/*!
+ * A pair of VkImage and VkImageView.
+ *
+ * @ingroup comp_common
+ */
+struct vk_swapchain_buffer
+{
+ VkImage image;
+ VkImageView view;
+};
+
+/*!
+ * Wraps and manage VkSwapchainKHR and VkSurfaceKHR, used by @ref comp code.
+ *
+ * @ingroup comp_common
+ */
+struct vk_swapchain
+{
+ struct vk_bundle *vk;
+
+ VkSwapchainKHR swap_chain;
+
+ VkSurfaceKHR surface;
+ VkSurfaceFormatKHR surface_format;
+
+ struct vk_swapchain_buffer *buffers;
+ uint32_t image_count;
+
+ VkFormat color_format;
+ VkColorSpaceKHR color_space;
+ VkPresentModeKHR present_mode;
+
+ void *cb_priv;
+ vk_swapchain_cb dimension_cb;
+};
+
+
+/*
+ *
+ * Functions.
+ *
+ */
+
+/*!
+ * Wraps and manage VkSwapchainKHR and VkSurfaceKHR, used by @ref comp code.
+ *
+ * @ingroup comp_common
+ */
+void
+vk_swapchain_init(struct vk_swapchain *sc,
+ struct vk_bundle *vk,
+ vk_swapchain_cb dimension_cb,
+ void *priv);
+
+/*!
+ * Initialize the given @ref vk_swapchain, does not allocate.
+ *
+ * @ingroup comp_common
+ */
+void
+vk_swapchain_create(struct vk_swapchain *sc,
+ uint32_t width,
+ uint32_t height,
+ VkFormat color_format,
+ VkColorSpaceKHR color_space,
+ VkPresentModeKHR present_mode);
+
+/*!
+ * Acquire a image index from the given @ref vk_swapchain for rendering.
+ *
+ * @ingroup comp_common
+ */
+VkResult
+vk_swapchain_acquire_next_image(struct vk_swapchain *sc,
+ VkSemaphore semaphore,
+ uint32_t *index);
+
+/*!
+ * Make the given @ref vk_swapchain present the next acquired image.
+ *
+ * @ingroup comp_common
+ */
+VkResult
+vk_swapchain_present(struct vk_swapchain *sc,
+ VkQueue queue,
+ uint32_t index,
+ VkSemaphore semaphore);
+
+/*!
+ * Free all managed resources on the given @ref vk_swapchain,
+ * does not free the struct itself.
+ *
+ * @ingroup comp_common
+ */
+void
+vk_swapchain_cleanup(struct vk_swapchain *sc);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/compositor/main/comp_client_interface.h b/src/xrt/compositor/main/comp_client_interface.h
new file mode 100644
index 000000000..d22f46914
--- /dev/null
+++ b/src/xrt/compositor/main/comp_client_interface.h
@@ -0,0 +1,30 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Interface for client code to compositor.
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#pragma once
+
+#include "xrt/xrt_device.h"
+#include "xrt/xrt_compositor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*!
+ * Create the compositor instance using the given device. Used by the client
+ * code and implemented by the main compositor code.
+ */
+struct xrt_compositor_fd*
+comp_compositor_create(struct xrt_device* xdev, bool flip_y);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/compositor/main/comp_compositor.c b/src/xrt/compositor/main/comp_compositor.c
new file mode 100644
index 000000000..d1a04399a
--- /dev/null
+++ b/src/xrt/compositor/main/comp_compositor.c
@@ -0,0 +1,505 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Main compositor written using Vulkan implementation.
+ * @author Jakob Bornecrantz
+ * @author Lubosz Sarnecki
+ * @ingroup comp
+ */
+
+#include
+#include
+#include
+
+#include "util/u_debug.h"
+
+#include "main/comp_compositor.h"
+#include "main/comp_client_interface.h"
+
+
+static void
+compositor_destroy(struct xrt_compositor *xc)
+{
+ struct comp_compositor *c = comp_compositor(xc);
+ struct vk_bundle *vk = &c->vk;
+
+ COMP_DEBUG(c, "DESTROY");
+
+ if (c->r) {
+ comp_renderer_destroy(c->r);
+ c->r = NULL;
+ }
+
+ vk_swapchain_cleanup(&c->window->swapchain);
+
+ if (c->window != NULL) {
+ c->window->destroy(c->window);
+ c->window = NULL;
+ }
+
+ if (vk->cmd_pool != VK_NULL_HANDLE) {
+ vk->vkDestroyCommandPool(vk->device, vk->cmd_pool, NULL);
+ vk->cmd_pool = VK_NULL_HANDLE;
+ }
+
+ if (vk->device != VK_NULL_HANDLE) {
+ vk->vkDestroyDevice(vk->device, NULL);
+ vk->device = VK_NULL_HANDLE;
+ }
+
+ vk_destroy_validation_callback(vk);
+
+ if (vk->instance != VK_NULL_HANDLE) {
+ vk->vkDestroyInstance(vk->instance, NULL);
+ vk->instance = VK_NULL_HANDLE;
+ }
+
+ free(c);
+}
+
+static void
+compositor_begin_session(struct xrt_compositor *xc, enum xrt_view_type type)
+{
+ struct comp_compositor *c = comp_compositor(xc);
+ COMP_DEBUG(c, "BEGIN_SESSION");
+}
+
+static void
+compositor_end_session(struct xrt_compositor *xc)
+{
+ struct comp_compositor *c = comp_compositor(xc);
+ COMP_DEBUG(c, "END_SESSION");
+}
+
+static void
+compositor_wait_frame(struct xrt_compositor *xc,
+ int64_t *predicted_display_time,
+ int64_t *predicted_display_period)
+{
+ struct comp_compositor *c = comp_compositor(xc);
+ COMP_SPEW(c, "WAIT_FRAME");
+
+ //! @todo set *predicted_display_time
+
+ // *predicted_display_time = 0;
+ // *predicted_display_period = 0;
+}
+
+static void
+compositor_begin_frame(struct xrt_compositor *xc)
+{
+ struct comp_compositor *c = comp_compositor(xc);
+ COMP_SPEW(c, "BEGIN_FRAME");
+}
+
+static void
+compositor_discard_frame(struct xrt_compositor *xc)
+{
+ struct comp_compositor *c = comp_compositor(xc);
+ COMP_SPEW(c, "DISCARD_FRAME");
+}
+
+static void
+compositor_end_frame(struct xrt_compositor *xc,
+ enum xrt_blend_mode blend_mode,
+ struct xrt_swapchain **xscs,
+ uint32_t *acquired_index,
+ uint32_t num_swapchains)
+{
+ struct comp_compositor *c = comp_compositor(xc);
+ COMP_SPEW(c, "END_FRAME");
+
+ struct comp_swapchain_image *right;
+ struct comp_swapchain_image *left;
+
+ // Stereo!
+ if (num_swapchains == 2) {
+ left = &comp_swapchain(xscs[0])->images[acquired_index[0]];
+ right = &comp_swapchain(xscs[1])->images[acquired_index[1]];
+ comp_renderer_frame(c->r, left, right);
+ } else {
+ COMP_ERROR(c, "non-stereo rendering not supported");
+ }
+}
+
+
+/*
+ *
+ * Vulkan functions.
+ *
+ */
+
+#define GET_PROC(name) (PFN_##name) c->vk.vkGetInstanceProcAddr(NULL, #name);
+#define GET_DEV_PROC(c, name) \
+ (PFN_##name) c->vk.vkGetDeviceProcAddr(c->vk.device, #name);
+#define GET_INS_PROC(c, name) \
+ (PFN_##name) c->vk.vkGetInstanceProcAddr(c->vk.instance, #name);
+#define GET_DEV_PROC(c, name) \
+ (PFN_##name) c->vk.vkGetDeviceProcAddr(c->vk.device, #name);
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
+vkGetInstanceProcAddr(VkInstance instance, const char *pName);
+
+static VkResult
+find_get_instance_proc_addr(struct comp_compositor *c)
+{
+ //! @todo Do any library loading here.
+ c->vk.vkGetInstanceProcAddr = vkGetInstanceProcAddr;
+
+ // Fill in all loader functions.
+ // clang-format off
+ c->vk.vkCreateInstance = GET_PROC(vkCreateInstance);
+ // clang-format on
+
+ return VK_SUCCESS;
+}
+
+#ifdef XRT_ENABLE_VK_VALIDATION
+#define COMPOSITOR_DEBUG_VULKAN_EXTENSIONS VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
+#else
+#define COMPOSITOR_DEBUG_VULKAN_EXTENSIONS
+#endif
+
+#define COMPOSITOR_COMMON_VULKAN_EXTENSIONS \
+ COMPOSITOR_DEBUG_VULKAN_EXTENSIONS \
+ VK_KHR_SURFACE_EXTENSION_NAME, \
+ VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \
+ VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, \
+ VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, \
+ VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME
+
+static const char *instance_extensions_none[] = {
+ COMPOSITOR_COMMON_VULKAN_EXTENSIONS};
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+static const char *instance_extensions_xcb[] = {
+ COMPOSITOR_COMMON_VULKAN_EXTENSIONS,
+ VK_KHR_XCB_SURFACE_EXTENSION_NAME,
+};
+#endif
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+static const char *instance_extensions_wayland[] = {
+ COMPOSITOR_COMMON_VULKAN_EXTENSIONS,
+ VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
+};
+#endif
+
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+static const char *instance_extensions_direct_mode[] = {
+ COMPOSITOR_COMMON_VULKAN_EXTENSIONS,
+ VK_KHR_DISPLAY_EXTENSION_NAME,
+ VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME,
+ VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME,
+};
+#endif
+
+static VkResult
+select_instances_extensions(struct comp_compositor *c,
+ const char ***out_exts,
+ uint32_t *out_num)
+{
+ switch (c->settings.window_type) {
+ case WINDOW_NONE:
+ *out_exts = instance_extensions_none;
+ *out_num = ARRAY_SIZE(instance_extensions_none);
+ break;
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ case WINDOW_XCB:
+ *out_exts = instance_extensions_xcb;
+ *out_num = ARRAY_SIZE(instance_extensions_xcb);
+ break;
+#endif
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ case WINDOW_WAYLAND:
+ *out_exts = instance_extensions_wayland;
+ *out_num = ARRAY_SIZE(instance_extensions_wayland);
+ break;
+#endif
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ case WINDOW_DIRECT_MODE:
+ *out_exts = instance_extensions_direct_mode;
+ *out_num = ARRAY_SIZE(instance_extensions_direct_mode);
+ break;
+#endif
+ default: return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ return VK_SUCCESS;
+}
+
+static VkResult
+create_instance(struct comp_compositor *c)
+{
+ const char **instance_extensions;
+ uint32_t num_extensions;
+ VkResult ret;
+
+ VkApplicationInfo app_info = {
+ .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
+ .pApplicationName = "Collabora Compositor",
+ .pEngineName = "Monado",
+ .apiVersion = VK_MAKE_VERSION(1, 0, 2),
+ };
+
+ ret = select_instances_extensions(c, &instance_extensions,
+ &num_extensions);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(c, "Failed to select instance extensions: %s",
+ vk_result_string(ret));
+ return ret;
+ }
+
+#ifdef XRT_ENABLE_VK_VALIDATION
+ const char *instance_layers[] = {
+ "VK_LAYER_LUNARG_standard_validation",
+ };
+#endif
+
+ VkInstanceCreateInfo instance_info = {
+ .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+ .pApplicationInfo = &app_info,
+ .enabledExtensionCount = num_extensions,
+ .ppEnabledExtensionNames = instance_extensions,
+#ifdef XRT_ENABLE_VK_VALIDATION
+ .enabledLayerCount = ARRAY_SIZE(instance_layers),
+ .ppEnabledLayerNames = instance_layers,
+#endif
+ };
+
+ ret = c->vk.vkCreateInstance(&instance_info, NULL, &c->vk.instance);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(c, "vkCreateInstance: %s\n", vk_result_string(ret));
+ COMP_ERROR(c, "Failed to create Vulkan instance");
+ return ret;
+ }
+
+ ret = vk_get_instance_functions(&c->vk);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(c, "Failed to get Vulkan instance functions: %s",
+ vk_result_string(ret));
+ return ret;
+ }
+
+#ifdef XRT_ENABLE_VK_VALIDATION
+ vk_init_validation_callback(&c->vk);
+#endif
+
+ return ret;
+}
+
+static bool
+compositor_init_vulkan(struct comp_compositor *c)
+{
+ VkResult ret;
+
+ ret = find_get_instance_proc_addr(c);
+ if (ret != VK_SUCCESS) {
+ return false;
+ }
+
+ ret = create_instance(c);
+ if (ret != VK_SUCCESS) {
+ return false;
+ }
+
+ ret = vk_create_device(&c->vk);
+ if (ret != VK_SUCCESS) {
+ return false;
+ }
+
+ ret = vk_init_cmd_pool(&c->vk);
+ if (ret != VK_SUCCESS) {
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ *
+ * Other functions.
+ *
+ */
+
+void
+comp_compositor_print(struct comp_compositor *c,
+ const char *func,
+ const char *fmt,
+ ...)
+{
+ fprintf(stderr, "%s - ", func);
+
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+
+ fprintf(stderr, "\n");
+}
+
+static bool
+compositor_try_window(struct comp_compositor *c, struct comp_window *window)
+{
+ if (window == NULL) {
+ return false;
+ }
+
+ if (!window->init(window)) {
+ window->destroy(window);
+ return false;
+ } else {
+ COMP_DEBUG(c, "Window backend %s initialized!", window->name);
+ c->window = window;
+ return true;
+ }
+}
+
+static bool
+compositor_init_window(struct comp_compositor *c)
+{
+ // Setup the initial width from the settings.
+ c->current.width = c->settings.width;
+ c->current.height = c->settings.height;
+
+ switch (c->settings.window_type) {
+ case WINDOW_AUTO:
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ if (compositor_try_window(c, comp_window_direct_create(c))) {
+ c->settings.window_type = WINDOW_DIRECT_MODE;
+ return true;
+ }
+#endif
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ if (compositor_try_window(c, comp_window_xcb_create(c))) {
+ c->settings.window_type = WINDOW_XCB;
+ return true;
+ }
+#endif
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ if (compositor_try_window(c, comp_window_wayland_create(c))) {
+ c->settings.window_type = WINDOW_WAYLAND;
+ return true;
+ }
+#endif
+ COMP_ERROR(c, "Failed to auto detect window support!");
+ break;
+ case WINDOW_XCB:
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ compositor_try_window(c, comp_window_xcb_create(c));
+#else
+ COMP_ERROR(c, "XCB support not compiled in!");
+#endif
+ break;
+ case WINDOW_WAYLAND:
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ compositor_try_window(c, comp_window_wayland_create(c));
+#else
+ COMP_ERROR(c, "Wayland support not compiled in!");
+#endif
+ break;
+ case WINDOW_DIRECT_MODE:
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ compositor_try_window(c, comp_window_direct_create(c));
+#else
+ COMP_ERROR(c, "Direct mode support not compiled in!");
+#endif
+ break;
+ default: COMP_ERROR(c, "Unknown window type!"); break;
+ }
+
+ // Failed to create?
+ if (c->window == NULL) {
+ return false;
+ }
+
+ return true;
+}
+
+
+static void
+_sc_dimension_cb(uint32_t width, uint32_t height, void *ptr)
+{
+ struct comp_compositor *c = (struct comp_compositor *)ptr;
+
+ COMP_DEBUG(c, "_sc_dimension_cb %dx%d", width, height);
+
+ c->current.width = width;
+ c->current.height = height;
+}
+
+static bool
+compositor_init_swapchain(struct comp_compositor *c)
+{
+ //! @todo Make c->window->init_swachain call vk_swapchain_init and give
+ //! _sc_dimension_cb to window or just have it call a function?
+ vk_swapchain_init(&c->window->swapchain, &c->vk, _sc_dimension_cb,
+ (void *)c);
+ if (!c->window->init_swapchain(c->window, c->current.width,
+ c->current.height)) {
+ COMP_ERROR(c, "Window init_swapchain failed!");
+ goto err_destroy;
+ }
+
+ return true;
+
+ // Error path.
+err_destroy:
+ c->window->destroy(c->window);
+ c->window = NULL;
+
+ return false;
+}
+
+static bool
+compositor_init_renderer(struct comp_compositor *c)
+{
+ c->r = comp_renderer_create(c);
+ if (c->r == NULL) {
+ return false;
+ }
+
+ return true;
+}
+
+struct xrt_compositor_fd *
+comp_compositor_create(struct xrt_device *xdev, bool flip_y)
+{
+ struct comp_compositor *c = calloc(1, sizeof(struct comp_compositor));
+
+ c->base.base.create_swapchain = comp_swapchain_create;
+ c->base.base.begin_session = compositor_begin_session;
+ c->base.base.end_session = compositor_end_session;
+ c->base.base.wait_frame = compositor_wait_frame;
+ c->base.base.begin_frame = compositor_begin_frame;
+ c->base.base.discard_frame = compositor_discard_frame;
+ c->base.base.end_frame = compositor_end_frame;
+ c->base.base.destroy = compositor_destroy;
+ c->xdev = xdev;
+
+ COMP_DEBUG(c, "Doing init %p", (void *)c);
+
+ // Init the settings to default.
+ comp_settings_init(&c->settings, xdev);
+
+ c->settings.flip_y = flip_y;
+
+ // Need to select window backend before creating Vulkan, then
+ // swapchain will initialize the window fully and the swapchain, and
+ // finally the renderer is created which renderers to window/swapchain.
+ // clang-format off
+ if (!compositor_init_window(c) ||
+ !compositor_init_vulkan(c) ||
+ !compositor_init_swapchain(c) ||
+ !compositor_init_renderer(c)) {
+ COMP_DEBUG(c, "Failed to init compositor %p", (void *)c);
+ c->base.base.destroy(&c->base.base);
+ return NULL;
+ }
+ // clang-format on
+
+ COMP_DEBUG(c, "Done %p", (void *)c);
+
+ return &c->base;
+}
diff --git a/src/xrt/compositor/main/comp_compositor.h b/src/xrt/compositor/main/comp_compositor.h
new file mode 100644
index 000000000..c3ba6fb22
--- /dev/null
+++ b/src/xrt/compositor/main/comp_compositor.h
@@ -0,0 +1,234 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Main compositor written using Vulkan header.
+ * @author Jakob Bornecrantz
+ * @author Lubosz Sarnecki
+ * @ingroup comp
+ */
+
+#pragma once
+
+#include "main/comp_settings.h"
+#include "main/comp_window.h"
+#include "main/comp_renderer.h"
+
+#include "xrt/xrt_gfx_vk.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ *
+ * Documentation
+ *
+ */
+
+/*!
+ * @defgroup comp Compositor
+ * Main compositing code.
+ *
+ * @ingroup xrt
+ */
+
+/*!
+ * Glue code between client program to the main compositor.
+ *
+ * @defgroup comp_client Compositor client glue code
+ * @ingroup comp
+ */
+
+/*!
+ * Common compositor code shared between main and client code.
+ *
+ * @defgroup comp_common Common compositor code
+ * @ingroup comp
+ */
+
+
+/*
+ *
+ * Structs
+ *
+ */
+
+/*!
+ * A single swapchain image, holds the needed state for tracking image usage.
+ *
+ * @ingroup comp
+ */
+struct comp_swapchain_image
+{
+ //! Vulkan image to create view from.
+ VkImage image;
+ //! Exported memory backing the image.
+ VkDeviceMemory memory;
+ //! Sampler used by the renderer and distortion code.
+ VkSampler sampler;
+ //! View used by the renderer and distortion code.
+ VkImageView view;
+};
+
+/*!
+ * A swapchain that is almost a one to one mapping to a OpenXR swapchain.
+ *
+ * Not used by the window backend that uses the vk_swapchain to render to.
+ *
+ * @ingroup comp
+ */
+struct comp_swapchain
+{
+ struct xrt_swapchain_fd base;
+
+ struct comp_compositor *c;
+
+ struct comp_swapchain_image images[XRT_MAX_SWAPCHAIN_IMAGES];
+};
+
+/*!
+ * Main compositor struct tying everything in the compositor together.
+ *
+ * @ingroup comp
+ */
+struct comp_compositor
+{
+ struct xrt_compositor_fd base;
+
+ //! A link back to the compositor we are presenting to the client.
+ struct xrt_compositor *client;
+
+ //! Renderer helper.
+ struct comp_renderer *r;
+
+ //! The window or display we are using.
+ struct comp_window *window;
+
+ //! The device we are displaying to.
+ struct xrt_device *xdev;
+
+ //! The settings.
+ struct comp_settings settings;
+
+ // Vulkan bundle of things.
+ struct vk_bundle vk;
+
+ /*!
+ * The current state we are tracking.
+ *
+ * Settings is supposed to be read only.
+ */
+ struct
+ {
+ uint32_t width;
+ uint32_t height;
+ } current;
+};
+
+
+/*
+ *
+ * Functions and helpers.
+ *
+ */
+
+/*!
+ * Convinence function to convert a xrt_swapchain to a comp_swapchain.
+ *
+ * @ingroup comp
+ */
+XRT_MAYBE_UNUSED static struct comp_swapchain *
+comp_swapchain(struct xrt_swapchain *xsc)
+{
+ return (struct comp_swapchain *)xsc;
+}
+
+/*!
+ * Convinence function to convert a xrt_compositor to a comp_compositor.
+ *
+ * @ingroup comp
+ */
+XRT_MAYBE_UNUSED static struct comp_compositor *
+comp_compositor(struct xrt_compositor *xc)
+{
+ return (struct comp_compositor *)xc;
+}
+
+/*!
+ * A compositor function that is implemented in the swapchain code.
+ *
+ * @ingroup comp
+ */
+struct xrt_swapchain *
+comp_swapchain_create(struct xrt_compositor *xc,
+ enum xrt_swapchain_create_flags create,
+ enum xrt_swapchain_usage_bits bits,
+ int64_t format,
+ uint32_t sample_count,
+ uint32_t width,
+ uint32_t height,
+ uint32_t face_count,
+ uint32_t array_size,
+ uint32_t mip_count);
+
+/*!
+ * Free and destroy any initialized fields on the given image, safe to pass in
+ * images that has one or all fields set to NULL.
+ *
+ * @ingroup comp
+ */
+void
+comp_swapchain_image_cleanup(struct vk_bundle *vk,
+ struct comp_swapchain_image *image);
+
+/*!
+ * Printer helper.
+ *
+ * @ingroup comp
+ */
+void
+comp_compositor_print(struct comp_compositor *c,
+ const char *func,
+ const char *fmt,
+ ...) XRT_PRINTF_FORMAT(3, 4);
+
+/*!
+ * Spew level logging.
+ *
+ * @ingroup comp
+ */
+#define COMP_SPEW(c, ...) \
+ do { \
+ if (c->settings.print_spew) { \
+ comp_compositor_print(c, __func__, __VA_ARGS__); \
+ } \
+ } while (false)
+
+/*!
+ * Debug level logging.
+ *
+ * @ingroup comp
+ */
+#define COMP_DEBUG(c, ...) \
+ do { \
+ if (c->settings.print_debug) { \
+ comp_compositor_print(c, __func__, __VA_ARGS__); \
+ } \
+ } while (false)
+
+/*!
+ * Error level logging.
+ *
+ * @ingroup comp
+ */
+#define COMP_ERROR(c, ...) \
+ do { \
+ comp_compositor_print(c, __func__, __VA_ARGS__); \
+ } while (false)
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/compositor/main/comp_distortion.c b/src/xrt/compositor/main/comp_distortion.c
new file mode 100644
index 000000000..f3d55c6c8
--- /dev/null
+++ b/src/xrt/compositor/main/comp_distortion.c
@@ -0,0 +1,719 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Distortion shader code.
+ * @author Lubosz Sarnecki
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#include
+#include
+
+#include "main/comp_settings.h"
+#include "main/comp_compositor.h"
+
+#include "comp_distortion.h"
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas"
+#pragma GCC diagnostic ignored "-Wnewline-eof"
+
+#include "shaders/distortion.vert.h"
+#include "shaders/none.frag.h"
+#include "shaders/panotools.frag.h"
+#include "shaders/vive.frag.h"
+
+#pragma GCC diagnostic pop
+
+/*
+ *
+ * Pre declare functions.
+ *
+ */
+
+static void
+comp_distortion_update_uniform_buffer_warp(struct comp_distortion *d,
+ struct comp_compositor *c);
+
+static void
+comp_distortion_init_uniform_buffer(struct comp_distortion *d,
+ struct comp_compositor *c);
+
+XRT_MAYBE_UNUSED static void
+comp_distortion_update_descriptor_sets(struct comp_distortion *d,
+ VkSampler samplers[2],
+ VkImageView views[2]);
+
+static void
+comp_distortion_init_descriptor_set_layout(struct comp_distortion *d);
+
+static void
+comp_distortion_init_pipeline_layout(struct comp_distortion *d);
+
+static void
+comp_distortion_init_pipeline(struct comp_distortion *d,
+ VkRenderPass render_pass,
+ VkPipelineCache pipeline_cache,
+ enum xrt_distortion_model distortion_model);
+
+static VkWriteDescriptorSet
+comp_distortion_get_uniform_write_descriptor_set(struct comp_distortion *d,
+ uint32_t binding,
+ uint32_t eye);
+
+static VkWriteDescriptorSet
+comp_distortion_get_uniform_write_descriptor_set_vp(struct comp_distortion *d,
+ uint32_t binding,
+ uint32_t eye);
+
+static VkWriteDescriptorSet
+comp_distortion_get_image_write_descriptor_set(
+ VkDescriptorSet descriptorSet,
+ VkDescriptorImageInfo *texDescriptorPosition,
+ uint32_t binding);
+
+static void
+comp_distortion_init_descriptor_sets(struct comp_distortion *d,
+ VkDescriptorPool descriptorPool);
+
+
+/*
+ *
+ * Buffer functions.
+ *
+ */
+
+static void
+_buffer_destroy(struct vk_bundle *vk, struct comp_uniform_buffer *buffer)
+{
+ vk->vkDestroyBuffer(buffer->device, buffer->buffer, NULL);
+ vk->vkFreeMemory(buffer->device, buffer->memory, NULL);
+}
+
+static VkResult
+_buffer_map(struct vk_bundle *vk,
+ struct comp_uniform_buffer *buffer,
+ VkDeviceSize size,
+ VkDeviceSize offset)
+{
+ return vk->vkMapMemory(vk->device, buffer->memory, offset, size, 0,
+ &buffer->mapped);
+}
+
+static void
+_buffer_unmap(struct vk_bundle *vk, struct comp_uniform_buffer *buffer)
+{
+ if (buffer->mapped) {
+ vk->vkUnmapMemory(vk->device, buffer->memory);
+ buffer->mapped = NULL;
+ }
+}
+
+static void
+_buffer_setup_descriptor(struct vk_bundle *vk,
+ struct comp_uniform_buffer *buffer,
+ VkDeviceSize size,
+ VkDeviceSize offset)
+{
+ buffer->descriptor.offset = offset;
+ buffer->descriptor.buffer = buffer->buffer;
+ buffer->descriptor.range = size;
+}
+
+
+/*
+ *
+ * Shader functions.
+ *
+ */
+
+static VkPipelineShaderStageCreateInfo
+_shader_load(struct vk_bundle *vk,
+ const uint32_t *code,
+ size_t size,
+ VkShaderStageFlagBits flags)
+{
+ VkResult ret;
+
+ VkShaderModuleCreateInfo info = {
+ .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
+ .codeSize = size,
+ .pCode = code,
+ };
+
+ VkShaderModule module;
+ ret = vk->vkCreateShaderModule(vk->device, &info, NULL, &module);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "vkCreateShaderModule failed %u", ret);
+ }
+
+ return (VkPipelineShaderStageCreateInfo){
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+ .stage = flags,
+ .module = module,
+ .pName = "main",
+ };
+}
+
+
+/*
+ *
+ * Functions.
+ *
+ */
+
+void
+comp_distortion_init(struct comp_distortion *d,
+ struct comp_compositor *c,
+ VkRenderPass render_pass,
+ VkPipelineCache pipeline_cache,
+ enum xrt_distortion_model distortion_model,
+ VkDescriptorPool descriptor_pool,
+ bool flip_y)
+{
+ d->vk = &c->vk;
+
+ d->ubo_vp_data[0].flip_y = flip_y;
+ d->ubo_vp_data[1].flip_y = flip_y;
+
+ comp_distortion_init_uniform_buffer(d, c);
+ comp_distortion_update_uniform_buffer_warp(d, c);
+ comp_distortion_init_descriptor_set_layout(d);
+ comp_distortion_init_pipeline_layout(d);
+ comp_distortion_init_pipeline(d, render_pass, pipeline_cache,
+ distortion_model);
+ comp_distortion_init_descriptor_sets(d, descriptor_pool);
+}
+
+void
+comp_distortion_destroy(struct comp_distortion *d)
+{
+ struct vk_bundle *vk = d->vk;
+
+
+ vk->vkDestroyDescriptorSetLayout(vk->device, d->descriptor_set_layout,
+ NULL);
+
+ _buffer_destroy(vk, &d->ubo_handle);
+ _buffer_destroy(vk, &d->ubo_viewport_handles[0]);
+ _buffer_destroy(vk, &d->ubo_viewport_handles[1]);
+
+ vk->vkDestroyPipeline(vk->device, d->pipeline, NULL);
+ vk->vkDestroyPipelineLayout(vk->device, d->pipeline_layout, NULL);
+}
+
+static void
+comp_distortion_init_pipeline(struct comp_distortion *d,
+ VkRenderPass render_pass,
+ VkPipelineCache pipeline_cache,
+ enum xrt_distortion_model distortion_model)
+{
+ struct vk_bundle *vk = d->vk;
+ VkResult ret;
+
+ VkPipelineInputAssemblyStateCreateInfo input_assembly_state = {
+ .sType =
+ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+ .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
+ .primitiveRestartEnable = VK_FALSE,
+ };
+
+ VkPipelineRasterizationStateCreateInfo rasterization_state = {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
+ .depthClampEnable = VK_FALSE,
+ .polygonMode = VK_POLYGON_MODE_FILL,
+ .cullMode = VK_CULL_MODE_BACK_BIT,
+ .frontFace = VK_FRONT_FACE_CLOCKWISE,
+ .lineWidth = 1.0f,
+ };
+
+ VkPipelineColorBlendAttachmentState blend_attachment_state = {
+ .blendEnable = VK_FALSE,
+ .colorWriteMask = 0xf,
+ };
+
+ VkPipelineColorBlendStateCreateInfo color_blend_state = {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
+ .attachmentCount = 1,
+ .pAttachments = &blend_attachment_state,
+ };
+
+ VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
+ .depthTestEnable = VK_TRUE,
+ .depthWriteEnable = VK_TRUE,
+ .depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL,
+ .front =
+ {
+ .compareOp = VK_COMPARE_OP_ALWAYS,
+ },
+ .back =
+ {
+ .compareOp = VK_COMPARE_OP_ALWAYS,
+ },
+ };
+
+ VkPipelineViewportStateCreateInfo viewport_state = {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+ .viewportCount = 1,
+ .scissorCount = 1,
+ };
+
+ VkPipelineMultisampleStateCreateInfo multisample_state = {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
+ .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT};
+
+ VkDynamicState dynamic_states[] = {
+ VK_DYNAMIC_STATE_VIEWPORT,
+ VK_DYNAMIC_STATE_SCISSOR,
+ };
+
+ VkPipelineDynamicStateCreateInfo dynamic_state = {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+ .dynamicStateCount = 2,
+ .pDynamicStates = dynamic_states,
+ };
+
+
+
+ const uint32_t *fragment_shader_code;
+ size_t fragment_shader_size;
+
+ switch (distortion_model) {
+ case XRT_DISTORTION_MODEL_NONE:
+ fragment_shader_code = shaders_none_frag;
+ fragment_shader_size = sizeof(shaders_none_frag);
+ break;
+ case XRT_DISTORTION_MODEL_PANOTOOLS:
+ fragment_shader_code = shaders_panotools_frag;
+ fragment_shader_size = sizeof(shaders_panotools_frag);
+ break;
+ case XRT_DISTORTION_MODEL_VIVE:
+ fragment_shader_code = shaders_vive_frag;
+ fragment_shader_size = sizeof(shaders_vive_frag);
+ break;
+ default:
+ fragment_shader_code = shaders_panotools_frag;
+ fragment_shader_size = sizeof(shaders_panotools_frag);
+ break;
+ }
+
+ VkPipelineShaderStageCreateInfo shader_stages[2] = {
+ _shader_load(d->vk, shaders_distortion_vert,
+ sizeof(shaders_distortion_vert),
+ VK_SHADER_STAGE_VERTEX_BIT),
+ _shader_load(d->vk, fragment_shader_code, fragment_shader_size,
+ VK_SHADER_STAGE_FRAGMENT_BIT),
+ };
+
+ /*
+ * We will generate positions and UVs for the full screen quad
+ * from the gl_VertexIndex
+ */
+ VkPipelineVertexInputStateCreateInfo empty_input_state = {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+ };
+
+ VkGraphicsPipelineCreateInfo pipeline_info = {
+ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+ .flags = 0,
+ .stageCount = ARRAY_SIZE(shader_stages),
+ .pStages = shader_stages,
+ .pVertexInputState = &empty_input_state,
+ .pInputAssemblyState = &input_assembly_state,
+ .pViewportState = &viewport_state,
+ .pRasterizationState = &rasterization_state,
+ .pMultisampleState = &multisample_state,
+ .pDepthStencilState = &depth_stencil_state,
+ .pColorBlendState = &color_blend_state,
+ .pDynamicState = &dynamic_state,
+ .layout = d->pipeline_layout,
+ .renderPass = render_pass,
+ .basePipelineHandle = VK_NULL_HANDLE,
+ .basePipelineIndex = -1,
+ };
+
+ ret = vk->vkCreateGraphicsPipelines(vk->device, pipeline_cache, 1,
+ &pipeline_info, NULL, &d->pipeline);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(d->vk, "vkCreateGraphicsPipelines failed %u!", ret);
+ }
+
+ vk->vkDestroyShaderModule(vk->device, shader_stages[0].module, NULL);
+ vk->vkDestroyShaderModule(vk->device, shader_stages[1].module, NULL);
+}
+
+static VkWriteDescriptorSet
+comp_distortion_get_uniform_write_descriptor_set(struct comp_distortion *d,
+ uint32_t binding,
+ uint32_t eye)
+{
+ return (VkWriteDescriptorSet){
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .dstSet = d->descriptor_sets[eye],
+ .dstBinding = binding,
+ .descriptorCount = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+ .pBufferInfo = &d->ubo_handle.descriptor,
+ };
+}
+
+static VkWriteDescriptorSet
+comp_distortion_get_uniform_write_descriptor_set_vp(struct comp_distortion *d,
+ uint32_t binding,
+ uint32_t eye)
+{
+ return (VkWriteDescriptorSet){
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .dstSet = d->descriptor_sets[eye],
+ .dstBinding = binding,
+ .descriptorCount = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+ .pBufferInfo = &d->ubo_viewport_handles[eye].descriptor,
+ };
+}
+
+static VkWriteDescriptorSet
+comp_distortion_get_image_write_descriptor_set(
+ VkDescriptorSet descriptor_set,
+ VkDescriptorImageInfo *descriptor_position,
+ uint32_t binding)
+{
+ return (VkWriteDescriptorSet){
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .dstSet = descriptor_set,
+ .dstBinding = binding,
+ .descriptorCount = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+ .pImageInfo = descriptor_position,
+ };
+}
+
+static void
+comp_distortion_init_descriptor_sets(struct comp_distortion *d,
+ VkDescriptorPool descriptor_pool)
+{
+ struct vk_bundle *vk = d->vk;
+ VkResult ret;
+
+ VkDescriptorSetAllocateInfo alloc_info = {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
+ .descriptorPool = descriptor_pool,
+ .descriptorSetCount = 1,
+ .pSetLayouts = &d->descriptor_set_layout,
+ };
+
+ for (uint32_t i = 0; i < 2; i++) {
+ ret = vk->vkAllocateDescriptorSets(d->vk->device, &alloc_info,
+ &d->descriptor_sets[i]);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(d->vk, "vkAllocateDescriptorSets failed %u",
+ ret);
+ }
+ }
+}
+
+void
+comp_distortion_update_descriptor_set(struct comp_distortion *d,
+ VkSampler sampler,
+ VkImageView view,
+ uint32_t eye)
+{
+ struct vk_bundle *vk = d->vk;
+
+ VkDescriptorImageInfo image_info = {
+ .sampler = sampler,
+ .imageView = view,
+ .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ };
+
+ VkWriteDescriptorSet write_descriptor_sets[3] = {
+ // Binding 0 : Render texture target
+ comp_distortion_get_image_write_descriptor_set(
+ d->descriptor_sets[eye], &image_info, 0),
+ // Binding 1 : Fragment shader uniform buffer
+ comp_distortion_get_uniform_write_descriptor_set(d, 1, eye),
+ // Binding 2 : view uniform buffer
+ comp_distortion_get_uniform_write_descriptor_set_vp(d, 2, eye),
+ };
+
+ vk->vkUpdateDescriptorSets(vk->device,
+ ARRAY_SIZE(write_descriptor_sets),
+ write_descriptor_sets, 0, NULL);
+}
+
+static void
+comp_distortion_update_descriptor_sets(struct comp_distortion *d,
+ VkSampler samplers[2],
+ VkImageView views[2])
+{
+ for (uint32_t i = 0; i < 2; i++) {
+ comp_distortion_update_descriptor_set(d, samplers[i], views[i],
+ i);
+ }
+}
+
+static void
+comp_distortion_init_descriptor_set_layout(struct comp_distortion *d)
+{
+ struct vk_bundle *vk = d->vk;
+ VkResult ret;
+
+ VkDescriptorSetLayoutBinding set_layout_bindings[3] = {
+ // Binding 0 : Render texture target left
+ {
+ .binding = 0,
+ .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+ .descriptorCount = 1,
+ .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
+ },
+ // Binding 1 : Fragment shader uniform buffer
+ {
+ .binding = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+ .descriptorCount = 1,
+ .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
+ },
+ // binding 2: viewport index
+ {
+ .binding = 2,
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+ .descriptorCount = 1,
+ .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
+ },
+ };
+
+ VkDescriptorSetLayoutCreateInfo set_layout_info = {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
+ .bindingCount = ARRAY_SIZE(set_layout_bindings),
+ .pBindings = set_layout_bindings,
+ };
+
+ ret = vk->vkCreateDescriptorSetLayout(d->vk->device, &set_layout_info,
+ NULL, &d->descriptor_set_layout);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(d->vk, "vkCreateDescriptorSetLayout failed %u", ret);
+ }
+}
+
+static void
+comp_distortion_init_pipeline_layout(struct comp_distortion *d)
+{
+ struct vk_bundle *vk = d->vk;
+ VkResult ret;
+
+ VkPipelineLayoutCreateInfo pipeline_layout_info = {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+ .setLayoutCount = 1,
+ .pSetLayouts = &d->descriptor_set_layout,
+ };
+
+ ret = vk->vkCreatePipelineLayout(d->vk->device, &pipeline_layout_info,
+ NULL, &d->pipeline_layout);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(d->vk, "Failed to create pipeline layout!");
+ }
+}
+
+void
+comp_distortion_draw_quad(struct comp_distortion *d,
+ VkCommandBuffer command_buffer,
+ int eye)
+{
+ struct vk_bundle *vk = d->vk;
+
+ vk->vkCmdBindDescriptorSets(
+ command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, d->pipeline_layout,
+ 0, 1, &d->descriptor_sets[eye], 0, NULL);
+
+ vk->vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
+ d->pipeline);
+
+ /* Draw 3 verts from which we construct the fullscreen quad in
+ * the shader*/
+ vk->vkCmdDraw(command_buffer, 3, 1, 0, 0);
+}
+
+// Update fragment shader hmd warp uniform block
+static void
+comp_distortion_update_uniform_buffer_warp(struct comp_distortion *d,
+ struct comp_compositor *c)
+{
+ /*
+ * Pano vision fragment shader
+ */
+
+ // clang-format off
+ d->ubo_data.hmd_warp_param[0] = c->xdev->distortion.pano.distortion_k[0];
+ d->ubo_data.hmd_warp_param[1] = c->xdev->distortion.pano.distortion_k[1];
+ d->ubo_data.hmd_warp_param[2] = c->xdev->distortion.pano.distortion_k[2];
+ d->ubo_data.hmd_warp_param[3] = c->xdev->distortion.pano.distortion_k[3];
+ d->ubo_data.aberr[0] = c->xdev->distortion.pano.aberration_k[0];
+ d->ubo_data.aberr[1] = c->xdev->distortion.pano.aberration_k[1];
+ d->ubo_data.aberr[2] = c->xdev->distortion.pano.aberration_k[2];
+ d->ubo_data.aberr[3] = c->xdev->distortion.pano.aberration_k[3];
+ d->ubo_data.lens_center[0][0] = c->xdev->views[0].lens_center.x_meters;
+ d->ubo_data.lens_center[0][1] = c->xdev->views[0].lens_center.y_meters;
+ d->ubo_data.lens_center[1][0] = c->xdev->views[1].lens_center.x_meters;
+ d->ubo_data.lens_center[1][1] = c->xdev->views[1].lens_center.y_meters;
+ d->ubo_data.viewport_scale[0] = c->xdev->views[0].display.w_meters;
+ d->ubo_data.viewport_scale[1] = c->xdev->views[0].display.h_meters;
+ d->ubo_data.warp_scale = c->xdev->distortion.pano.warp_scale;
+
+ memcpy(d->ubo_handle.mapped, &d->ubo_data, sizeof(d->ubo_data));
+ // clang-format on
+
+
+ /*
+ * Common vertex shader stuff.
+ */
+
+ // clang-format off
+ d->ubo_vp_data[0].viewport_id = 0;
+ d->ubo_vp_data[0].rot = c->xdev->views[0].rot;
+ d->ubo_vp_data[1].viewport_id = 1;
+ d->ubo_vp_data[1].rot = c->xdev->views[1].rot;
+
+ memcpy(d->ubo_viewport_handles[0].mapped, &d->ubo_vp_data[0], sizeof(d->ubo_vp_data[0]));
+ memcpy(d->ubo_viewport_handles[1].mapped, &d->ubo_vp_data[1], sizeof(d->ubo_vp_data[1]));
+ // clang-format on
+}
+
+static VkResult
+_create_buffer(struct vk_bundle *vk,
+ VkBufferUsageFlags usage_flags,
+ VkMemoryPropertyFlags memory_property_flags,
+ struct comp_uniform_buffer *buffer,
+ VkDeviceSize size,
+ void *data)
+{
+ buffer->device = vk->device;
+ VkResult ret;
+
+ // Create the buffer handle.
+ VkBufferCreateInfo buffer_info = {
+ .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
+ .size = size,
+ .usage = usage_flags,
+ };
+ ret =
+ vk->vkCreateBuffer(vk->device, &buffer_info, NULL, &buffer->buffer);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "Failed to create buffer!");
+ return ret;
+ }
+
+ // Create the memory backing up the buffer handle.
+ VkMemoryRequirements mem_reqs;
+ vk->vkGetBufferMemoryRequirements(vk->device, buffer->buffer,
+ &mem_reqs);
+
+ // Find a memory type index that fits the properties of the buffer.
+ uint32_t memory_type_index;
+ vk_get_memory_type(vk, mem_reqs.memoryTypeBits, memory_property_flags,
+ &memory_type_index);
+
+ VkMemoryAllocateInfo mem_alloc = {
+ .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+ .allocationSize = mem_reqs.size,
+ .memoryTypeIndex = memory_type_index,
+ };
+
+ ret =
+ vk->vkAllocateMemory(vk->device, &mem_alloc, NULL, &buffer->memory);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "Failed to allocate memory!");
+ goto err_buffer;
+ }
+
+ buffer->alignment = mem_reqs.alignment;
+ buffer->size = mem_alloc.allocationSize;
+ buffer->usageFlags = usage_flags;
+ buffer->memoryPropertyFlags = memory_property_flags;
+
+ // If a pointer to the buffer data has been passed, map the
+ // buffer and copy over the data
+ if (data != NULL) {
+ ret = _buffer_map(vk, buffer, VK_WHOLE_SIZE, 0);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "Failed to map buffer!");
+ goto err_memory;
+ }
+
+ memcpy(buffer->mapped, data, size);
+ _buffer_unmap(vk, buffer);
+ }
+
+ // Initialize a default descriptor that covers the whole buffer size
+ _buffer_setup_descriptor(vk, buffer, VK_WHOLE_SIZE, 0);
+
+ // Attach the memory to the buffer object
+ ret = vk->vkBindBufferMemory(vk->device, buffer->buffer, buffer->memory,
+ 0);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "Failed to bind buffer to memory!");
+ goto err_memory;
+ }
+
+ return VK_SUCCESS;
+
+
+err_memory:
+ vk->vkFreeMemory(vk->device, buffer->memory, NULL);
+
+err_buffer:
+ vk->vkDestroyBuffer(vk->device, buffer->buffer, NULL);
+
+ return ret;
+}
+
+static void
+comp_distortion_init_uniform_buffer(struct comp_distortion *d,
+ struct comp_compositor *c)
+{
+ struct vk_bundle *vk = &c->vk;
+ VkMemoryPropertyFlags memory_property_flags = 0;
+ VkBufferUsageFlags usage_flags = 0;
+ VkResult ret;
+
+ // Using the same flags for all uniform buffers.
+ usage_flags |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+ memory_property_flags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+ memory_property_flags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
+
+ // Warp UBO in deferred fragment shader
+ ret = _create_buffer(vk, usage_flags, memory_property_flags,
+ &d->ubo_handle, sizeof(d->ubo_data), NULL);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "Failed to create warp ubo buffer!");
+ }
+ ret = _buffer_map(vk, &d->ubo_handle, VK_WHOLE_SIZE, 0);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "Failed to map warp ubo buffer!");
+ }
+
+ // vp ubos
+ ret = _create_buffer(vk, usage_flags, memory_property_flags,
+ &d->ubo_viewport_handles[0],
+ sizeof(d->ubo_vp_data[0]), NULL);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "Failed to create vp ubo buffer[0]!");
+ }
+ ret = _buffer_map(vk, &d->ubo_viewport_handles[0], VK_WHOLE_SIZE, 0);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "Failed to map vp ubo buffer[0]!");
+ }
+
+ ret = _create_buffer(vk, usage_flags, memory_property_flags,
+ &d->ubo_viewport_handles[1],
+ sizeof(d->ubo_vp_data[1]), NULL);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "Failed to create vp ubo buffer[1]!");
+ }
+ ret = _buffer_map(vk, &d->ubo_viewport_handles[1], VK_WHOLE_SIZE, 0);
+ if (ret != VK_SUCCESS) {
+ VK_DEBUG(vk, "Failed to map vp ubo buffer[1]!");
+ }
+}
diff --git a/src/xrt/compositor/main/comp_distortion.h b/src/xrt/compositor/main/comp_distortion.h
new file mode 100644
index 000000000..b70ea626a
--- /dev/null
+++ b/src/xrt/compositor/main/comp_distortion.h
@@ -0,0 +1,135 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Distortion shader code header.
+ * @author Lubosz Sarnecki
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#pragma once
+
+#include "main/comp_settings.h"
+#include "main/comp_compositor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ *
+ * Structs
+ *
+ */
+
+
+/*!
+ * Helper buffer for a single uniform buffer.
+ *
+ * @ingroup comp
+ */
+struct comp_uniform_buffer
+{
+ VkDevice device;
+ VkBuffer buffer;
+ VkDeviceMemory memory;
+ VkDescriptorBufferInfo descriptor;
+ VkDeviceSize size;
+ VkDeviceSize alignment;
+ void *mapped;
+ VkBufferUsageFlags usageFlags;
+ VkMemoryPropertyFlags memoryPropertyFlags;
+};
+
+/*!
+ * Helper struct that encapsulate a distortion rendering code.
+ *
+ * @ingroup comp
+ */
+struct comp_distortion
+{
+ // Holds all of the needed common Vulkan things.
+ struct vk_bundle *vk;
+
+ struct comp_uniform_buffer ubo_handle;
+ struct comp_uniform_buffer ubo_viewport_handles[2];
+
+ struct
+ {
+ float hmd_warp_param[4];
+ float aberr[4];
+ float lens_center[2][4];
+ float viewport_scale[2];
+ float warp_scale;
+ } ubo_data;
+
+ struct
+ {
+ struct xrt_matrix_2x2 rot;
+ int viewport_id;
+ bool flip_y;
+ } ubo_vp_data[2];
+
+ VkPipelineLayout pipeline_layout;
+ VkPipeline pipeline;
+
+ VkDescriptorSetLayout descriptor_set_layout;
+ VkDescriptorSet descriptor_sets[2];
+};
+
+
+/*
+ *
+ * Functions.
+ *
+ */
+
+/*!
+ * Init a distortion, pass in the distortion so it can be embedded in a struct.
+ *
+ * @ingroup comp
+ */
+void
+comp_distortion_init(struct comp_distortion *d,
+ struct comp_compositor *c,
+ VkRenderPass render_pass,
+ VkPipelineCache pipeline_cache,
+ enum xrt_distortion_model distortion_model,
+ VkDescriptorPool descriptor_pool,
+ bool flip_y);
+
+/*!
+ * Free and destroy all fields, does not free the destortion itself.
+ *
+ * @ingroup comp
+ */
+void
+comp_distortion_destroy(struct comp_distortion *d);
+
+/*!
+ * Update the descriptor set to a new image.
+ *
+ * @ingroup comp
+ */
+void
+comp_distortion_update_descriptor_set(struct comp_distortion *d,
+ VkSampler sampler,
+ VkImageView view,
+ uint32_t eye);
+
+/*!
+ * Submit draw commands to the given command_buffer.
+ *
+ * @ingroup comp
+ */
+void
+comp_distortion_draw_quad(struct comp_distortion *d,
+ VkCommandBuffer command_buffer,
+ int eye);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/compositor/main/comp_glue_gl.c b/src/xrt/compositor/main/comp_glue_gl.c
new file mode 100644
index 000000000..67b5a5e14
--- /dev/null
+++ b/src/xrt/compositor/main/comp_glue_gl.c
@@ -0,0 +1,22 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Glue code to OpenGL client side glue code.
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#include "xrt/xrt_gfx_gl.h"
+
+
+void
+xrt_gfx_gl_get_versions(struct xrt_api_requirements *ver)
+{
+ ver->min_major = 4;
+ ver->min_minor = 5;
+ ver->min_patch = 0;
+ ver->max_major = 4;
+ ver->max_minor = 6;
+ ver->max_patch = (1024 - 1);
+}
diff --git a/src/xrt/compositor/main/comp_glue_vk.c b/src/xrt/compositor/main/comp_glue_vk.c
new file mode 100644
index 000000000..b19c3c424
--- /dev/null
+++ b/src/xrt/compositor/main/comp_glue_vk.c
@@ -0,0 +1,65 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Glue code to vulkan client side glue code.
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#include
+
+#include "main/comp_client_interface.h"
+#include "client/comp_vk_client.h"
+
+
+const char *xrt_gfx_vk_instance_extensions =
+ "VK_KHR_external_fence_capabilities "
+ "VK_KHR_external_memory_capabilities "
+ "VK_KHR_external_semaphore_capabilities "
+ "VK_KHR_get_physical_device_properties2 "
+ "VK_KHR_surface";
+
+const char *xrt_gfx_vk_device_extensions =
+ "VK_KHR_dedicated_allocation "
+ "VK_KHR_external_fence "
+ "VK_KHR_external_fence_fd "
+ "VK_KHR_external_memory "
+ "VK_KHR_external_memory_fd "
+ "VK_KHR_external_semaphore "
+ "VK_KHR_external_semaphore_fd "
+ "VK_KHR_get_memory_requirements2 "
+ "VK_KHR_swapchain";
+
+void
+xrt_gfx_vk_get_versions(struct xrt_api_requirements *ver)
+{
+ ver->min_major = 1;
+ ver->min_minor = 0;
+ ver->min_patch = 0;
+
+ ver->max_major = (1024 - 1);
+ ver->max_minor = (1024 - 1);
+ ver->max_patch = (1024 - 1);
+}
+
+struct xrt_compositor_vk *
+xrt_gfx_vk_provider_create(struct xrt_device *xdev,
+ VkInstance instance,
+ PFN_vkGetInstanceProcAddr get_instance_proc_addr,
+ VkPhysicalDevice physical_device,
+ VkDevice device,
+ uint32_t queue_family_index,
+ uint32_t queue_index)
+{
+ struct xrt_compositor_fd *xcfd = comp_compositor_create(xdev, false);
+ if (xcfd == NULL) {
+ return NULL;
+ }
+
+ struct client_vk_compositor *vcc = client_vk_compositor_create(
+ xcfd, instance, get_instance_proc_addr, physical_device, device,
+ queue_family_index, queue_index);
+
+ return &vcc->base;
+}
diff --git a/src/xrt/compositor/main/comp_glue_xlib.c b/src/xrt/compositor/main/comp_glue_xlib.c
new file mode 100644
index 000000000..5e4442242
--- /dev/null
+++ b/src/xrt/compositor/main/comp_glue_xlib.c
@@ -0,0 +1,36 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Glue code to Xlib client side glue code.
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#include
+#include
+
+#include "xrt/xrt_gfx_xlib.h"
+
+#include "main/comp_client_interface.h"
+#include "client/comp_xlib_client.h"
+
+
+struct xrt_compositor_gl *
+xrt_gfx_provider_create_gl_xlib(struct xrt_device *xdev,
+ Display *xDisplay,
+ uint32_t visualid,
+ GLXFBConfig glxFBConfig,
+ GLXDrawable glxDrawable,
+ GLXContext glxContext)
+{
+ struct xrt_compositor_fd *xcfd = comp_compositor_create(xdev, true);
+ if (xcfd == NULL) {
+ return NULL;
+ }
+
+ struct client_xlib_compositor *xcc = client_xlib_compositor_create(
+ xcfd, xDisplay, visualid, glxFBConfig, glxDrawable, glxContext);
+
+ return &xcc->base.base;
+}
diff --git a/src/xrt/compositor/main/comp_renderer.c b/src/xrt/compositor/main/comp_renderer.c
new file mode 100644
index 000000000..ec29e362b
--- /dev/null
+++ b/src/xrt/compositor/main/comp_renderer.c
@@ -0,0 +1,997 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Compositor rendering code.
+ * @author Lubosz Sarnecki
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#include
+#include
+#include
+#include
+
+#include "xrt/xrt_compositor.h"
+#include "main/comp_distortion.h"
+
+
+/*
+ *
+ * Private struct.
+ *
+ */
+
+/*!
+ * Holds associated vulkan objects and state to render with a distortion.
+ *
+ * @ingroup comp
+ */
+struct comp_renderer
+{
+ bool one_buffer_imported[2];
+
+ uint32_t current_buffer;
+
+ VkQueue queue;
+ VkRenderPass render_pass;
+ VkDescriptorPool descriptor_pool;
+ VkPipelineCache pipeline_cache;
+
+ struct
+ {
+ VkSemaphore present_complete;
+ VkSemaphore render_complete;
+ } semaphores;
+
+ VkCommandBuffer *cmd_buffers;
+ uint32_t num_cmd_buffers;
+ VkFramebuffer *frame_buffers;
+ uint32_t num_frame_buffers;
+
+ struct comp_swapchain_image dummy_images[2];
+
+ struct comp_compositor *c;
+ struct comp_settings *settings;
+ struct comp_distortion *distortion;
+};
+
+
+/*
+ *
+ * Pre declare functions.
+ *
+ */
+
+static void
+renderer_create(struct comp_renderer *r, struct comp_compositor *c);
+
+static void
+renderer_init(struct comp_renderer *r);
+
+static void
+renderer_set_swapchain_image(struct comp_renderer *r,
+ uint32_t eye,
+ struct comp_swapchain_image *image);
+
+static void
+renderer_render(struct comp_renderer *r);
+
+static void
+renderer_submit_queue(struct comp_renderer *r);
+
+static void
+renderer_build_command_buffers(struct comp_renderer *r);
+
+static void
+renderer_rebuild_command_buffers(struct comp_renderer *r);
+
+static void
+renderer_build_command_buffer(struct comp_renderer *r,
+ VkCommandBuffer command_buffer,
+ VkFramebuffer framebuffer);
+
+static void
+renderer_init_descriptor_pool(struct comp_renderer *r);
+
+static void
+renderer_init_dummy_images(struct comp_renderer *r);
+
+static void
+renderer_create_frame_buffer(struct comp_renderer *r,
+ VkFramebuffer *frame_buffer,
+ uint32_t num_attachements,
+ VkImageView *attachments);
+
+static void
+renderer_allocate_command_buffers(struct comp_renderer *r, uint32_t count);
+
+static void
+renderer_destroy_command_buffers(struct comp_renderer *r);
+
+static void
+renderer_create_pipeline_cache(struct comp_renderer *r);
+
+static void
+renderer_init_semaphores(struct comp_renderer *r);
+
+static void
+renderer_resize(struct comp_renderer *r);
+
+static void
+renderer_create_frame_buffers(struct comp_renderer *r, uint32_t count);
+
+static void
+renderer_create_render_pass(struct comp_renderer *r);
+
+static void
+renderer_aquire_swapchain_image(struct comp_renderer *r);
+
+static void
+renderer_present_swapchain_image(struct comp_renderer *r);
+
+static void
+renderer_destroy(struct comp_renderer *r);
+
+
+/*
+ *
+ * Interface functions.
+ *
+ */
+
+struct comp_renderer *
+comp_renderer_create(struct comp_compositor *c)
+{
+ struct comp_renderer *r = malloc(sizeof(struct comp_renderer));
+
+ renderer_create(r, c);
+ renderer_init(r);
+
+ return r;
+}
+
+void
+comp_renderer_frame(struct comp_renderer *r,
+ struct comp_swapchain_image *left,
+ struct comp_swapchain_image *right)
+{
+ renderer_set_swapchain_image(r, 0, left);
+ renderer_set_swapchain_image(r, 1, right);
+ renderer_render(r);
+ r->c->vk.vkDeviceWaitIdle(r->c->vk.device);
+}
+
+void
+comp_renderer_destroy(struct comp_renderer *r)
+{
+ renderer_destroy(r);
+ free(r);
+}
+
+
+/*
+ *
+ * Functions.
+ *
+ */
+
+static void
+renderer_create(struct comp_renderer *r, struct comp_compositor *c)
+{
+ r->c = c;
+ r->settings = &c->settings;
+
+ r->one_buffer_imported[0] = false;
+ r->one_buffer_imported[1] = false;
+ r->current_buffer = 0;
+ r->queue = VK_NULL_HANDLE;
+ r->render_pass = VK_NULL_HANDLE;
+ r->descriptor_pool = VK_NULL_HANDLE;
+ r->pipeline_cache = VK_NULL_HANDLE;
+ r->semaphores.present_complete = VK_NULL_HANDLE;
+ r->semaphores.render_complete = VK_NULL_HANDLE;
+
+ memset(&r->dummy_images[0], 0, sizeof(struct comp_swapchain_image));
+ memset(&r->dummy_images[1], 0, sizeof(struct comp_swapchain_image));
+
+ r->distortion = NULL;
+ r->cmd_buffers = NULL;
+ r->frame_buffers = NULL;
+}
+
+static void
+renderer_submit_queue(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+ VkResult ret;
+
+ VkPipelineStageFlags stage_flags[1] = {
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ };
+
+ VkSubmitInfo comp_submit_info = {
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+ .pNext = NULL,
+ .waitSemaphoreCount = 1,
+ .pWaitSemaphores = &r->semaphores.present_complete,
+ .pWaitDstStageMask = stage_flags,
+ .commandBufferCount = 1,
+ .pCommandBuffers = &r->cmd_buffers[r->current_buffer],
+ .signalSemaphoreCount = 1,
+ .pSignalSemaphores = &r->semaphores.render_complete,
+ };
+
+ ret = vk->vkQueueSubmit(r->queue, 1, &comp_submit_info, VK_NULL_HANDLE);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vkQueueSubmit: %s", vk_result_string(ret));
+ }
+}
+
+static void
+renderer_build_command_buffers(struct comp_renderer *r)
+{
+ for (uint32_t i = 0; i < r->num_cmd_buffers; ++i)
+ renderer_build_command_buffer(r, r->cmd_buffers[i],
+ r->frame_buffers[i]);
+}
+
+static void
+renderer_rebuild_command_buffers(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+
+
+ vk->vkFreeCommandBuffers(vk->device, vk->cmd_pool, r->num_cmd_buffers,
+ r->cmd_buffers);
+ renderer_allocate_command_buffers(r,
+ r->c->window->swapchain.image_count);
+ renderer_build_command_buffers(r);
+}
+
+static void
+renderer_set_viewport_scissor(float scale_x,
+ float scale_y,
+ VkViewport *v,
+ VkRect2D *s,
+ struct xrt_view *view)
+{
+ v->x = view->viewport.x_pixels * scale_x;
+ v->y = view->viewport.y_pixels * scale_y;
+ v->width = view->viewport.w_pixels * scale_x;
+ v->height = view->viewport.h_pixels * scale_y;
+
+ s->offset.x = (int32_t)(view->viewport.x_pixels * scale_x);
+ s->offset.y = (int32_t)(view->viewport.y_pixels * scale_y);
+ s->extent.width = (uint32_t)(view->viewport.w_pixels * scale_x);
+ s->extent.height = (uint32_t)(view->viewport.h_pixels * scale_y);
+}
+
+static void
+renderer_build_command_buffer(struct comp_renderer *r,
+ VkCommandBuffer command_buffer,
+ VkFramebuffer framebuffer)
+{
+ struct vk_bundle *vk = &r->c->vk;
+ VkResult ret;
+
+ VkClearValue clear_color = {
+ .color = {.float32 = {0.0f, 0.0f, 0.0f, 0.0f}}};
+
+ VkCommandBufferBeginInfo command_buffer_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ .pInheritanceInfo = NULL,
+ };
+
+ ret = vk->vkBeginCommandBuffer(command_buffer, &command_buffer_info);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vkBeginCommandBuffer: %s",
+ vk_result_string(ret));
+ return;
+ }
+
+ VkRenderPassBeginInfo render_pass_begin_info = {
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+ .pNext = NULL,
+ .renderPass = r->render_pass,
+ .framebuffer = framebuffer,
+ .renderArea =
+ {
+ .offset =
+ {
+ .x = 0,
+ .y = 0,
+ },
+ .extent =
+ {
+ .width = r->c->current.width,
+ .height = r->c->current.height,
+ },
+ },
+ .clearValueCount = 1,
+ .pClearValues = &clear_color,
+ };
+ vk->vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info,
+ VK_SUBPASS_CONTENTS_INLINE);
+
+
+ // clang-format off
+ float scale_x = (float)r->c->current.width /
+ (float)r->c->xdev->screens[0].w_pixels;
+ float scale_y = (float)r->c->current.height /
+ (float)r->c->xdev->screens[0].h_pixels;
+ // clang-format on
+
+ VkViewport viewport = {
+ .x = 0,
+ .y = 0,
+ .width = 0,
+ .height = 0,
+ .minDepth = 0.0f,
+ .maxDepth = 1.0f,
+ };
+
+ VkRect2D scissor = {
+ .offset = {.x = 0, .y = 0},
+ .extent = {.width = 0, .height = 0},
+ };
+
+ renderer_set_viewport_scissor(scale_x, scale_y, &viewport, &scissor,
+ &r->c->xdev->views[0]);
+ vk->vkCmdSetViewport(command_buffer, 0, 1, &viewport);
+ vk->vkCmdSetScissor(command_buffer, 0, 1, &scissor);
+
+ comp_distortion_draw_quad(r->distortion, command_buffer, 0);
+
+
+ renderer_set_viewport_scissor(scale_x, scale_y, &viewport, &scissor,
+ &r->c->xdev->views[1]);
+ vk->vkCmdSetViewport(command_buffer, 0, 1, &viewport);
+ vk->vkCmdSetScissor(command_buffer, 0, 1, &scissor);
+
+ comp_distortion_draw_quad(r->distortion, command_buffer, 1);
+
+ vk->vkCmdEndRenderPass(command_buffer);
+
+ ret = vk->vkEndCommandBuffer(command_buffer);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vkEndCommandBuffer: %s",
+ vk_result_string(ret));
+ return;
+ }
+}
+
+static void
+renderer_init_descriptor_pool(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+ VkResult ret;
+
+ VkDescriptorPoolSize pool_sizes[2] = {
+ {
+ .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+ .descriptorCount = 4,
+ },
+ {
+ .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+ .descriptorCount = 2,
+ },
+ };
+
+ VkDescriptorPoolCreateInfo descriptor_pool_info = {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ .maxSets = 2,
+ .poolSizeCount = ARRAY_SIZE(pool_sizes),
+ .pPoolSizes = pool_sizes,
+ };
+
+ ret = vk->vkCreateDescriptorPool(vk->device, &descriptor_pool_info,
+ NULL, &r->descriptor_pool);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vkCreateDescriptorPool: %s",
+ vk_result_string(ret));
+ }
+}
+
+
+static void
+_set_image_layout(struct vk_bundle *vk,
+ VkCommandBuffer cmd_buffer,
+ VkImage image,
+ VkAccessFlags src_access_mask,
+ VkAccessFlags dst_access_mask,
+ VkImageLayout old_layout,
+ VkImageLayout new_layout,
+ VkImageSubresourceRange subresource_range)
+{
+ VkImageMemoryBarrier barrier = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+ .pNext = NULL,
+ .srcAccessMask = src_access_mask,
+ .dstAccessMask = dst_access_mask,
+ .oldLayout = old_layout,
+ .newLayout = new_layout,
+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .image = image,
+ .subresourceRange = subresource_range,
+ };
+
+ vk->vkCmdPipelineBarrier(cmd_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, NULL,
+ 0, NULL, 1, &barrier);
+}
+
+static bool
+_init_cmd_buffer(struct comp_compositor *c,
+ VkCommandPool cmd_pool,
+ VkCommandBuffer *out_cmd_buffer)
+{
+ struct vk_bundle *vk = &c->vk;
+
+ VkCommandBufferAllocateInfo cmd_buffer_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+ .pNext = NULL,
+ .commandPool = cmd_pool,
+ .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+ .commandBufferCount = 1,
+ };
+
+ VkResult ret;
+ ret = vk->vkAllocateCommandBuffers(vk->device, &cmd_buffer_info,
+ out_cmd_buffer);
+ if (ret != VK_SUCCESS) {
+ fprintf(stderr,
+ "Error: Could not initialize command buffer.\n");
+ return false;
+ }
+
+ VkCommandBufferBeginInfo begin_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ .pInheritanceInfo = NULL,
+ };
+ ret = vk->vkBeginCommandBuffer(*out_cmd_buffer, &begin_info);
+ if (ret != VK_SUCCESS) {
+ fprintf(stderr, "Error: Could not begin command buffer.\n");
+ return false;
+ }
+ return true;
+}
+
+static bool
+_submit_cmd_buffer(struct comp_compositor *c,
+ VkCommandPool cmd_pool,
+ VkCommandBuffer cmd_buffer)
+{
+ struct vk_bundle *vk = &c->vk;
+ VkResult ret;
+
+ ret = vk->vkEndCommandBuffer(cmd_buffer);
+ if (ret != VK_SUCCESS) {
+ }
+
+ VkSubmitInfo submitInfo = {
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+ .pNext = NULL,
+ .waitSemaphoreCount = 0,
+ .pWaitSemaphores = NULL,
+ .pWaitDstStageMask = NULL,
+ .commandBufferCount = 1,
+ .pCommandBuffers = &cmd_buffer,
+ .signalSemaphoreCount = 0,
+ .pSignalSemaphores = NULL,
+ };
+
+ VkFenceCreateInfo fence_info = {
+ .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ };
+ VkFence fence;
+ ret = vk->vkCreateFence(vk->device, &fence_info, NULL, &fence);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(c, "vkCreateFence: %s", vk_result_string(ret));
+ vk->vkFreeCommandBuffers(vk->device, cmd_pool, 1, &cmd_buffer);
+ return false;
+ }
+
+ VkQueue queue;
+ vk->vkGetDeviceQueue(vk->device, c->vk.queue_family_index, 0, &queue);
+
+ ret = vk->vkQueueSubmit(queue, 1, &submitInfo, fence);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(c, "vkCreateFence: %s", vk_result_string(ret));
+ vk->vkDestroyFence(vk->device, fence, NULL);
+ vk->vkFreeCommandBuffers(vk->device, cmd_pool, 1, &cmd_buffer);
+ return false;
+ }
+
+ ret = vk->vkWaitForFences(vk->device, 1, &fence, VK_TRUE, UINT64_MAX);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(c, "vkCreateFence: %s", vk_result_string(ret));
+ vk->vkDestroyFence(vk->device, fence, NULL);
+ vk->vkFreeCommandBuffers(vk->device, cmd_pool, 1, &cmd_buffer);
+ return false;
+ }
+
+ vk->vkDestroyFence(vk->device, fence, NULL);
+ vk->vkFreeCommandBuffers(vk->device, cmd_pool, 1, &cmd_buffer);
+
+ return true;
+}
+
+static void
+renderer_init_dummy_images(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+ VkCommandBuffer cmd_buffer;
+ _init_cmd_buffer(r->c, vk->cmd_pool, &cmd_buffer);
+
+ VkImageSubresourceRange subresource_range = {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .baseMipLevel = 0,
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ .layerCount = 1};
+
+ VkClearColorValue color = {.float32 = {1, 1, 1, 1}};
+
+ for (uint32_t i = 0; i < 2; i++) {
+ vk_create_image_simple(
+ &r->c->vk, 640, 800, VK_FORMAT_B8G8R8A8_SRGB,
+ &r->dummy_images[i].memory, &r->dummy_images[i].image);
+
+ _set_image_layout(
+ vk, cmd_buffer, r->dummy_images[i].image, 0,
+ VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresource_range);
+
+ vk->vkCmdClearColorImage(cmd_buffer, r->dummy_images[i].image,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ &color, 1, &subresource_range);
+
+ vk_set_image_layout(vk, cmd_buffer, r->dummy_images[i].image,
+ VK_ACCESS_TRANSFER_WRITE_BIT,
+ VK_ACCESS_SHADER_READ_BIT,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ subresource_range);
+
+ vk_create_sampler(vk, &r->dummy_images[i].sampler);
+ vk_create_view(vk, r->dummy_images[i].image,
+ VK_FORMAT_B8G8R8A8_SRGB,
+ &r->dummy_images[i].view);
+ }
+
+ _submit_cmd_buffer(r->c, vk->cmd_pool, cmd_buffer);
+}
+
+static void
+renderer_init(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+
+ vk->vkGetDeviceQueue(vk->device, r->c->vk.queue_family_index, 0,
+ &r->queue);
+ renderer_init_semaphores(r);
+ renderer_create_pipeline_cache(r);
+ renderer_create_render_pass(r);
+
+ assert(r->c->window->swapchain.image_count > 0);
+
+ renderer_create_frame_buffers(r, r->c->window->swapchain.image_count);
+ renderer_allocate_command_buffers(r,
+ r->c->window->swapchain.image_count);
+
+ renderer_init_dummy_images(r);
+
+ renderer_init_descriptor_pool(r);
+
+ r->distortion = calloc(1, sizeof(struct comp_distortion));
+
+ comp_distortion_init(r->distortion, r->c, r->render_pass,
+ r->pipeline_cache, r->settings->distortion_model,
+ r->descriptor_pool, r->settings->flip_y);
+
+ for (uint32_t i = 0; i < 2; i++)
+ comp_distortion_update_descriptor_set(
+ r->distortion, r->dummy_images[i].sampler,
+ r->dummy_images[i].view, i);
+
+ renderer_build_command_buffers(r);
+}
+
+static void
+renderer_set_swapchain_image(struct comp_renderer *r,
+ uint32_t eye,
+ struct comp_swapchain_image *image)
+{
+ if (eye > 1) {
+ COMP_ERROR(r->c, "Swapchain image %p %u not found",
+ (void *)image, eye);
+ return;
+ }
+
+ if (!r->one_buffer_imported[eye]) {
+ COMP_DEBUG(r->c,
+ "Updating descriptor set for"
+ " swapchain image %p and eye %u",
+ (void *)image, eye);
+ comp_distortion_update_descriptor_set(
+ r->distortion, image->sampler, image->view, (uint32_t)eye);
+ renderer_rebuild_command_buffers(r);
+ r->one_buffer_imported[eye] = true;
+ }
+}
+
+static void
+renderer_render(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+
+ r->c->window->flush(r->c->window);
+ renderer_aquire_swapchain_image(r);
+ vk->vkDeviceWaitIdle(vk->device);
+ renderer_submit_queue(r);
+ renderer_present_swapchain_image(r);
+}
+
+static void
+renderer_create_frame_buffer(struct comp_renderer *r,
+ VkFramebuffer *frame_buffer,
+ uint32_t num_attachements,
+ VkImageView *attachments)
+{
+ struct vk_bundle *vk = &r->c->vk;
+ VkResult ret;
+
+ VkFramebufferCreateInfo frame_buffer_info = {
+ .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ .renderPass = r->render_pass,
+ .attachmentCount = num_attachements,
+ .pAttachments = attachments,
+ .width = r->c->current.width,
+ .height = r->c->current.height,
+ .layers = 1,
+ };
+
+ ret = vk->vkCreateFramebuffer(vk->device, &frame_buffer_info, NULL,
+ frame_buffer);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vkCreateFramebuffer: %s",
+ vk_result_string(ret));
+ }
+}
+
+static void
+renderer_allocate_command_buffers(struct comp_renderer *r, uint32_t count)
+{
+ struct vk_bundle *vk = &r->c->vk;
+ VkResult ret;
+
+ if (count == 0) {
+ COMP_ERROR(r->c, "Requested 0 command buffers.");
+ return;
+ }
+
+ COMP_DEBUG(r->c, "Allocating %d Command Buffers.", count);
+
+ if (r->cmd_buffers != NULL)
+ free(r->cmd_buffers);
+
+ r->num_cmd_buffers = count;
+
+ r->cmd_buffers = malloc(sizeof(VkCommandBuffer) * count);
+
+ VkCommandBufferAllocateInfo cmd_buffer_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+ .pNext = NULL,
+ .commandPool = vk->cmd_pool,
+ .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+ .commandBufferCount = count,
+ };
+
+ ret = vk->vkAllocateCommandBuffers(vk->device, &cmd_buffer_info,
+ r->cmd_buffers);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vkCreateFramebuffer: %s",
+ vk_result_string(ret));
+ }
+}
+
+static void
+renderer_destroy_command_buffers(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+
+ vk->vkFreeCommandBuffers(vk->device, vk->cmd_pool, r->num_cmd_buffers,
+ r->cmd_buffers);
+}
+
+static void
+renderer_create_pipeline_cache(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+ VkResult ret;
+
+ VkPipelineCacheCreateInfo pipeline_cache_info = {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ .initialDataSize = 0,
+ .pInitialData = NULL,
+ };
+ ret = vk->vkCreatePipelineCache(vk->device, &pipeline_cache_info, NULL,
+ &r->pipeline_cache);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vkCreatePipelineCache: %s",
+ vk_result_string(ret));
+ }
+}
+
+static void
+renderer_init_semaphores(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+ VkResult ret;
+
+ VkSemaphoreCreateInfo info = {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ };
+
+ ret = vk->vkCreateSemaphore(vk->device, &info, NULL,
+ &r->semaphores.present_complete);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vkCreateSemaphore: %s",
+ vk_result_string(ret));
+ }
+
+ ret = vk->vkCreateSemaphore(vk->device, &info, NULL,
+ &r->semaphores.render_complete);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vkCreateSemaphore: %s",
+ vk_result_string(ret));
+ }
+}
+
+static void
+renderer_resize(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+
+ vk->vkDeviceWaitIdle(vk->device);
+
+ vk_swapchain_create(&r->c->window->swapchain, r->c->current.width,
+ r->c->current.height, r->settings->color_format,
+ r->settings->color_space,
+ r->settings->present_mode);
+
+ for (uint32_t i = 0; i < r->num_frame_buffers; i++)
+ vk->vkDestroyFramebuffer(vk->device, r->frame_buffers[i], NULL);
+ renderer_create_frame_buffers(r, r->c->window->swapchain.image_count);
+
+ renderer_destroy_command_buffers(r);
+ renderer_allocate_command_buffers(r,
+ r->c->window->swapchain.image_count);
+
+ renderer_build_command_buffers(r);
+ vk->vkDeviceWaitIdle(vk->device);
+}
+
+static void
+renderer_create_frame_buffers(struct comp_renderer *r, uint32_t count)
+{
+ r->num_frame_buffers = count;
+
+ if (r->frame_buffers != NULL)
+ free(r->frame_buffers);
+
+ r->frame_buffers = malloc(sizeof(VkFramebuffer) * count);
+
+ for (uint32_t i = 0; i < count; i++) {
+ VkImageView attachments[1] = {
+ r->c->window->swapchain.buffers[i].view,
+ };
+ renderer_create_frame_buffer(r, &r->frame_buffers[i],
+ ARRAY_SIZE(attachments),
+ attachments);
+ }
+}
+
+static void
+renderer_create_render_pass(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+ VkResult ret;
+
+ VkAttachmentDescription attachments[1] = {
+ (VkAttachmentDescription){
+ .flags = 0,
+ .format = r->c->window->swapchain.surface_format.format,
+ .samples = VK_SAMPLE_COUNT_1_BIT,
+ .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
+ .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+ .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+ .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
+ .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
+ .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+ },
+ };
+
+ VkAttachmentReference color_reference = {
+ .attachment = 0,
+ .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ };
+
+ VkSubpassDescription subpass_description = {
+ .flags = 0,
+ .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
+ .inputAttachmentCount = 0,
+ .pInputAttachments = NULL,
+ .colorAttachmentCount = 1,
+ .pColorAttachments = &color_reference,
+ .pResolveAttachments = NULL,
+ .pDepthStencilAttachment = NULL,
+ .preserveAttachmentCount = 0,
+ .pPreserveAttachments = NULL,
+ };
+
+ VkSubpassDependency dependencies[1] = {
+ (VkSubpassDependency){
+ .srcSubpass = VK_SUBPASS_EXTERNAL,
+ .dstSubpass = 0,
+ .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ .srcAccessMask = 0,
+ .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ .dependencyFlags = 0,
+ },
+ };
+
+ VkRenderPassCreateInfo render_pass_info = {
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ .attachmentCount = ARRAY_SIZE(attachments),
+ .pAttachments = attachments,
+ .subpassCount = 1,
+ .pSubpasses = &subpass_description,
+ .dependencyCount = ARRAY_SIZE(dependencies),
+ .pDependencies = dependencies,
+ };
+
+ ret = vk->vkCreateRenderPass(vk->device, &render_pass_info, NULL,
+ &r->render_pass);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vkCreateRenderPass: %s",
+ vk_result_string(ret));
+ }
+}
+
+static void
+renderer_aquire_swapchain_image(struct comp_renderer *r)
+{
+ VkResult ret;
+
+ ret = vk_swapchain_acquire_next_image(&r->c->window->swapchain,
+ r->semaphores.present_complete,
+ &r->current_buffer);
+
+ if ((ret == VK_ERROR_OUT_OF_DATE_KHR) || (ret == VK_SUBOPTIMAL_KHR)) {
+ COMP_DEBUG(r->c, "Received %s.", vk_result_string(ret));
+ renderer_resize(r);
+ /* Acquire image again to silence validation error */
+ ret = vk_swapchain_acquire_next_image(
+ &r->c->window->swapchain, r->semaphores.present_complete,
+ &r->current_buffer);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vk_swapchain_acquire_next_image: %s",
+ vk_result_string(ret));
+ }
+ } else if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vk_swapchain_acquire_next_image: %s",
+ vk_result_string(ret));
+ }
+}
+
+static void
+renderer_present_swapchain_image(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+ VkResult ret;
+
+ ret = vk_swapchain_present(&r->c->window->swapchain, r->queue,
+ r->current_buffer,
+ r->semaphores.render_complete);
+ if (ret == VK_ERROR_OUT_OF_DATE_KHR) {
+ renderer_resize(r);
+ return;
+ } else if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vk_swapchain_present: %s",
+ vk_result_string(ret));
+ }
+
+ ret = vk->vkQueueWaitIdle(r->queue);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(r->c, "vkQueueWaitIdle: %s", vk_result_string(ret));
+ }
+}
+
+static void
+renderer_destroy(struct comp_renderer *r)
+{
+ struct vk_bundle *vk = &r->c->vk;
+
+ // Distortion
+ if (r->distortion != NULL) {
+ comp_distortion_destroy(r->distortion);
+ r->distortion = NULL;
+ }
+
+ // Dummy images
+ for (uint32_t i = 0; i < 2; i++) {
+ comp_swapchain_image_cleanup(vk, &r->dummy_images[i]);
+ }
+
+ // Discriptor pool
+ if (r->descriptor_pool != VK_NULL_HANDLE) {
+ vk->vkDestroyDescriptorPool(vk->device, r->descriptor_pool,
+ NULL);
+ r->descriptor_pool = VK_NULL_HANDLE;
+ }
+
+ // Command buffers
+ renderer_destroy_command_buffers(r);
+ if (r->cmd_buffers != NULL)
+ free(r->cmd_buffers);
+ r->num_cmd_buffers = 0;
+
+ // Render pass
+ if (r->render_pass != VK_NULL_HANDLE) {
+ vk->vkDestroyRenderPass(vk->device, r->render_pass, NULL);
+ r->render_pass = VK_NULL_HANDLE;
+ }
+
+ // Frame buffers
+ for (uint32_t i = 0; i < r->num_frame_buffers; i++) {
+ if (r->frame_buffers[i] != VK_NULL_HANDLE) {
+ vk->vkDestroyFramebuffer(vk->device,
+ r->frame_buffers[i], NULL);
+ r->frame_buffers[i] = VK_NULL_HANDLE;
+ }
+ }
+ if (r->frame_buffers != NULL)
+ free(r->frame_buffers);
+ r->frame_buffers = NULL;
+ r->num_frame_buffers = 0;
+
+ // Pipeline cache
+ if (r->pipeline_cache != VK_NULL_HANDLE) {
+ vk->vkDestroyPipelineCache(vk->device, r->pipeline_cache, NULL);
+ r->pipeline_cache = VK_NULL_HANDLE;
+ }
+
+ // Semaphores
+ if (r->semaphores.present_complete != VK_NULL_HANDLE) {
+ vk->vkDestroySemaphore(vk->device,
+ r->semaphores.present_complete, NULL);
+ r->semaphores.present_complete = VK_NULL_HANDLE;
+ }
+ if (r->semaphores.render_complete != VK_NULL_HANDLE) {
+ vk->vkDestroySemaphore(vk->device,
+ r->semaphores.render_complete, NULL);
+ r->semaphores.render_complete = VK_NULL_HANDLE;
+ }
+}
diff --git a/src/xrt/compositor/main/comp_renderer.h b/src/xrt/compositor/main/comp_renderer.h
new file mode 100644
index 000000000..9c4af294b
--- /dev/null
+++ b/src/xrt/compositor/main/comp_renderer.h
@@ -0,0 +1,53 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Compositor rendering code header.
+ * @author Lubosz Sarnecki
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#pragma once
+
+#include "xrt/xrt_compiler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct comp_compositor;
+struct comp_renderer;
+struct comp_swapchain_image;
+
+/*!
+ * Called by the main compositor code to create the renderer.
+ *
+ * @ingroup comp
+ */
+struct comp_renderer *
+comp_renderer_create(struct comp_compositor *c);
+
+/*!
+ * Render a distorted stereo frame.
+ *
+ * @ingroup comp
+ */
+void
+comp_renderer_frame(struct comp_renderer *r,
+ struct comp_swapchain_image *left,
+ struct comp_swapchain_image *right);
+
+/*!
+ * Clean up and free the renderer.
+ *
+ * @ingroup comp
+ */
+void
+comp_renderer_destroy(struct comp_renderer *r);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/compositor/main/comp_settings.c b/src/xrt/compositor/main/comp_settings.c
new file mode 100644
index 000000000..418855237
--- /dev/null
+++ b/src/xrt/compositor/main/comp_settings.c
@@ -0,0 +1,51 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Settings struct for compositor.
+ * @author Lubosz Sarnecki
+ * @ingroup comp
+ */
+
+#include "util/u_debug.h"
+#include "comp_settings.h"
+
+DEBUG_GET_ONCE_BOOL_OPTION(print_spew, "XRT_COMPOSITOR_PRINT_SPEW", false)
+DEBUG_GET_ONCE_BOOL_OPTION(print_debug, "XRT_COMPOSITOR_PRINT_DEBUG", false)
+DEBUG_GET_ONCE_BOOL_OPTION(force_direct, "XRT_COMPOSITOR_FORCE_DIRECT", false)
+DEBUG_GET_ONCE_BOOL_OPTION(force_xcb, "XRT_COMPOSITOR_FORCE_XCB", false)
+DEBUG_GET_ONCE_BOOL_OPTION(force_wayland, "XRT_COMPOSITOR_FORCE_WAYLAND", false)
+
+void
+comp_settings_init(struct comp_settings *s, struct xrt_device *xdev)
+{
+ s->display = -1;
+ s->mode = -1;
+ s->color_format = VK_FORMAT_B8G8R8A8_UNORM;
+ s->color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
+ s->present_mode = VK_PRESENT_MODE_FIFO_KHR;
+ s->window_type = WINDOW_AUTO;
+ s->fullscreen = false;
+ s->flip_y = false;
+ s->distortion_model = xdev->distortion.preferred;
+ s->width = xdev->screens[0].w_pixels;
+ s->height = xdev->screens[0].h_pixels;
+ s->print_spew = debug_get_bool_option_print_spew();
+ s->print_debug = debug_get_bool_option_print_debug();
+
+ if (debug_get_bool_option_force_direct()) {
+ s->window_type = WINDOW_DIRECT_MODE;
+ }
+ if (debug_get_bool_option_force_xcb()) {
+ s->window_type = WINDOW_XCB;
+ // HMD screen tends to be much larger then monitors.
+ s->width /= 2;
+ s->height /= 2;
+ }
+ if (debug_get_bool_option_force_wayland()) {
+ s->window_type = WINDOW_WAYLAND;
+ // HMD screen tends to be much larger then monitors.
+ s->width /= 2;
+ s->height /= 2;
+ }
+}
diff --git a/src/xrt/compositor/main/comp_settings.h b/src/xrt/compositor/main/comp_settings.h
new file mode 100644
index 000000000..97c491ecd
--- /dev/null
+++ b/src/xrt/compositor/main/comp_settings.h
@@ -0,0 +1,83 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Settings struct for compositor header.
+ * @author Lubosz Sarnecki
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#pragma once
+
+#include "xrt/xrt_device.h"
+#include "xrt/xrt_compositor.h"
+#include "xrt/xrt_vulkan_includes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*!
+ * Window type to use.
+ *
+ * @ingroup comp
+ */
+enum window_type
+{
+ WINDOW_NONE = 0,
+ WINDOW_AUTO,
+ WINDOW_XCB,
+ WINDOW_WAYLAND,
+ WINDOW_DIRECT_MODE,
+};
+
+/*!
+ * Settings for the compositor.
+ *
+ * @ingroup comp
+ */
+struct comp_settings
+{
+ int display;
+ int mode;
+
+ VkFormat color_format;
+ VkColorSpaceKHR color_space;
+ VkPresentModeKHR present_mode;
+
+ //! Window type to use.
+ enum window_type window_type;
+
+ //! Distortion type to use.
+ enum xrt_distortion_model distortion_model;
+
+ uint32_t width;
+ uint32_t height;
+
+ //! Not used with direct mode.
+ bool fullscreen;
+
+ //! Should we debug print a lot!
+ bool print_spew;
+
+ //! Should we debug print.
+ bool print_debug;
+
+ //! Should we flip y axis for compositor buffers (for GL)
+ bool flip_y;
+};
+
+/*!
+ * Initialize the settings struct with either defaults or loaded setting.
+ *
+ * @ingroup comp
+ */
+void
+comp_settings_init(struct comp_settings *s, struct xrt_device *xdev);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/compositor/main/comp_swapchain.c b/src/xrt/compositor/main/comp_swapchain.c
new file mode 100644
index 000000000..523efcaf1
--- /dev/null
+++ b/src/xrt/compositor/main/comp_swapchain.c
@@ -0,0 +1,303 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Swapchain code for the main compositor.
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#include
+#include
+
+#include "main/comp_compositor.h"
+
+
+static void
+swapchain_destroy(struct xrt_swapchain *xsc)
+{
+ struct comp_swapchain *sc = comp_swapchain(xsc);
+ struct vk_bundle *vk = &sc->c->vk;
+
+ COMP_SPEW(sc->c, "DESTROY");
+
+ for (uint32_t i = 0; i < sc->base.base.num_images; i++) {
+ comp_swapchain_image_cleanup(vk, &sc->images[i]);
+ }
+
+ free(sc);
+}
+
+static bool
+swapchain_acquire_image(struct xrt_swapchain *xsc, uint32_t *index)
+{
+ struct comp_swapchain *sc = comp_swapchain(xsc);
+
+ COMP_SPEW(sc->c, "ACQUIRE_IMAGE");
+ *index = 0;
+ return true;
+}
+
+static bool
+swapchain_wait_image(struct xrt_swapchain *xsc,
+ uint64_t timeout,
+ uint32_t index)
+{
+ struct comp_swapchain *sc = comp_swapchain(xsc);
+
+ COMP_SPEW(sc->c, "WAIT_IMAGE");
+ return true;
+}
+
+static bool
+swapchain_release_image(struct xrt_swapchain *xsc, uint32_t index)
+{
+ struct comp_swapchain *sc = comp_swapchain(xsc);
+
+ COMP_SPEW(sc->c, "RELEASE_IMAGE");
+ return true;
+}
+
+static VkResult
+create_image_fd(struct comp_compositor *c,
+ int64_t format,
+ uint32_t width,
+ uint32_t height,
+ uint32_t mip_count,
+ VkImage *out_image,
+ VkDeviceMemory *out_mem,
+ struct xrt_image_fd *out_image_fd)
+{
+ VkMemoryRequirements memory_requirements;
+ VkImageUsageFlagBits image_usage = 0;
+ VkDeviceMemory device_memory = NULL;
+ uint32_t memory_type_index = UINT32_MAX;
+ VkImage image = NULL;
+ VkResult ret;
+ size_t size;
+ int fd;
+
+ COMP_SPEW(c, "->image - vkCreateImage %dx%d", width, height);
+
+
+ /*
+ * Create the image.
+ */
+
+ VkExternalMemoryImageCreateInfoKHR external_memory_image_create_info = {
+ .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR,
+ .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
+ };
+
+ image_usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
+ image_usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+ image_usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+
+ VkImageCreateInfo info = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+ .pNext = &external_memory_image_create_info,
+ .imageType = VK_IMAGE_TYPE_2D,
+ .format = format,
+ .extent = {.width = width, .height = height, .depth = 1},
+ .mipLevels = mip_count,
+ .arrayLayers = 1,
+ .samples = VK_SAMPLE_COUNT_1_BIT,
+ .tiling = VK_IMAGE_TILING_OPTIMAL,
+ .usage = image_usage,
+ .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
+ .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
+ };
+
+ ret = c->vk.vkCreateImage(c->vk.device, &info, NULL, &image);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(c, "->image - vkCreateImage: %s",
+ vk_result_string(ret));
+ goto err;
+ }
+
+
+ /*
+ * Get the size of the buffer.
+ */
+
+ c->vk.vkGetImageMemoryRequirements(c->vk.device, image,
+ &memory_requirements);
+ size = memory_requirements.size;
+
+ if (!vk_get_memory_type(&c->vk, memory_requirements.memoryTypeBits,
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+ &memory_type_index)) {
+ COMP_ERROR(c, "->image - _get_memory_type!");
+ ret = VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ goto err_image;
+ }
+
+ /*
+ * Create the memory.
+ */
+
+ VkMemoryDedicatedAllocateInfoKHR dedicated_memory_info = {
+ .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
+ .pNext = NULL,
+ .image = image,
+ .buffer = VK_NULL_HANDLE,
+ };
+
+ VkExportMemoryAllocateInfo export_alloc_info = {
+ .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
+ .pNext = &dedicated_memory_info,
+ .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
+ };
+
+ VkMemoryAllocateInfo alloc_info = {
+ .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+ .pNext = &export_alloc_info,
+ .allocationSize = size,
+ .memoryTypeIndex = memory_type_index,
+ };
+
+ ret = c->vk.vkAllocateMemory(c->vk.device, &alloc_info, NULL,
+ &device_memory);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(c, "->image - vkAllocateMemory: %s",
+ vk_result_string(ret));
+ goto err_image;
+ }
+
+ ret = c->vk.vkBindImageMemory(c->vk.device, image, device_memory, 0);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(c, "->image - vkBindImageMemory: %s",
+ vk_result_string(ret));
+ goto err_mem;
+ }
+
+
+ /*
+ * Get the fd.
+ */
+
+ VkMemoryGetFdInfoKHR fd_info = {
+ .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
+ .memory = device_memory,
+ .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
+ };
+
+ ret = c->vk.vkGetMemoryFdKHR(c->vk.device, &fd_info, &fd);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(c, "->image - vkGetMemoryFdKHR: %s",
+ vk_result_string(ret));
+ ret = VK_ERROR_FEATURE_NOT_PRESENT;
+ goto err_mem;
+ }
+
+ *out_image = image;
+ *out_mem = device_memory;
+ out_image_fd->fd = fd;
+ out_image_fd->size = size;
+
+ return ret;
+
+err_mem:
+ c->vk.vkFreeMemory(c->vk.device, device_memory, NULL);
+err_image:
+ c->vk.vkDestroyImage(c->vk.device, image, NULL);
+err:
+ return ret;
+}
+
+struct xrt_swapchain *
+comp_swapchain_create(struct xrt_compositor *xc,
+ enum xrt_swapchain_create_flags create,
+ enum xrt_swapchain_usage_bits bits,
+ int64_t format,
+ uint32_t sample_count,
+ uint32_t width,
+ uint32_t height,
+ uint32_t face_count,
+ uint32_t array_size,
+ uint32_t mip_count)
+{
+ struct comp_compositor *c = comp_compositor(xc);
+ VkCommandBuffer cmd_buffer;
+ uint32_t num_images = 3;
+ VkResult ret;
+
+
+ struct comp_swapchain *sc = calloc(1, sizeof(struct comp_swapchain));
+ sc->base.base.destroy = swapchain_destroy;
+ sc->base.base.acquire_image = swapchain_acquire_image;
+ sc->base.base.wait_image = swapchain_wait_image;
+ sc->base.base.release_image = swapchain_release_image;
+ sc->base.base.num_images = num_images;
+ sc->c = c;
+
+ COMP_DEBUG(c, "CREATE %p %dx%d", (void *)sc, width, height);
+
+ for (uint32_t i = 0; i < num_images; i++) {
+ ret = create_image_fd(
+ c, format, width, height, mip_count, &sc->images[i].image,
+ &sc->images[i].memory, &sc->base.images[i]);
+ if (ret != VK_SUCCESS) {
+ return NULL;
+ }
+
+ vk_create_sampler(&c->vk, &sc->images[i].sampler);
+
+ vk_create_view(&c->vk, sc->images[i].image, format,
+ &sc->images[i].view);
+ }
+
+
+ /*
+ *
+ * Transition image.
+ *
+ */
+
+ vk_init_cmd_buffer(&c->vk, &cmd_buffer);
+
+ VkImageSubresourceRange subresource_range = {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .baseMipLevel = 0,
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ .layerCount = 1,
+ };
+
+ for (uint32_t i = 0; i < num_images; i++) {
+ vk_set_image_layout(&c->vk, cmd_buffer, sc->images[i].image, 0,
+ VK_ACCESS_SHADER_READ_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ subresource_range);
+ }
+
+ vk_submit_cmd_buffer(&c->vk, cmd_buffer);
+
+ return &sc->base.base;
+}
+
+void
+comp_swapchain_image_cleanup(struct vk_bundle *vk,
+ struct comp_swapchain_image *image)
+{
+ if (image->view != NULL) {
+ vk->vkDestroyImageView(vk->device, image->view, NULL);
+ image->view = NULL;
+ }
+
+ if (image->sampler != NULL) {
+ vk->vkDestroySampler(vk->device, image->sampler, NULL);
+ image->sampler = NULL;
+ }
+
+ if (image->image != NULL) {
+ vk->vkDestroyImage(vk->device, image->image, NULL);
+ image->image = NULL;
+ }
+
+ if (image->memory != NULL) {
+ vk->vkFreeMemory(vk->device, image->memory, NULL);
+ image->memory = NULL;
+ }
+}
diff --git a/src/xrt/compositor/main/comp_window.h b/src/xrt/compositor/main/comp_window.h
new file mode 100644
index 000000000..0afdb2197
--- /dev/null
+++ b/src/xrt/compositor/main/comp_window.h
@@ -0,0 +1,92 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Compositor window header.
+ * @author Lubosz Sarnecki
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#pragma once
+
+#include "common/comp_vk_swapchain.h"
+#include "main/comp_compositor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ *
+ * Structs
+ *
+ */
+
+/*!
+ * A output device or a window, often directly connected to the device.
+ *
+ * @ingroup comp
+ */
+struct comp_window
+{
+ //! Owning compositor.
+ struct comp_compositor *c;
+
+ //! Name of the window system.
+ const char *name;
+
+ //! Helper struct.
+ struct vk_swapchain swapchain;
+
+ void (*destroy)(struct comp_window *w);
+ void (*flush)(struct comp_window *w);
+ bool (*init)(struct comp_window *w);
+ bool (*init_swapchain)(struct comp_window *w,
+ uint32_t width,
+ uint32_t height);
+ void (*update_window_title)(struct comp_window *w, const char *title);
+};
+
+
+/*
+ *
+ * Functions.
+ *
+ */
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+/*!
+ * Create a xcb window.
+ *
+ * @ingroup comp
+ */
+struct comp_window *
+comp_window_xcb_create(struct comp_compositor *c);
+#endif
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+/*!
+ * Create a wayland window.
+ *
+ * @ingroup comp
+ */
+struct comp_window *
+comp_window_wayland_create(struct comp_compositor *c);
+#endif
+
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+/*!
+ * Create a direct surface to a HMD.
+ *
+ * @ingroup comp
+ */
+struct comp_window *
+comp_window_direct_create(struct comp_compositor *c);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/compositor/main/comp_window_direct_mode.cpp b/src/xrt/compositor/main/comp_window_direct_mode.cpp
new file mode 100644
index 000000000..833c27334
--- /dev/null
+++ b/src/xrt/compositor/main/comp_window_direct_mode.cpp
@@ -0,0 +1,648 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Direct mode window code.
+ * @author Lubosz Sarnecki
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "xrt/xrt_compiler.h"
+#include "main/comp_window.h"
+
+
+/*
+ *
+ * Private structs
+ *
+ */
+
+/*!
+ * Probed display.
+ */
+struct comp_window_direct_display
+{
+ std::string name;
+ xcb_randr_output_t output;
+ xcb_randr_mode_info_t primary_mode;
+ VkDisplayKHR display;
+};
+
+/*!
+ * Direct mode "window" into a device, using Vulkan direct mode extension
+ * and xcb.
+ */
+struct comp_window_direct
+{
+ struct comp_window base = comp_window();
+
+ Display* dpy = nullptr;
+ xcb_connection_t* connection = nullptr;
+ xcb_screen_t* screen = nullptr;
+
+ std::map modes = {};
+
+ std::vector displays = {};
+};
+
+
+/*
+ *
+ * Pre decalre functions
+ *
+ */
+
+static void
+comp_window_direct_destroy(struct comp_window* w);
+
+XRT_MAYBE_UNUSED static void
+comp_window_direct_list_screens(struct comp_window_direct* w);
+
+static bool
+comp_window_direct_init(struct comp_window* w);
+
+static comp_window_direct_display*
+comp_window_direct_current_display(struct comp_window_direct* w);
+
+static void
+comp_window_direct_flush(struct comp_window* w);
+
+static VkDisplayModeKHR
+comp_window_direct_get_primary_display_mode(struct comp_window_direct* w,
+ VkDisplayKHR display);
+
+static VkDisplayPlaneAlphaFlagBitsKHR
+choose_alpha_mode(VkDisplayPlaneAlphaFlagsKHR flags);
+
+static VkResult
+comp_window_direct_create_surface(struct comp_window_direct* w,
+ VkInstance instance,
+ VkSurfaceKHR* surface,
+ uint32_t width,
+ uint32_t height);
+
+static bool
+comp_window_direct_init_swapchain(struct comp_window* w,
+ uint32_t width,
+ uint32_t height);
+
+static int
+comp_window_direct_connect(struct comp_window_direct* w);
+
+static void
+comp_window_direct_aquire_xlib_display(struct comp_window_direct* w,
+ VkDisplayKHR display);
+
+static VkDisplayKHR
+comp_window_direct_get_xlib_randr_output(struct comp_window_direct* w,
+ RROutput output);
+
+static void
+comp_window_direct_enumerate_modes(
+ struct comp_window_direct* w,
+ xcb_randr_get_screen_resources_reply_t* resources_reply);
+
+static void
+comp_window_direct_get_randr_outputs(struct comp_window_direct* w);
+
+static void
+comp_window_direct_update_window_title(struct comp_window* w,
+ const char* title);
+
+
+/*
+ *
+ * Functions.
+ *
+ */
+
+extern "C" struct comp_window*
+comp_window_direct_create(struct comp_compositor* c)
+{
+ auto w = new comp_window_direct();
+
+ w->base.name = "direct";
+ w->base.destroy = comp_window_direct_destroy;
+ w->base.flush = comp_window_direct_flush;
+ w->base.init = comp_window_direct_init;
+ w->base.init_swapchain = comp_window_direct_init_swapchain;
+ w->base.update_window_title = comp_window_direct_update_window_title;
+ w->base.c = c;
+ w->modes.clear();
+
+ return &w->base;
+}
+
+static void
+comp_window_direct_destroy(struct comp_window* w)
+{
+ comp_window_direct* w_direct = (comp_window_direct*)w;
+ vk_bundle* vk = &w->c->vk;
+
+ for (uint32_t i = 0; i < w_direct->displays.size(); i++) {
+ comp_window_direct_display* d = &w_direct->displays[i];
+
+ if (d->display == VK_NULL_HANDLE) {
+ continue;
+ }
+
+ vk->vkReleaseDisplayEXT(vk->physical_device, d->display);
+ d->display = VK_NULL_HANDLE;
+ }
+
+ if (w_direct->connection) {
+ xcb_disconnect(w_direct->connection);
+ w_direct->connection = nullptr;
+ }
+
+ delete w;
+}
+
+static void
+comp_window_direct_list_screens(struct comp_window_direct* w)
+{
+ int display_i = 0;
+ for (comp_window_direct_display d : w->displays) {
+ COMP_DEBUG(w->base.c, "%d: %s %dx%d@%.2f", display_i,
+ d.name.c_str(), d.primary_mode.width,
+ d.primary_mode.height,
+ (double)d.primary_mode.dot_clock /
+ (d.primary_mode.htotal * d.primary_mode.vtotal));
+ display_i++;
+ }
+}
+
+static bool
+comp_window_direct_init(struct comp_window* w)
+{
+ comp_window_direct* w_direct = (comp_window_direct*)w;
+
+ if (!comp_window_direct_connect(w_direct)) {
+ return false;
+ }
+
+ xcb_screen_iterator_t iter =
+ xcb_setup_roots_iterator(xcb_get_setup(w_direct->connection));
+
+ w_direct->screen = iter.data;
+
+ comp_window_direct_get_randr_outputs(w_direct);
+
+ if (w_direct->displays.size() < 1) {
+ COMP_ERROR(w->c, "No non-desktop output available.");
+ return false;
+ }
+
+ if (w->c->settings.display > (int)w_direct->displays.size() - 1) {
+ COMP_DEBUG(w->c,
+ "Requested display %d, but only %d displays are "
+ "available.",
+ w->c->settings.display,
+ (int)w_direct->displays.size());
+
+ w->c->settings.display = 0;
+ comp_window_direct_display* d =
+ comp_window_direct_current_display(w_direct);
+ COMP_DEBUG(w->c, "Selecting '%s' instead.", d->name.c_str());
+ }
+
+ if (w->c->settings.display < 0) {
+ w->c->settings.display = 0;
+ comp_window_direct_display* d =
+ comp_window_direct_current_display(w_direct);
+ COMP_DEBUG(w->c, "Selecting '%s' first display.",
+ d->name.c_str());
+ }
+
+ comp_window_direct_display* d =
+ comp_window_direct_current_display(w_direct);
+ w->c->settings.width = d->primary_mode.width;
+ w->c->settings.height = d->primary_mode.height;
+ // TODO: size callback
+ // set_size_cb(settings->width, settings->height);
+
+ return true;
+}
+
+static comp_window_direct_display*
+comp_window_direct_current_display(struct comp_window_direct* w)
+{
+ uint32_t index = w->base.c->settings.display;
+ if (index == (uint32_t)-1) {
+ index = 0;
+ }
+
+ if (w->displays.size() <= index) {
+ return nullptr;
+ }
+
+ return &w->displays[index];
+}
+
+static void
+comp_window_direct_flush(struct comp_window* w)
+{}
+
+static VkDisplayModeKHR
+comp_window_direct_get_primary_display_mode(struct comp_window_direct* w,
+ VkDisplayKHR display)
+{
+ struct vk_bundle* vk = w->base.swapchain.vk;
+ uint32_t mode_count;
+ VkResult ret;
+
+ ret = vk->vkGetDisplayModePropertiesKHR(
+ w->base.swapchain.vk->physical_device, display, &mode_count,
+ nullptr);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(w->base.c, "vkGetDisplayModePropertiesKHR: %s",
+ vk_result_string(ret));
+ return nullptr;
+ }
+
+ COMP_DEBUG(w->base.c, "Found %d modes", mode_count);
+
+ VkDisplayModePropertiesKHR* mode_properties;
+ mode_properties = new VkDisplayModePropertiesKHR[mode_count];
+ ret = vk->vkGetDisplayModePropertiesKHR(
+ w->base.swapchain.vk->physical_device, display, &mode_count,
+ mode_properties);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(w->base.c, "vkGetDisplayModePropertiesKHR: %s",
+ vk_result_string(ret));
+ delete[] mode_properties;
+ return nullptr;
+ }
+
+ VkDisplayModePropertiesKHR props = mode_properties[0];
+
+ COMP_DEBUG(w->base.c, "found display mode %d %d",
+ props.parameters.visibleRegion.width,
+ props.parameters.visibleRegion.height);
+
+ delete[] mode_properties;
+
+ return props.displayMode;
+}
+
+static VkDisplayPlaneAlphaFlagBitsKHR
+choose_alpha_mode(VkDisplayPlaneAlphaFlagsKHR flags)
+{
+ if (flags & VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR) {
+ return VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR;
+ } else if (flags & VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR) {
+ return VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR;
+ } else {
+ return VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR;
+ }
+}
+
+static VkResult
+comp_window_direct_create_surface(struct comp_window_direct* w,
+ VkInstance instance,
+ VkSurfaceKHR* surface,
+ uint32_t width,
+ uint32_t height)
+{
+ comp_window_direct_display* d = comp_window_direct_current_display(w);
+ struct vk_bundle* vk = w->base.swapchain.vk;
+ VkResult ret;
+
+ COMP_DEBUG(w->base.c, "Will use display: %s %dx%d@%.2f",
+ d->name.c_str(), d->primary_mode.width,
+ d->primary_mode.height,
+ (double)d->primary_mode.dot_clock /
+ (d->primary_mode.htotal * d->primary_mode.vtotal));
+
+ d->display = comp_window_direct_get_xlib_randr_output(w, d->output);
+ if (d->display == VK_NULL_HANDLE) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ comp_window_direct_aquire_xlib_display(w, d->display);
+
+
+ // Get plane properties
+ uint32_t plane_property_count;
+ ret = vk->vkGetPhysicalDeviceDisplayPlanePropertiesKHR(
+ w->base.swapchain.vk->physical_device, &plane_property_count,
+ nullptr);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(w->base.c,
+ "vkGetPhysicalDeviceDisplayPlanePropertiesKHR: %s",
+ vk_result_string(ret));
+ return ret;
+ }
+
+ COMP_DEBUG(w->base.c, "Found %d plane properites.",
+ plane_property_count);
+
+ VkDisplayPlanePropertiesKHR* plane_properties =
+ new VkDisplayPlanePropertiesKHR[plane_property_count];
+
+ ret = vk->vkGetPhysicalDeviceDisplayPlanePropertiesKHR(
+ w->base.swapchain.vk->physical_device, &plane_property_count,
+ plane_properties);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(w->base.c,
+ "vkGetPhysicalDeviceDisplayPlanePropertiesKHR: %s",
+ vk_result_string(ret));
+ delete[] plane_properties;
+ return ret;
+ }
+
+ uint32_t plane_index = 0;
+
+ VkDisplayModeKHR display_mode =
+ comp_window_direct_get_primary_display_mode(w, d->display);
+
+ VkDisplayPlaneCapabilitiesKHR plane_caps;
+ vk->vkGetDisplayPlaneCapabilitiesKHR(
+ w->base.swapchain.vk->physical_device, display_mode, plane_index,
+ &plane_caps);
+
+ VkDisplaySurfaceCreateInfoKHR surface_info = {
+ .sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR,
+ .pNext = nullptr,
+ .flags = 0,
+ .displayMode = display_mode,
+ .planeIndex = plane_index,
+ .planeStackIndex = plane_properties[plane_index].currentStackIndex,
+ .transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
+ .globalAlpha = 1.0,
+ .alphaMode = choose_alpha_mode(plane_caps.supportedAlpha),
+ .imageExtent =
+ {
+ .width = width,
+ .height = height,
+ },
+ };
+
+ VkResult result = vk->vkCreateDisplayPlaneSurfaceKHR(
+ instance, &surface_info, nullptr, surface);
+
+ delete[] plane_properties;
+
+ return result;
+}
+
+static bool
+comp_window_direct_init_swapchain(struct comp_window* w,
+ uint32_t width,
+ uint32_t height)
+{
+ comp_window_direct* w_direct = (comp_window_direct*)w;
+ VkResult ret;
+
+
+ ret = comp_window_direct_create_surface(
+ w_direct, w->swapchain.vk->instance, &w->swapchain.surface, width,
+ height);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(w->c, "Failed to create surface!");
+ return false;
+ }
+
+ vk_swapchain_create(
+ &w->swapchain, width, height, w->c->settings.color_format,
+ w->c->settings.color_space, w->c->settings.present_mode);
+
+ return true;
+}
+
+static int
+comp_window_direct_connect(struct comp_window_direct* w)
+{
+ w->dpy = XOpenDisplay(nullptr);
+ if (w->dpy == nullptr) {
+ COMP_ERROR(w->base.c, "Could not open X display.");
+ return false;
+ }
+
+ //! @todo only open one connection and use XGetXCBConnection.
+ w->connection = xcb_connect(nullptr, nullptr);
+ return !xcb_connection_has_error(w->connection);
+}
+
+static void
+comp_window_direct_aquire_xlib_display(struct comp_window_direct* w,
+ VkDisplayKHR display)
+{
+ struct vk_bundle* vk = w->base.swapchain.vk;
+ VkResult ret;
+
+ ret = vk->vkAcquireXlibDisplayEXT(w->base.swapchain.vk->physical_device,
+ w->dpy, display);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(w->base.c, "vkAcquireXlibDisplayEXT: %s (%p)",
+ vk_result_string(ret), (void*)display);
+ }
+}
+
+static VkDisplayKHR
+comp_window_direct_get_xlib_randr_output(struct comp_window_direct* w,
+ RROutput output)
+{
+ struct vk_bundle* vk = w->base.swapchain.vk;
+ VkResult ret;
+
+ VkDisplayKHR display;
+ ret = vk->vkGetRandROutputDisplayEXT(
+ w->base.swapchain.vk->physical_device, w->dpy, output, &display);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(w->base.c, "vkGetRandROutputDisplayEXT: %s",
+ vk_result_string(ret));
+ return nullptr;
+ }
+
+ if (display == VK_NULL_HANDLE) {
+ COMP_DEBUG(w->base.c,
+ "vkGetRandROutputDisplayEXT"
+ " returned a null display! %p",
+ display);
+ return VK_NULL_HANDLE;
+ }
+
+ return display;
+}
+
+static void
+comp_window_direct_enumerate_modes(
+ struct comp_window_direct* w,
+ xcb_randr_get_screen_resources_reply_t* resources_reply)
+{
+ xcb_randr_mode_info_t* mode_infos =
+ xcb_randr_get_screen_resources_modes(resources_reply);
+
+ int n = xcb_randr_get_screen_resources_modes_length(resources_reply);
+ for (int i = 0; i < n; i++)
+ w->modes.insert(std::pair(
+ mode_infos[i].id, mode_infos[i]));
+}
+
+static void
+comp_window_direct_get_randr_outputs(struct comp_window_direct* w)
+{
+ xcb_randr_query_version_cookie_t version_cookie =
+ xcb_randr_query_version(w->connection, XCB_RANDR_MAJOR_VERSION,
+ XCB_RANDR_MINOR_VERSION);
+ xcb_randr_query_version_reply_t* version_reply =
+ xcb_randr_query_version_reply(w->connection, version_cookie, NULL);
+
+ if (!version_reply) {
+ COMP_ERROR(w->base.c, "Could not get RandR version.");
+ return;
+ }
+
+ COMP_DEBUG(w->base.c, "RandR version %d.%d",
+ version_reply->major_version, version_reply->minor_version);
+
+ if (version_reply->major_version < 1 ||
+ version_reply->minor_version < 6) {
+ COMP_DEBUG(w->base.c, "RandR version below 1.6.");
+ }
+
+ xcb_generic_error_t* error = nullptr;
+ xcb_intern_atom_cookie_t non_desktop_cookie = xcb_intern_atom(
+ w->connection, 1, strlen("non-desktop"), "non-desktop");
+ xcb_intern_atom_reply_t* non_desktop_reply =
+ xcb_intern_atom_reply(w->connection, non_desktop_cookie, &error);
+
+ if (error != nullptr) {
+ COMP_ERROR(w->base.c, "xcb_intern_atom_reply returned error %d",
+ error->error_code);
+ return;
+ }
+
+ if (non_desktop_reply == nullptr) {
+ COMP_ERROR(w->base.c, "non-desktop reply nullptr");
+ return;
+ }
+
+ if (non_desktop_reply->atom == XCB_NONE) {
+ COMP_ERROR(w->base.c, "No output has non-desktop property");
+ return;
+ }
+
+ xcb_randr_get_screen_resources_cookie_t resources_cookie =
+ xcb_randr_get_screen_resources(w->connection, w->screen->root);
+ xcb_randr_get_screen_resources_reply_t* resources_reply =
+ xcb_randr_get_screen_resources_reply(w->connection,
+ resources_cookie, nullptr);
+ xcb_randr_output_t* xcb_outputs =
+ xcb_randr_get_screen_resources_outputs(resources_reply);
+
+ comp_window_direct_enumerate_modes(w, resources_reply);
+
+ int count =
+ xcb_randr_get_screen_resources_outputs_length(resources_reply);
+ if (count < 1) {
+ COMP_ERROR(w->base.c, "failed to retrieve randr outputs");
+ }
+
+ for (int i = 0; i < count; i++) {
+ xcb_randr_get_output_info_cookie_t output_cookie =
+ xcb_randr_get_output_info(w->connection, xcb_outputs[i],
+ XCB_CURRENT_TIME);
+ xcb_randr_get_output_info_reply_t* output_reply =
+ xcb_randr_get_output_info_reply(w->connection,
+ output_cookie, nullptr);
+
+ // Only outputs with an available mode should be used
+ // (it is possible to see 'ghost' outputs with non-desktop=1).
+ if (output_reply->num_modes == 0) {
+ continue;
+ }
+
+ uint8_t* name = xcb_randr_get_output_info_name(output_reply);
+ int name_len =
+ xcb_randr_get_output_info_name_length(output_reply);
+
+ char* name_str = (char*)malloc(name_len + 1);
+ memcpy(name_str, name, name_len);
+ name_str[name_len] = '\0';
+
+ // Find the first output that has the non-desktop property set.
+ xcb_randr_get_output_property_cookie_t prop_cookie;
+ prop_cookie = xcb_randr_get_output_property(
+ w->connection, xcb_outputs[i], non_desktop_reply->atom,
+ XCB_ATOM_NONE, 0, 4, 0, 0);
+ xcb_randr_get_output_property_reply_t* prop_reply = nullptr;
+ prop_reply = xcb_randr_get_output_property_reply(
+ w->connection, prop_cookie, &error);
+ if (error != nullptr) {
+ COMP_ERROR(w->base.c,
+ "xcb_randr_get_output_property_reply "
+ "returned error %d",
+ error->error_code);
+ free(name_str);
+ continue;
+ }
+
+ if (prop_reply == nullptr) {
+ COMP_ERROR(w->base.c, "property reply == nullptr");
+ free(name_str);
+ continue;
+ }
+
+ if (prop_reply->type != XCB_ATOM_INTEGER ||
+ prop_reply->num_items != 1 || prop_reply->format != 32) {
+ COMP_ERROR(w->base.c, "Invalid non-desktop reply");
+ free(name_str);
+ continue;
+ }
+
+ uint8_t non_desktop =
+ *xcb_randr_get_output_property_data(prop_reply);
+ if (non_desktop == 1) {
+ xcb_randr_mode_t* output_modes =
+ xcb_randr_get_output_info_modes(output_reply);
+
+ int num_modes = xcb_randr_get_output_info_modes_length(
+ output_reply);
+ if (num_modes == 0) {
+ COMP_ERROR(w->base.c,
+ "%s does not have any modes "
+ "available. "
+ "Check `xrandr --prop`.",
+ name_str);
+ }
+
+ if (!w->modes.count(output_modes[0])) {
+ COMP_ERROR(w->base.c,
+ "No mode with id %d found??",
+ output_modes[0]);
+ }
+
+ comp_window_direct_display d = {
+ .name = std::string(name_str),
+ .output = xcb_outputs[i],
+ .primary_mode = w->modes.at(output_modes[0]),
+ .display = VK_NULL_HANDLE,
+ };
+
+ w->displays.push_back(d);
+ }
+
+ free(name_str);
+ }
+}
+
+static void
+comp_window_direct_update_window_title(struct comp_window* w, const char* title)
+{}
+
+#endif
diff --git a/src/xrt/compositor/main/comp_window_wayland.cpp b/src/xrt/compositor/main/comp_window_wayland.cpp
new file mode 100644
index 000000000..6c4e3b4d1
--- /dev/null
+++ b/src/xrt/compositor/main/comp_window_wayland.cpp
@@ -0,0 +1,629 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Wayland window code.
+ * @author Lubosz Sarnecki
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+
+#include
+#include
+#include
+#include "xdg-shell-unstable-v6.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include "xrt/xrt_compiler.h"
+#include "main/comp_window.h"
+
+
+/*
+ *
+ * Private structs.
+ *
+ */
+
+/*!
+ * Wayland display mode.
+ */
+struct comp_window_wayland_mode
+{
+ std::pair size;
+ int refresh;
+};
+
+/*!
+ * A single Wayland display.
+ */
+struct comp_window_wayland_display
+{
+ wl_output *output;
+ std::string make;
+ std::string model;
+ std::vector modes;
+ std::pair physical_size_mm;
+ std::pair position;
+};
+
+/*!
+ * A Wayland connection and window.
+ */
+struct comp_window_wayland
+{
+ struct comp_window base = comp_window();
+
+ wl_display *display = nullptr;
+ wl_compositor *compositor = nullptr;
+ wl_surface *surface = nullptr;
+
+ zxdg_shell_v6 *shell = nullptr;
+ zxdg_surface_v6 *xdg_surface = nullptr;
+ zxdg_toplevel_v6 *xdg_toplevel = nullptr;
+
+ std::vector displays = {};
+
+ bool is_configured = false;
+ bool first_configure = true;
+ bool fullscreen_requested = false;
+};
+
+
+/*
+ *
+ * Pre declare functions.
+ *
+ */
+
+static void
+comp_window_wayland_destroy(struct comp_window *w);
+
+static bool
+comp_window_wayland_init(struct comp_window *w);
+
+static void
+comp_window_wayland_update_window_title(struct comp_window *w,
+ const char *title);
+
+static void
+comp_window_wayland_registry_global(struct comp_window_wayland *w,
+ wl_registry *registry,
+ uint32_t name,
+ const char *interface);
+
+static void
+comp_window_wayland_fullscreen(struct comp_window_wayland *w);
+
+static void
+comp_window_wayland_fullscreen(struct comp_window_wayland *w,
+ wl_output *output);
+
+static bool
+comp_window_wayland_init_swapchain(struct comp_window *w,
+ uint32_t width,
+ uint32_t height);
+
+static VkResult
+comp_window_wayland_create_surface(struct comp_window_wayland *w,
+ VkSurfaceKHR *vk_surface);
+
+static void
+comp_window_wayland_flush(struct comp_window *w);
+
+static void
+comp_window_wayland_output_mode(struct comp_window_wayland *w,
+ wl_output *output,
+ unsigned int flags,
+ int width,
+ int height,
+ int refresh);
+
+static comp_window_wayland_display *
+comp_window_wayland_get_display_from_output(struct comp_window_wayland *w,
+ wl_output *output);
+
+XRT_MAYBE_UNUSED static void
+comp_window_wayland_print_displays(struct comp_window_wayland *w);
+
+static comp_window_wayland_display *
+comp_window_wayland_current_display(struct comp_window_wayland *w);
+
+static comp_window_wayland_mode *
+comp_window_wayland_current_mode(struct comp_window_wayland *w);
+
+static std::string
+mode_to_string(comp_window_wayland_mode *m);
+
+static void
+comp_window_wayland_validate_display(struct comp_window_wayland *w);
+
+static void
+validate_mode(struct comp_window_wayland *w);
+
+static void
+comp_window_wayland_configure(struct comp_window_wayland *w,
+ int32_t width,
+ int32_t height);
+
+
+/*
+ *
+ * Functions.
+ *
+ */
+
+extern "C" struct comp_window *
+comp_window_wayland_create(struct comp_compositor *c)
+{
+ auto w = new comp_window_wayland();
+
+ w->base.name = "wayland";
+ w->base.destroy = comp_window_wayland_destroy;
+ w->base.flush = comp_window_wayland_flush;
+ w->base.init = comp_window_wayland_init;
+ w->base.init_swapchain = comp_window_wayland_init_swapchain;
+ w->base.update_window_title = comp_window_wayland_update_window_title;
+ w->base.c = c;
+
+ return &w->base;
+}
+
+static void
+comp_window_wayland_destroy(struct comp_window *w)
+{
+ struct comp_window_wayland *w_wayland = (struct comp_window_wayland *)w;
+
+ if (w_wayland->surface) {
+ wl_surface_destroy(w_wayland->surface);
+ w_wayland->surface = nullptr;
+ }
+ if (w_wayland->compositor) {
+ wl_compositor_destroy(w_wayland->compositor);
+ w_wayland->compositor = nullptr;
+ }
+ if (w_wayland->display) {
+ wl_display_disconnect(w_wayland->display);
+ w_wayland->display = nullptr;
+ }
+
+ delete w;
+}
+
+static void
+comp_window_wayland_update_window_title(struct comp_window *w,
+ const char *title)
+{
+ struct comp_window_wayland *w_wayland = (struct comp_window_wayland *)w;
+ zxdg_toplevel_v6_set_title(w_wayland->xdg_toplevel, title);
+}
+
+static void
+comp_window_wayland_fullscreen(struct comp_window_wayland *w)
+{
+ comp_window_wayland_fullscreen(
+ w, comp_window_wayland_current_display(w)->output);
+}
+
+static void
+comp_window_wayland_fullscreen(struct comp_window_wayland *w, wl_output *output)
+{
+ zxdg_toplevel_v6_set_fullscreen(w->xdg_toplevel, output);
+ wl_surface_commit(w->surface);
+}
+
+static void
+_xdg_surface_configure_cb(void *data, zxdg_surface_v6 *surface, uint32_t serial)
+{
+ zxdg_surface_v6_ack_configure(surface, serial);
+}
+
+static void
+_xdg_toplevel_configure_cb(void *data,
+ zxdg_toplevel_v6 *toplevel,
+ int32_t width,
+ int32_t height,
+ struct wl_array *states)
+{
+ comp_window_wayland *w = (comp_window_wayland *)data;
+ comp_window_wayland_configure(w, width, height);
+}
+
+static const zxdg_surface_v6_listener xdg_surface_listener = {
+ _xdg_surface_configure_cb,
+};
+
+static void
+_xdg_toplevel_close_cb(void *data, zxdg_toplevel_v6 *toplevel)
+{}
+
+static const zxdg_toplevel_v6_listener xdg_toplevel_listener = {
+ _xdg_toplevel_configure_cb,
+ _xdg_toplevel_close_cb,
+};
+
+static void
+_xdg_shell_ping_cb(void *data, zxdg_shell_v6 *shell, uint32_t serial)
+{
+ zxdg_shell_v6_pong(shell, serial);
+}
+
+const zxdg_shell_v6_listener xdg_shell_listener = {
+ _xdg_shell_ping_cb,
+};
+
+static bool
+comp_window_wayland_init_swapchain(struct comp_window *w,
+ uint32_t width,
+ uint32_t height)
+{
+ struct comp_window_wayland *w_wayland = (struct comp_window_wayland *)w;
+ VkResult ret;
+
+ ret = comp_window_wayland_create_surface(w_wayland,
+ &w->swapchain.surface);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(w->c, "Failed to create surface!");
+ return false;
+ }
+
+ vk_swapchain_create(
+ &w->swapchain, width, height, w->c->settings.color_format,
+ w->c->settings.color_space, w->c->settings.present_mode);
+
+ return true;
+}
+
+static VkResult
+comp_window_wayland_create_surface(struct comp_window_wayland *w,
+ VkSurfaceKHR *vk_surface)
+{
+ struct vk_bundle *vk = w->base.swapchain.vk;
+ VkResult ret;
+
+ VkWaylandSurfaceCreateInfoKHR surface_info = {
+ .sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
+ .pNext = nullptr,
+ .flags = 0,
+ .display = w->display,
+ .surface = w->surface,
+ };
+
+ ret = vk->vkCreateWaylandSurfaceKHR(vk->instance, &surface_info, NULL,
+ vk_surface);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(w->base.c, "vkCreateWaylandSurfaceKHR: %s",
+ vk_result_string(ret));
+ return ret;
+ }
+
+ return VK_SUCCESS;
+}
+
+static void
+comp_window_wayland_flush(struct comp_window *w)
+{
+ struct comp_window_wayland *w_wayland = (struct comp_window_wayland *)w;
+
+ while (wl_display_prepare_read(w_wayland->display) != 0)
+ wl_display_dispatch_pending(w_wayland->display);
+ if (wl_display_flush(w_wayland->display) < 0 && errno != EAGAIN) {
+ wl_display_cancel_read(w_wayland->display);
+ return;
+ }
+
+ struct pollfd fds[] = {
+ {
+ .fd = wl_display_get_fd(w_wayland->display),
+ .events = POLLIN,
+ .revents = 0,
+ },
+ };
+
+ if (poll(fds, 1, 0) > 0) {
+ wl_display_read_events(w_wayland->display);
+ wl_display_dispatch_pending(w_wayland->display);
+ } else {
+ wl_display_cancel_read(w_wayland->display);
+ }
+}
+
+static void
+comp_window_wayland_output_mode(struct comp_window_wayland *w,
+ wl_output *output,
+ unsigned int flags,
+ int width,
+ int height,
+ int refresh)
+{
+ comp_window_wayland_mode m = {};
+ m.size = {width, height};
+ m.refresh = refresh;
+
+ comp_window_wayland_display *d =
+ comp_window_wayland_get_display_from_output(w, output);
+ if (d == nullptr) {
+ COMP_ERROR(w->base.c, "Output mode callback before geomentry!");
+ return;
+ }
+
+ d->modes.push_back(m);
+}
+
+static void
+_output_done_cb(void *data, wl_output *output)
+{}
+
+static void
+_output_scale_cb(void *data, wl_output *output, int scale)
+{}
+
+static void
+_registry_global_remove_cb(void *data, wl_registry *registry, uint32_t name)
+{}
+
+static void
+_registry_global_cb(void *data,
+ wl_registry *registry,
+ uint32_t name,
+ const char *interface,
+ uint32_t version)
+{
+ comp_window_wayland *w = (comp_window_wayland *)data;
+ // vik_log_d("Interface: %s Version %d", interface, version);
+ comp_window_wayland_registry_global(w, registry, name, interface);
+}
+
+static void
+_output_mode_cb(void *data,
+ wl_output *output,
+ unsigned int flags,
+ int width,
+ int height,
+ int refresh)
+{
+ comp_window_wayland *w = (comp_window_wayland *)data;
+ comp_window_wayland_output_mode(w, output, flags, width, height,
+ refresh);
+}
+
+static void
+_output_geometry_cb(void *data,
+ wl_output *output,
+ int x,
+ int y,
+ int w,
+ int h,
+ int subpixel,
+ const char *make,
+ const char *model,
+ int transform)
+{
+ comp_window_wayland_display d = {};
+ d.output = output;
+ d.make = std::string(make);
+ d.model = std::string(model);
+ d.physical_size_mm = {w, h};
+ d.position = {x, y};
+
+ comp_window_wayland *self = (comp_window_wayland *)data;
+ self->displays.push_back(d);
+}
+
+// listeners
+static const wl_registry_listener registry_listener = {
+ _registry_global_cb,
+ _registry_global_remove_cb,
+};
+
+static const wl_output_listener output_listener = {
+ _output_geometry_cb,
+ _output_mode_cb,
+ _output_done_cb,
+ _output_scale_cb,
+};
+
+static void
+comp_window_wayland_registry_global(struct comp_window_wayland *w,
+ wl_registry *registry,
+ uint32_t name,
+ const char *interface)
+{
+ if (strcmp(interface, "wl_compositor") == 0) {
+ w->compositor = (wl_compositor *)wl_registry_bind(
+ registry, name, &wl_compositor_interface, 4);
+ } else if (strcmp(interface, "zxdg_shell_v6") == 0) {
+ w->shell = (zxdg_shell_v6 *)wl_registry_bind(
+ registry, name, &zxdg_shell_v6_interface, 1);
+ zxdg_shell_v6_add_listener(w->shell, &xdg_shell_listener, w);
+ } else if (strcmp(interface, "wl_output") == 0) {
+ wl_output *_output = (wl_output *)wl_registry_bind(
+ registry, name, &wl_output_interface, 2);
+ wl_output_add_listener(_output, &output_listener, w);
+ }
+}
+
+static bool
+comp_window_wayland_init(struct comp_window *w)
+{
+ struct comp_window_wayland *w_wayland = (struct comp_window_wayland *)w;
+
+ w_wayland->display = wl_display_connect(NULL);
+ if (!w_wayland->display) {
+ return false;
+ }
+
+ wl_registry *registry = wl_display_get_registry(w_wayland->display);
+ wl_registry_add_listener(registry, ®istry_listener, w_wayland);
+
+ wl_display_roundtrip(w_wayland->display);
+
+ wl_registry_destroy(registry);
+
+ w_wayland->surface =
+ wl_compositor_create_surface(w_wayland->compositor);
+
+ if (!w_wayland->shell) {
+ COMP_ERROR(
+ w->c,
+ "Compositor is missing unstable zxdg_shell_v6 support");
+ }
+
+ w_wayland->xdg_surface =
+ zxdg_shell_v6_get_xdg_surface(w_wayland->shell, w_wayland->surface);
+
+ zxdg_surface_v6_add_listener(w_wayland->xdg_surface,
+ &xdg_surface_listener, w_wayland);
+
+ w_wayland->xdg_toplevel =
+ zxdg_surface_v6_get_toplevel(w_wayland->xdg_surface);
+
+ zxdg_toplevel_v6_add_listener(w_wayland->xdg_toplevel,
+ &xdg_toplevel_listener, w_wayland);
+
+ wl_surface_commit(w_wayland->surface);
+
+ return true;
+}
+
+static comp_window_wayland_display *
+comp_window_wayland_get_display_from_output(struct comp_window_wayland *w,
+ wl_output *output)
+{
+ for (int i = 0; i < (int)w->displays.size(); i++) {
+ if (w->displays[i].output == output)
+ return &w->displays[i];
+ }
+ return nullptr;
+}
+
+XRT_MAYBE_UNUSED static void
+comp_window_wayland_print_displays(struct comp_window_wayland *w)
+{
+ int i_d = 0;
+ COMP_DEBUG(w->base.c, "Available displays:");
+ for (auto d : w->displays) {
+ COMP_DEBUG(w->base.c, "%d: %s %s [%d, %d] %dx%dmm (%d Modes)",
+ i_d, d.make.c_str(), d.model.c_str(),
+ d.position.first, d.position.second,
+ d.physical_size_mm.first, d.physical_size_mm.second,
+ (int)d.modes.size());
+
+ int i_m = 0;
+ for (auto m : d.modes) {
+ COMP_DEBUG(w->base.c, "\t%d: %s", i_m,
+ mode_to_string(&m).c_str());
+ i_m++;
+ }
+ i_d++;
+ }
+}
+
+static comp_window_wayland_display *
+comp_window_wayland_current_display(struct comp_window_wayland *w)
+{
+ return &w->displays[w->base.c->settings.display];
+}
+
+static comp_window_wayland_mode *
+comp_window_wayland_current_mode(struct comp_window_wayland *w)
+{
+ return &comp_window_wayland_current_display(w)
+ ->modes[w->base.c->settings.mode];
+}
+
+static std::string
+mode_to_string(comp_window_wayland_mode *m)
+{
+ auto size = std::snprintf(nullptr, 0, "%d x %d @ %.2fHz", m->size.first,
+ m->size.second, (float)m->refresh / 1000.0);
+ std::string output(size + 1, '\0');
+ std::snprintf(&output[0], size, "%d x %d @ %.2fHz", m->size.first,
+ m->size.second, (float)m->refresh / 1000.0);
+ return std::string(output);
+}
+
+static void
+comp_window_wayland_validate_display(struct comp_window_wayland *w)
+{
+ comp_window_wayland_display *d;
+
+ if (w->base.c->settings.display < 0)
+ w->base.c->settings.display = 0;
+
+ if (w->base.c->settings.display > (int)w->displays.size()) {
+ COMP_DEBUG(w->base.c,
+ "Requested display %d, but only %d displays are "
+ "available.",
+ w->base.c->settings.display,
+ (int)w->displays.size());
+
+ w->base.c->settings.display = 0;
+ d = comp_window_wayland_current_display(w);
+ COMP_DEBUG(w->base.c, "Selecting '%s %s' instead.",
+ d->make.c_str(), d->model.c_str());
+ }
+}
+
+static void
+validate_mode(struct comp_window_wayland *w)
+{
+ comp_window_wayland_display *d = comp_window_wayland_current_display(w);
+
+ if (w->base.c->settings.mode < 0)
+ w->base.c->settings.mode = 0;
+
+ if (w->base.c->settings.mode > (int)d->modes.size()) {
+ COMP_DEBUG(w->base.c,
+ "Requested mode %d, but only %d modes"
+ " are available on display %d.",
+ w->base.c->settings.mode, (int)d->modes.size(),
+ w->base.c->settings.display);
+ w->base.c->settings.mode = 0;
+ COMP_DEBUG(w->base.c, "Selecting '%s' instead",
+ mode_to_string(comp_window_wayland_current_mode(w))
+ .c_str());
+ }
+}
+
+static void
+comp_window_wayland_configure(struct comp_window_wayland *w,
+ int32_t width,
+ int32_t height)
+{
+ if (w->first_configure) {
+ comp_window_wayland_validate_display(w);
+ validate_mode(w);
+ w->first_configure = false;
+ }
+
+ comp_window_wayland_mode *m = comp_window_wayland_current_mode(w);
+ if (w->fullscreen_requested &&
+ (m->size.first != width || m->size.second != height)) {
+ COMP_DEBUG(w->base.c,
+ "Received mode %dx%d does not match requested Mode "
+ "%dx%d. "
+ "Compositor bug? Requesting again.",
+ width, height, m->size.first, m->size.second);
+ w->fullscreen_requested = false;
+ }
+
+ m = comp_window_wayland_current_mode(w);
+ if (w->base.c->settings.fullscreen && !w->fullscreen_requested) {
+ COMP_DEBUG(
+ w->base.c, "Setting full screen on Display %d Mode %s",
+ w->base.c->settings.display, mode_to_string(m).c_str());
+ comp_window_wayland_fullscreen(w);
+ w->fullscreen_requested = true;
+ // TODO: resize cb
+ // resize_cb(m->size.first, m->size.second);
+ }
+}
+
+#endif
diff --git a/src/xrt/compositor/main/comp_window_xcb.cpp b/src/xrt/compositor/main/comp_window_xcb.cpp
new file mode 100644
index 000000000..c80bed3c6
--- /dev/null
+++ b/src/xrt/compositor/main/comp_window_xcb.cpp
@@ -0,0 +1,408 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief XCB window code.
+ * @author Lubosz Sarnecki
+ * @author Jakob Bornecrantz
+ * @ingroup comp
+ */
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include "xrt/xrt_compiler.h"
+#include "main/comp_window.h"
+
+
+/*
+ *
+ * Private structs.
+ *
+ */
+
+/*!
+ * Xcb display, xrandr output.
+ */
+struct comp_window_xcb_display
+{
+ std::string name;
+ std::pair position;
+ std::pair size;
+};
+
+/*!
+ * A xcb connection and window.
+ */
+struct comp_window_xcb
+{
+ struct comp_window base = comp_window();
+
+ xcb_connection_t* connection = nullptr;
+ xcb_window_t window = XCB_NONE;
+ xcb_screen_t* screen = nullptr;
+
+ xcb_atom_t atom_wm_protocols = XCB_NONE;
+ xcb_atom_t atom_wm_delete_window = XCB_NONE;
+
+ std::vector displays = {};
+};
+
+
+/*
+ *
+ * Pre declare functions.
+ *
+ */
+
+static void
+comp_window_xcb_destroy(struct comp_window* w);
+
+static void
+comp_window_xcb_flush(struct comp_window* w);
+
+XRT_MAYBE_UNUSED static void
+comp_window_xcb_list_screens(comp_window_xcb* w, xcb_screen_t* screen);
+
+static bool
+comp_window_xcb_init(struct comp_window* w);
+
+static comp_window_xcb_display*
+comp_window_xcb_current_display(comp_window_xcb* w);
+
+static bool
+comp_window_xcb_init_swapchain(struct comp_window* w,
+ uint32_t width,
+ uint32_t height);
+
+static int
+comp_window_xcb_connect(comp_window_xcb* w);
+
+static void
+comp_window_xcb_create_window(comp_window_xcb* w,
+ uint32_t width,
+ uint32_t height);
+
+static void
+comp_window_xcb_get_randr_outputs(comp_window_xcb* w);
+
+static void
+comp_window_xcb_connect_delete_event(comp_window_xcb* w);
+
+static void
+comp_window_xcb_set_full_screen(comp_window_xcb* w);
+
+static xcb_atom_t
+comp_window_xcb_get_atom(comp_window_xcb* w, const char* name);
+
+static VkResult
+comp_window_xcb_create_surface(comp_window_xcb* w, VkSurfaceKHR* surface);
+
+static void
+comp_window_xcb_update_window_title(struct comp_window* w, const char* title);
+
+
+/*
+ *
+ * Functions.
+ *
+ */
+
+extern "C" struct comp_window*
+comp_window_xcb_create(struct comp_compositor* c)
+{
+ auto w = new comp_window_xcb();
+
+ w->base.name = "xcb";
+ w->base.destroy = comp_window_xcb_destroy;
+ w->base.flush = comp_window_xcb_flush;
+ w->base.init = comp_window_xcb_init;
+ w->base.init_swapchain = comp_window_xcb_init_swapchain;
+ w->base.update_window_title = comp_window_xcb_update_window_title;
+ w->base.c = c;
+
+ return &w->base;
+}
+
+static void
+comp_window_xcb_destroy(struct comp_window* w)
+{
+ comp_window_xcb* w_xcb = (comp_window_xcb*)w;
+ xcb_destroy_window(w_xcb->connection, w_xcb->window);
+ xcb_disconnect(w_xcb->connection);
+
+ delete w;
+}
+
+static void
+comp_window_xcb_list_screens(comp_window_xcb* w, xcb_screen_t* screen)
+{
+ COMP_DEBUG(w->base.c, "Screen 0 %dx%d", screen->width_in_pixels,
+ screen->height_in_pixels);
+ comp_window_xcb_get_randr_outputs(w);
+
+ int display_i = 0;
+ for (comp_window_xcb_display d : w->displays) {
+ COMP_DEBUG(w->base.c, "%d: %s %dx%d [%d, %d]", display_i,
+ d.name.c_str(), d.size.first, d.size.second,
+ d.position.first, d.position.second);
+ display_i++;
+ }
+}
+
+static bool
+comp_window_xcb_init(struct comp_window* w)
+{
+ struct comp_window_xcb* w_xcb = (struct comp_window_xcb*)w;
+
+ if (!comp_window_xcb_connect(w_xcb)) {
+ return false;
+ }
+
+ xcb_screen_iterator_t iter =
+ xcb_setup_roots_iterator(xcb_get_setup(w_xcb->connection));
+
+ w_xcb->screen = iter.data;
+
+ if (w->c->settings.fullscreen) {
+ comp_window_xcb_get_randr_outputs(w_xcb);
+
+ if (w->c->settings.display > (int)w_xcb->displays.size() - 1) {
+ COMP_DEBUG(w->c,
+ "Requested display %d, but only %d "
+ "displays are available.",
+ w->c->settings.display,
+ (int)w_xcb->displays.size());
+
+ w->c->settings.display = 0;
+ comp_window_xcb_display* d =
+ comp_window_xcb_current_display(w_xcb);
+ COMP_DEBUG(w->c, "Selecting '%s' instead.",
+ d->name.c_str());
+ }
+
+ if (w->c->settings.display == -1)
+ w->c->settings.display = 0;
+
+ comp_window_xcb_display* d =
+ comp_window_xcb_current_display(w_xcb);
+ w->c->settings.width = d->size.first;
+ w->c->settings.height = d->size.second;
+ // TODO: size cb
+ // set_size_cb(settings->width, settings->height);
+ }
+
+ comp_window_xcb_create_window(w_xcb, w->c->settings.width,
+ w->c->settings.height);
+
+ comp_window_xcb_connect_delete_event(w_xcb);
+
+ if (w->c->settings.fullscreen)
+ comp_window_xcb_set_full_screen(w_xcb);
+
+ xcb_map_window(w_xcb->connection, w_xcb->window);
+
+ return true;
+}
+
+static comp_window_xcb_display*
+comp_window_xcb_current_display(comp_window_xcb* w)
+{
+ return &w->displays[w->base.c->settings.display];
+}
+
+static void
+comp_window_xcb_flush(struct comp_window* w)
+{}
+
+static bool
+comp_window_xcb_init_swapchain(struct comp_window* w,
+ uint32_t width,
+ uint32_t height)
+{
+ comp_window_xcb* w_xcb = (comp_window_xcb*)w;
+ VkResult ret;
+
+ ret = comp_window_xcb_create_surface(w_xcb, &w->swapchain.surface);
+ if (ret != VK_SUCCESS) {
+ return false;
+ }
+
+ // vk_swapchain_set_dimension_cb(&swapchain, set_size_cb);
+ // vk_swapchain_set_settings(&w->swapchain, w->settings);
+ vk_swapchain_create(
+ &w->swapchain, width, height, w->c->settings.color_format,
+ w->c->settings.color_space, w->c->settings.present_mode);
+
+ return true;
+}
+
+static int
+comp_window_xcb_connect(comp_window_xcb* w)
+{
+ w->connection = xcb_connect(nullptr, nullptr);
+ return !xcb_connection_has_error(w->connection);
+}
+
+static void
+comp_window_xcb_create_window(comp_window_xcb* w,
+ uint32_t width,
+ uint32_t height)
+{
+ w->window = xcb_generate_id(w->connection);
+
+ int x = 0;
+ int y = 0;
+
+ if (w->base.c->settings.fullscreen) {
+ x = comp_window_xcb_current_display(w)->position.first;
+ y = comp_window_xcb_current_display(w)->position.second;
+ }
+
+ uint32_t value_list = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
+
+ xcb_create_window(w->connection, XCB_COPY_FROM_PARENT, w->window,
+ w->screen->root, x, y, width, height, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, w->screen->root_visual,
+ XCB_CW_EVENT_MASK, &value_list);
+}
+
+static void
+comp_window_xcb_get_randr_outputs(comp_window_xcb* w)
+{
+ xcb_randr_get_screen_resources_cookie_t resources_cookie =
+ xcb_randr_get_screen_resources(w->connection, w->screen->root);
+ xcb_randr_get_screen_resources_reply_t* resources_reply =
+ xcb_randr_get_screen_resources_reply(w->connection,
+ resources_cookie, nullptr);
+ xcb_randr_output_t* xcb_outputs =
+ xcb_randr_get_screen_resources_outputs(resources_reply);
+
+ int count =
+ xcb_randr_get_screen_resources_outputs_length(resources_reply);
+ if (count < 1) {
+ COMP_ERROR(w->base.c, "Failed to retrieve randr outputs");
+ }
+
+ for (int i = 0; i < count; i++) {
+ xcb_randr_get_output_info_cookie_t output_cookie =
+ xcb_randr_get_output_info(w->connection, xcb_outputs[i],
+ XCB_CURRENT_TIME);
+ xcb_randr_get_output_info_reply_t* output_reply =
+ xcb_randr_get_output_info_reply(w->connection,
+ output_cookie, nullptr);
+
+ if (output_reply->connection !=
+ XCB_RANDR_CONNECTION_CONNECTED ||
+ output_reply->crtc == XCB_NONE) {
+ continue;
+ }
+
+ xcb_randr_get_crtc_info_cookie_t crtc_cookie =
+ xcb_randr_get_crtc_info(w->connection, output_reply->crtc,
+ XCB_CURRENT_TIME);
+ xcb_randr_get_crtc_info_reply_t* crtc_reply =
+ xcb_randr_get_crtc_info_reply(w->connection, crtc_cookie,
+ nullptr);
+
+ uint8_t* name = xcb_randr_get_output_info_name(output_reply);
+ int name_len =
+ xcb_randr_get_output_info_name_length(output_reply);
+
+ char* name_str = (char*)malloc(name_len + 1);
+ memcpy(name_str, name, name_len);
+ name_str[name_len] = '\0';
+
+ struct comp_window_xcb_display d = {};
+ d.name = std::string(name_str);
+ d.position = {crtc_reply->x, crtc_reply->y};
+ d.size = {crtc_reply->width, crtc_reply->height};
+ w->displays.push_back(d);
+
+ free(name_str);
+ }
+}
+
+static void
+comp_window_xcb_connect_delete_event(comp_window_xcb* w)
+{
+ w->atom_wm_protocols = comp_window_xcb_get_atom(w, "WM_PROTOCOLS");
+ w->atom_wm_delete_window =
+ comp_window_xcb_get_atom(w, "WM_DELETE_WINDOW");
+ xcb_change_property(w->connection, XCB_PROP_MODE_REPLACE, w->window,
+ w->atom_wm_protocols, XCB_ATOM_ATOM, 32, 1,
+ &w->atom_wm_delete_window);
+}
+
+static void
+comp_window_xcb_set_full_screen(comp_window_xcb* w)
+{
+ xcb_atom_t atom_wm_state = comp_window_xcb_get_atom(w, "_NET_WM_STATE");
+ xcb_atom_t atom_wm_fullscreen =
+ comp_window_xcb_get_atom(w, "_NET_WM_STATE_FULLSCREEN");
+ xcb_change_property(w->connection, XCB_PROP_MODE_REPLACE, w->window,
+ atom_wm_state, XCB_ATOM_ATOM, 32, 1,
+ &atom_wm_fullscreen);
+}
+
+static xcb_atom_t
+comp_window_xcb_get_atom(comp_window_xcb* w, const char* name)
+{
+ xcb_intern_atom_cookie_t cookie;
+ xcb_intern_atom_reply_t* reply;
+ xcb_atom_t atom;
+
+ cookie = xcb_intern_atom(w->connection, 0, strlen(name), name);
+ reply = xcb_intern_atom_reply(w->connection, cookie, NULL);
+ if (reply) {
+ atom = reply->atom;
+ } else {
+ atom = XCB_NONE;
+ }
+
+ free(reply);
+ return atom;
+}
+
+static VkResult
+comp_window_xcb_create_surface(comp_window_xcb* w, VkSurfaceKHR* surface)
+{
+ struct vk_bundle* vk = w->base.swapchain.vk;
+ VkResult ret;
+
+ VkXcbSurfaceCreateInfoKHR surface_info = {
+ .sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
+ .pNext = nullptr,
+ .flags = 0,
+ .connection = w->connection,
+ .window = w->window,
+ };
+
+ ret = vk->vkCreateXcbSurfaceKHR(vk->instance, &surface_info, NULL,
+ surface);
+ if (ret != VK_SUCCESS) {
+ COMP_ERROR(w->base.c, "vkCreateXcbSurfaceKHR: %s",
+ vk_result_string(ret));
+ return ret;
+ }
+
+ return VK_SUCCESS;
+}
+
+static void
+comp_window_xcb_update_window_title(struct comp_window* w, const char* title)
+{
+ comp_window_xcb* w_xcb = (comp_window_xcb*)w;
+ xcb_change_property(w_xcb->connection, XCB_PROP_MODE_REPLACE,
+ w_xcb->window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8,
+ strlen(title), title);
+}
+
+#endif
diff --git a/src/xrt/compositor/shaders/CMakeLists.txt b/src/xrt/compositor/shaders/CMakeLists.txt
new file mode 100644
index 000000000..814a73aef
--- /dev/null
+++ b/src/xrt/compositor/shaders/CMakeLists.txt
@@ -0,0 +1,5 @@
+# Copyright 2019, Collabora, Ltd.
+# SPDX-License-Identifier: BSL-1.0
+
+# CMakeLists.txt required for CMake to create the shaders/ directory in the build tree.
+# Generated shaders will be placed there.
diff --git a/src/xrt/compositor/shaders/distortion.vert b/src/xrt/compositor/shaders/distortion.vert
new file mode 100644
index 000000000..81b07fa82
--- /dev/null
+++ b/src/xrt/compositor/shaders/distortion.vert
@@ -0,0 +1,34 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+// Author: Lubosz Sarnecki
+#version 450
+
+layout (location = 0) out vec2 outUV;
+layout (location = 1) out int outViewIndex;
+
+layout (binding = 2, std140) uniform UBO
+{
+ vec4 rot;
+ int viewport_id;
+ bool flip_y;
+} ubo_vp;
+
+out gl_PerVertex
+{
+ vec4 gl_Position;
+};
+
+
+void main()
+{
+ mat2x2 rot = {
+ ubo_vp.rot.xy,
+ ubo_vp.rot.zw,
+ };
+
+ outViewIndex = ubo_vp.viewport_id;
+ outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
+ gl_Position = vec4(rot * (outUV * 2.0f - 1.0f), 0.0f, 1.0f);
+ if (ubo_vp.flip_y)
+ outUV.y = 1.0 - outUV.y;
+}
diff --git a/src/xrt/compositor/shaders/none.frag b/src/xrt/compositor/shaders/none.frag
new file mode 100644
index 000000000..df2ab5b8a
--- /dev/null
+++ b/src/xrt/compositor/shaders/none.frag
@@ -0,0 +1,17 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+// Author: Jakob Bornecrantz
+#version 450
+
+layout (binding = 0) uniform sampler2D texSampler;
+
+layout (location = 0) in vec2 inUV;
+layout (location = 1) flat in int inViewIndex;
+
+layout (location = 0) out vec4 outColor;
+
+
+void main()
+{
+ outColor = vec4(texture(texSampler, inUV).rgb, 1.0);
+}
diff --git a/src/xrt/compositor/shaders/panotools.frag b/src/xrt/compositor/shaders/panotools.frag
new file mode 100644
index 000000000..9e7c9503f
--- /dev/null
+++ b/src/xrt/compositor/shaders/panotools.frag
@@ -0,0 +1,77 @@
+// Copyright 2017, James Sarrett.
+// Copyright 2017, Bastiaan Olij.
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+// Author: James Sarrett
+// Author: Bastiaan Olij
+// Author: Lubosz Sarnecki
+#version 450
+
+layout (binding = 0) uniform sampler2D texSampler;
+
+layout (binding = 1, std140) uniform UBO
+{
+ // Distoriton coefficients (PanoTools model) [a,b,c,d]
+ vec4 HmdWarpParam;
+
+ // chromatic distortion post scaling
+ vec4 aberr;
+
+ // Position of lens center in m (usually eye_w/2, eye_h/2)
+ vec2 LensCenter[2];
+
+ // Scale from texture co-ords to m (usually eye_w, eye_h)
+ vec2 ViewportScale;
+
+ // Distortion overall scale in m (usually ~eye_w/2)
+ float WarpScale;
+} ubo;
+
+layout (location = 0) in vec2 inUV;
+layout (location = 1) flat in int inViewIndex;
+
+layout (location = 0) out vec4 outColor;
+
+
+void main()
+{
+ const int i = inViewIndex;
+
+ vec2 r = inUV * ubo.ViewportScale - ubo.LensCenter[i];
+
+ // scale for distortion model
+ // distortion model has r=1 being the largest circle inscribed (e.g. eye_w/2)
+ r /= ubo.WarpScale;
+
+ // |r|**2
+ float r_mag = length(r);
+
+ // offset for which fragment is sourced
+ vec2 r_displaced = r * (
+ ubo.HmdWarpParam.w +
+ ubo.HmdWarpParam.z * r_mag +
+ ubo.HmdWarpParam.y * r_mag * r_mag +
+ ubo.HmdWarpParam.x * r_mag * r_mag * r_mag
+ );
+
+ // back to world scale
+ r_displaced *= ubo.WarpScale;
+
+ // back to viewport co-ord
+ vec2 tcR = (ubo.LensCenter[i] + ubo.aberr.r * r_displaced) / ubo.ViewportScale;
+ vec2 tcG = (ubo.LensCenter[i] + ubo.aberr.g * r_displaced) / ubo.ViewportScale;
+ vec2 tcB = (ubo.LensCenter[i] + ubo.aberr.b * r_displaced) / ubo.ViewportScale;
+
+ vec3 color = vec3(
+ texture(texSampler, tcR).r,
+ texture(texSampler, tcG).g,
+ texture(texSampler, tcB).b
+ );
+
+ // distortion cuttoff
+ if (tcG.x < 0.0 || tcG.x > 1.0 || tcG.y < 0.0 || tcG.y > 1.0) {
+ color *= 0.125;
+ }
+
+ outColor = vec4(color, 1.0);
+}
diff --git a/src/xrt/compositor/shaders/vive.frag b/src/xrt/compositor/shaders/vive.frag
new file mode 100644
index 000000000..012e2b947
--- /dev/null
+++ b/src/xrt/compositor/shaders/vive.frag
@@ -0,0 +1,84 @@
+// Copyright 2017, Philipp Zabel.
+// Copyright 2017-2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+// Author: Philipp Zabel
+// Author: Lubosz Sarnecki
+#version 450
+
+// TODO: Don't use hard coded config
+float aspect_x_over_y = 0.8999999761581421;
+float grow_for_undistort = 0.6000000238418579;
+
+vec2 undistort_r2_cutoff = vec2(1.11622154712677, 1.101870775222778);
+
+vec2 center[2] = vec2[](
+ vec2(0.08946027017045266, -0.009002181016260827),
+ vec2(-0.08933516629552526, -0.006014565287238661)
+);
+
+vec3 coeffs[2][3] = {
+ // left
+ {
+ // green
+ vec3(-0.188236068524731, -0.221086205321053, -0.2537849057915209),
+ // blue
+ vec3(-0.07316590815739493, -0.02332400789561968, 0.02469959434698275),
+ // red
+ vec3(-0.02223805567703767, -0.04931309279533211, -0.07862881939243466),
+ },
+ // right
+ {
+ // green
+ vec3(-0.1906209981894497, -0.2248896677207884, -0.2721364516782803),
+ // blue
+ vec3(-0.07346071902951497, -0.02189527566250131, 0.0581378652359256),
+ // red
+ vec3(-0.01755850332081247, -0.04517245633373419, -0.0928909347763)
+ }
+};
+
+layout (binding = 0) uniform sampler2D texSampler;
+
+layout (location = 0) in vec2 inUV;
+layout (location = 1) flat in int inViewIndex;
+
+layout (location = 0) out vec4 outColor;
+
+
+void main()
+{
+ const int i = inViewIndex;
+
+ const vec2 factor = 0.5 / (1.0 + grow_for_undistort)
+ * vec2(1.0, aspect_x_over_y);
+
+ vec2 texCoord = 2.0 * inUV - vec2(1.0);
+
+ texCoord.y /= aspect_x_over_y;
+ texCoord -= center[i];
+
+ float r2 = dot(texCoord, texCoord);
+
+ vec3 d_inv = ((r2 * coeffs[i][2] + coeffs[i][1])
+ * r2 + coeffs[i][0])
+ * r2 + vec3(1.0);
+
+ const vec3 d = 1.0 / d_inv;
+
+ const vec2 offset = vec2(0.5);
+
+ vec2 tcR = offset + (texCoord * d.r + center[i]) * factor;
+ vec2 tcG = offset + (texCoord * d.g + center[i]) * factor;
+ vec2 tcB = offset + (texCoord * d.b + center[i]) * factor;
+
+ vec3 color = vec3(
+ texture(texSampler, tcR).r,
+ texture(texSampler, tcG).g,
+ texture(texSampler, tcB).b);
+
+ if (r2 > undistort_r2_cutoff[i]) {
+ color *= 0.125;
+ }
+
+ outColor = vec4(color, 1.0);
+}
diff --git a/src/xrt/drivers/CMakeLists.txt b/src/xrt/drivers/CMakeLists.txt
new file mode 100644
index 000000000..f7beac62a
--- /dev/null
+++ b/src/xrt/drivers/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright 2019, Collabora, Ltd.
+# SPDX-License-Identifier: BSL-1.0
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../auxiliary
+ )
+
+set(OHMD_SOURCE_FILES
+ ohmd/oh_device.c
+ ohmd/oh_device.h
+ ohmd/oh_interface.h
+ ohmd/oh_prober.c
+ )
+
+# Use OBJECT to not create a archive, since it just gets in the way.
+add_library(drv_ohmd OBJECT ${OHMD_SOURCE_FILES})
+set_property(TARGET drv_ohmd PROPERTY POSITION_INDEPENDENT_CODE ON)
+target_include_directories(drv_ohmd SYSTEM
+ PRIVATE ${OPENHMD_INCLUDE_DIRS}
+ )
+
+if(HIDAPI_FOUND)
+ set(HDK_SOURCE_FILES
+ hdk/hdk_device.cpp
+ hdk/hdk_device.h
+ hdk/hdk_interface.h
+ hdk/hdk_prober.c
+ )
+
+ # Use OBJECT to not create a archive, since it just gets in the way.
+ add_library(drv_hdk OBJECT ${HDK_SOURCE_FILES})
+ set_property(TARGET drv_hdk PROPERTY POSITION_INDEPENDENT_CODE ON)
+ target_include_directories(drv_hdk SYSTEM
+ PRIVATE ${HIDAPI_INCLUDE_DIRS}
+ )
+endif()
diff --git a/src/xrt/drivers/hdk/hdk_device.cpp b/src/xrt/drivers/hdk/hdk_device.cpp
new file mode 100644
index 000000000..8a0226d99
--- /dev/null
+++ b/src/xrt/drivers/hdk/hdk_device.cpp
@@ -0,0 +1,276 @@
+// Copyright 2019, Collabora, Ltd.
+// Copyright 2014, Kevin M. Godby
+// Copyright 2014-2018, Sensics, Inc.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Driver for an OSVR Hacker Dev Kit device.
+ *
+ * Based in part on the corresponding VRPN driver,
+ * available under BSL-1.0.
+ *
+ * @author Ryan Pavlik
+ * @author Kevin M. Godby
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "math/m_api.h"
+#include "xrt/xrt_device.h"
+#include "util/u_debug.h"
+#include "util/u_misc.h"
+#include "util/u_device.h"
+
+#include "hdk_device.h"
+
+
+/**
+ * A fixed-point to float conversion function.
+ *
+ * Values are signed, two's-complement, if the supplied integer is.
+ *
+ * The conversion is effectively from the fixed-point arithmetic type known
+ * "unambiguously" as Q INTEGER_BITS.FRACTIONAL_BITS - the number of integer
+ * bits is not inferred, though it is checked to ensure it adds up.
+ *
+ * @tparam INTEGER_BITS The number of bits devoted to the integer part.
+ * @tparam FRACTIONAL_BITS The number of bits devoted to the fractional
+ * part.
+ * @tparam IntegerType The input integer type, typically deduced (do not need to
+ * specify explicitly)
+ * @param v An input "integer" that is actually a fixed-point value.
+ *
+ * INTEGER_BITS and FRACTIONAL_BITS must sum to 8 * sizeof(v), the bit width of
+ * the input integer, for unsigned values, or to one less than that (for the
+ * sign bit) for signed values.
+ *
+ * Based in part on the VRPN header vrpn_FixedPoint.h,
+ * available under BSL-1.0.
+ */
+template
+static inline float
+fromFixedPoint(IntegerType v)
+{
+ constexpr size_t SIGN_BIT = std::is_signed::value ? 1 : 0;
+ static_assert(INTEGER_BITS + FRACTIONAL_BITS + SIGN_BIT ==
+ 8 * sizeof(IntegerType),
+ "INTEGER_BITS and FRACTIONAL_BITS, plus 1 for a sign bit "
+ "if applicable, must sum to the input "
+ "integer width, but do not.");
+ return static_cast(v) / (1 << FRACTIONAL_BITS);
+}
+
+static inline uint16_t
+hdk_get_le_uint16(uint8_t *&bufPtr)
+{
+ assert(bufPtr != nullptr);
+ uint16_t ret = static_cast(*bufPtr) |
+ (static_cast(*(bufPtr + 1)) << 8);
+ bufPtr += 2;
+ return ret;
+}
+
+static inline int16_t
+hdk_get_le_int16(uint8_t *&bufPtr)
+{
+ return static_cast(hdk_get_le_uint16(bufPtr));
+}
+
+static void
+hdk_device_destroy(struct xrt_device *xdev)
+{
+ struct hdk_device *hd = hdk_device(xdev);
+
+ if (hd->dev != NULL) {
+ hid_close(hd->dev);
+ hd->dev = NULL;
+ }
+
+ free(hd);
+}
+
+static void
+hdk_device_get_tracked_pose(struct xrt_device *xdev,
+ struct xrt_space_relation *out_relation)
+{
+ struct hdk_device *hd = hdk_device(xdev);
+
+ uint8_t buffer[32];
+ auto bytesRead = hid_read(hd->dev, &(buffer[0]), sizeof(buffer));
+ if (bytesRead != 32 && bytesRead != 16) {
+ HDK_DEBUG(hd, "Only got %d bytes", bytesRead);
+ out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
+ return;
+ }
+ uint8_t *buf = &(buffer[0]);
+
+#if 0
+ uint8_t version = uint8_t(0x0f) & *buf;
+ uint8_t hdmi_status = (uint8_t(0xf0) & *buf) >> 4;
+#endif
+ buf++;
+
+ // HDMI status only valid in reports version 3.
+ // Expecting either version 1 (100Hz) or 3 (400Hz):
+ // https://github.com/OSVR/OSVR-HDK-MCU-Firmware/blob/master/Source%20code/Embedded/src/DeviceDrivers/BNO070_using_hostif.c#L511
+
+ // Next byte is sequence number, ignore
+ buf++;
+
+ struct xrt_quat quat;
+ quat.x = fromFixedPoint<1, 14>(hdk_get_le_int16(buf)) * -1;
+ quat.y = fromFixedPoint<1, 14>(hdk_get_le_int16(buf)) * -1;
+ quat.z = fromFixedPoint<1, 14>(hdk_get_le_int16(buf));
+ quat.w = fromFixedPoint<1, 14>(hdk_get_le_int16(buf));
+
+ out_relation->pose.orientation = quat;
+
+ /// @todo might not be accurate on some version 1 reports??
+
+ // This is in the "world" coordinate system.
+ struct xrt_vec3 ang_vel;
+ ang_vel.x = fromFixedPoint<6, 9>(hdk_get_le_int16(buf));
+ ang_vel.y = fromFixedPoint<6, 9>(hdk_get_le_int16(buf));
+ ang_vel.z = fromFixedPoint<6, 9>(hdk_get_le_int16(buf));
+
+ out_relation->angular_velocity = ang_vel;
+
+ out_relation->relation_flags = xrt_space_relation_flags(
+ XRT_SPACE_RELATION_ORIENTATION_VALID_BIT |
+ XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT |
+ XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT);
+
+ HDK_SPEW(hd, "GET_TRACKED_POSE (%f, %f, %f, %f) ANG_VEL (%f, %f, %f)",
+ quat.x, quat.y, quat.z, quat.w, ang_vel.x, ang_vel.y,
+ ang_vel.z);
+}
+
+static void
+hdk_device_get_view_pose(struct xrt_device *xdev,
+ struct xrt_vec3 *eye_relation,
+ uint32_t view_index,
+ struct xrt_pose *out_pose)
+{
+ struct xrt_pose pose = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}};
+ bool adjust = view_index == 0;
+
+ pose.position.x = eye_relation->x / 2.0f;
+ pose.position.y = eye_relation->y / 2.0f;
+ pose.position.z = eye_relation->z / 2.0f;
+
+ // Adjust for left/right while also making sure there aren't any -0.f.
+ if (pose.position.x > 0.0f && adjust) {
+ pose.position.x = -pose.position.x;
+ }
+ if (pose.position.y > 0.0f && adjust) {
+ pose.position.y = -pose.position.y;
+ }
+ if (pose.position.z > 0.0f && adjust) {
+ pose.position.z = -pose.position.z;
+ }
+
+ *out_pose = pose;
+}
+
+#define HDK_DEBUG_INT(hd, name, val) HDK_DEBUG(hd, "\t%s = %u", name, val)
+
+#define HDK_DEBUG_MM(hd, name, val) \
+ HDK_DEBUG(hd, "\t%s = %i.%02imm", name, (int32_t)(val * 1000.f), \
+ abs((int32_t)(val * 100000.f)) % 100)
+
+#define HDK_DEBUG_ANGLE(hd, name, val) \
+ HDK_DEBUG(hd, "\t%s = %f (%i)", name, val, \
+ (int32_t)(val * (180 / M_PI)))
+
+#define HDK_DEBUG_MAT2X2(hd, name, rot) \
+ HDK_DEBUG(hd, "\t%s = {%f, %f} {%f, %f}", name, rot.v[0], rot.v[1], \
+ rot.v[2], rot.v[3])
+
+struct hdk_device *
+hdk_device_create(hid_device *dev,
+ enum HDK_VARIANT variant,
+ bool print_spew,
+ bool print_debug)
+{
+ struct hdk_device *hd =
+ (struct hdk_device *)calloc(1, sizeof(struct hdk_device));
+ hd->base.blend_mode = XRT_BLEND_MODE_OPAQUE;
+ hd->base.destroy = hdk_device_destroy;
+ hd->base.get_tracked_pose = hdk_device_get_tracked_pose;
+ hd->base.get_view_pose = hdk_device_get_view_pose;
+ hd->dev = dev;
+ hd->print_spew = print_spew;
+ hd->print_debug = print_debug;
+
+ if (variant != HDK_VARIANT_2) {
+ HDK_ERROR(hd,
+ "Only recognize HDK2 for now, and this isn't it!");
+ hdk_device_destroy(&hd->base);
+ return NULL;
+ }
+
+ // Treat as symmetric right now.
+ const double FOV = 92.0 / 180 * M_PI;
+ {
+ /* right eye */
+ math_compute_fovs(1.0, 0.5, FOV, 1, 0.5, FOV,
+ &hd->base.views[1].fov);
+ }
+ {
+ /* left eye - just mirroring right eye now */
+ hd->base.views[0].fov.angle_up = hd->base.views[1].fov.angle_up;
+ hd->base.views[0].fov.angle_down =
+ hd->base.views[1].fov.angle_down;
+
+ hd->base.views[0].fov.angle_left =
+ -hd->base.views[1].fov.angle_right;
+ hd->base.views[0].fov.angle_right =
+ -hd->base.views[1].fov.angle_left;
+ }
+
+ // HDK2 is upside down :facepalm:
+
+ // clang-format off
+ // Main display.
+ hd->base.screens[0].w_pixels = 2160;
+ hd->base.screens[0].h_pixels = 1200;
+
+ // Left
+ hd->base.views[0].display.w_pixels = 1080;
+ hd->base.views[0].display.h_pixels = 1200;
+ hd->base.views[0].viewport.x_pixels = 1080; // right half of display
+ hd->base.views[0].viewport.y_pixels = 60;
+ hd->base.views[0].viewport.w_pixels = 1080;
+ hd->base.views[0].viewport.h_pixels = 1080;
+ hd->base.views[0].rot = u_device_rotation_180;
+
+ // Right
+ hd->base.views[1].display.w_pixels = 1080;
+ hd->base.views[1].display.h_pixels = 1200;
+ hd->base.views[1].viewport.x_pixels = 0;
+ hd->base.views[1].viewport.y_pixels = 60;
+ hd->base.views[1].viewport.w_pixels = 1080;
+ hd->base.views[1].viewport.h_pixels = 1080;
+ hd->base.views[1].rot = u_device_rotation_180;
+
+ // Distortion
+ hd->base.distortion.models = XRT_DISTORTION_MODEL_NONE;
+ hd->base.distortion.preferred = XRT_DISTORTION_MODEL_NONE;
+ // clang-format on
+
+
+ if (hd->print_debug) {
+ u_device_dump_config(&hd->base, __func__,
+ "OSVR HDK-family Device");
+ }
+
+ return hd;
+}
diff --git a/src/xrt/drivers/hdk/hdk_device.h b/src/xrt/drivers/hdk/hdk_device.h
new file mode 100644
index 000000000..ea4d083f0
--- /dev/null
+++ b/src/xrt/drivers/hdk/hdk_device.h
@@ -0,0 +1,76 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Interface to direct OSVR HDK driver code.
+ * @author Jakob Bornecrantz
+ * @author Ryan Pavlik
+ */
+
+#pragma once
+
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum HDK_VARIANT
+{
+ HDK_UNKNOWN = 0,
+ HDK_VARIANT_1_2,
+ HDK_VARIANT_1_3_1_4,
+ HDK_VARIANT_2
+};
+
+struct hdk_device
+{
+ struct xrt_device base;
+ hid_device *dev;
+ enum HDK_VARIANT variant;
+
+ bool print_spew;
+ bool print_debug;
+};
+
+static inline struct hdk_device *
+hdk_device(struct xrt_device *xdev)
+{
+ return (struct hdk_device *)xdev;
+}
+
+struct hdk_device *
+hdk_device_create(hid_device *dev,
+ enum HDK_VARIANT variant,
+ bool print_spew,
+ bool print_debug);
+
+#define HDK_SPEW(c, ...) \
+ do { \
+ if (c->print_spew) { \
+ fprintf(stderr, "%s - ", __func__); \
+ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+ } \
+ } while (false)
+#define HDK_DEBUG(c, ...) \
+ do { \
+ if (c->print_debug) { \
+ fprintf(stderr, "%s - ", __func__); \
+ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+ } \
+ } while (false)
+
+#define HDK_ERROR(c, ...) \
+ do { \
+ fprintf(stderr, "%s - ", __func__); \
+ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+ } while (false)
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/drivers/hdk/hdk_interface.h b/src/xrt/drivers/hdk/hdk_interface.h
new file mode 100644
index 000000000..0fb5a4aba
--- /dev/null
+++ b/src/xrt/drivers/hdk/hdk_interface.h
@@ -0,0 +1,23 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Interface to direct OSVR HDK driver code.
+ * @author Jakob Bornecrantz
+ * @author Ryan Pavlik
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct xrt_prober*
+hdk_create_prober();
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/xrt/drivers/hdk/hdk_prober.c b/src/xrt/drivers/hdk/hdk_prober.c
new file mode 100644
index 000000000..5145992db
--- /dev/null
+++ b/src/xrt/drivers/hdk/hdk_prober.c
@@ -0,0 +1,107 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief OSVR HDK prober code.
+ * @author Jakob Bornecrantz
+ * @author Ryan Pavlik
+ */
+
+#include
+#include
+#include
+
+#include
+#include "xrt/xrt_prober.h"
+
+#include "util/u_misc.h"
+#include "util/u_debug.h"
+
+#include "hdk_device.h"
+
+
+DEBUG_GET_ONCE_BOOL_OPTION(hdk_spew, "HDK_PRINT_SPEW", false)
+DEBUG_GET_ONCE_BOOL_OPTION(hdk_debug, "HDK_PRINT_DEBUG", false)
+
+struct hdk_prober
+{
+ struct xrt_prober base;
+};
+
+static inline struct hdk_prober *
+hdk_prober(struct xrt_prober *p)
+{
+ return (struct hdk_prober *)p;
+}
+
+static void
+hdk_prober_destroy(struct xrt_prober *p)
+{
+ struct hdk_prober *hhp = hdk_prober(p);
+
+
+ free(hhp);
+}
+#define HDK_MAKE_STRING(NAME, STR) \
+ static const char NAME[] = STR; \
+ static const wchar_t NAME##_W[] = L##STR
+
+HDK_MAKE_STRING(HDK2_PRODUCT_STRING, "OSVR HDK 2");
+HDK_MAKE_STRING(HDK13_PRODUCT_STRING, "OSVR HDK 1.3/1.4");
+
+
+static const uint16_t HDK_VID = 0x1532;
+static const uint16_t HDK_PID = 0x0b00;
+
+static struct xrt_device *
+hdk_prober_autoprobe(struct xrt_prober *p)
+{
+ struct hdk_prober *hhp = hdk_prober(p);
+
+ (void)hhp;
+
+ bool print_spew = debug_get_bool_option_hdk_spew();
+ bool print_debug = debug_get_bool_option_hdk_debug();
+ struct hid_device_info *devs = hid_enumerate(HDK_VID, HDK_PID);
+
+ // Just take the first one, not going to loop right now.
+ if (devs == NULL) {
+ if (print_debug) {
+ fprintf(stderr, "%s - no device found\n", __func__);
+ }
+ return NULL;
+ }
+ enum HDK_VARIANT variant = HDK_UNKNOWN;
+ const char *name = NULL;
+ if (0 == wcscmp(HDK2_PRODUCT_STRING_W, devs->product_string)) {
+ variant = HDK_VARIANT_2;
+ name = HDK2_PRODUCT_STRING;
+ } else {
+ //! @todo just assuming anything else is 1.3 for now
+ (void)HDK13_PRODUCT_STRING_W;
+ variant = HDK_VARIANT_1_3_1_4;
+ name = HDK13_PRODUCT_STRING;
+ }
+
+ hid_device *dev = hid_open(HDK_VID, HDK_PID, devs->serial_number);
+ struct hdk_device *hd =
+ hdk_device_create(dev, variant, print_spew, print_debug);
+ hid_free_enumeration(devs);
+ devs = NULL;
+
+ printf("%s - Found at least the tracker of some HDK: %s\n", __func__,
+ name);
+
+ return &hd->base;
+}
+
+struct xrt_prober *
+hdk_create_prober()
+{
+ struct hdk_prober *hhp =
+ (struct hdk_prober *)calloc(1, sizeof(struct hdk_prober));
+ hhp->base.destroy = hdk_prober_destroy;
+ hhp->base.lelo_dallas_autoprobe = hdk_prober_autoprobe;
+
+ return &hhp->base;
+}
diff --git a/src/xrt/drivers/ohmd/oh_device.c b/src/xrt/drivers/ohmd/oh_device.c
new file mode 100644
index 000000000..f70ce59c6
--- /dev/null
+++ b/src/xrt/drivers/ohmd/oh_device.c
@@ -0,0 +1,379 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief Adaptor to a OpenHMD device.
+ * @author Jakob Bornecrantz
+ */
+
+
+#include