From 15a97422ba17aa9d8a78cf66bc9f449211a4437d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz <jakob@collabora.com> Date: Mon, 18 Mar 2019 05:52:32 +0000 Subject: [PATCH] xrt: Add all of Monado --- .gitignore | 15 + CMakeLists.txt | 58 + CONTRIBUTING.md | 82 + README.md | 206 + cmake/FindHIDAPI.cmake | 46 + cmake/FindWayland.cmake | 66 + cmake/SPIR-V.cmake | 38 + doc/CMakeLists.txt | 36 + doc/Doxyfile.in | 2541 ++++++++++++ doc/roadmap.md | 35 + scripts/format-project.sh | 28 + src/CMakeLists.txt | 4 + src/external/glad/gl.c | 1654 ++++++++ src/external/glad/gl.h | 3692 +++++++++++++++++ .../openxr_includes/loader_interfaces.h | 122 + src/external/openxr_includes/openxr.h | 1479 +++++++ .../openxr_includes/openxr_platform.h | 415 ++ .../openxr_includes/openxr_platform_defines.h | 120 + src/xrt/.clang-format | 48 + src/xrt/CMakeLists.txt | 8 + src/xrt/auxiliary/CMakeLists.txt | 42 + src/xrt/auxiliary/math/m_api.h | 250 ++ src/xrt/auxiliary/math/m_base.cpp | 430 ++ src/xrt/auxiliary/math/m_eigen_interop.h | 111 + src/xrt/auxiliary/math/m_optics.c | 167 + src/xrt/auxiliary/math/m_quatexpmap.cpp | 148 + src/xrt/auxiliary/util/u_debug.c | 139 + src/xrt/auxiliary/util/u_debug.h | 81 + src/xrt/auxiliary/util/u_device.c | 126 + src/xrt/auxiliary/util/u_device.h | 35 + src/xrt/auxiliary/util/u_misc.c | 16 + src/xrt/auxiliary/util/u_misc.h | 19 + src/xrt/auxiliary/util/u_time.cpp | 135 + src/xrt/auxiliary/util/u_time.h | 106 + src/xrt/compositor/CMakeLists.txt | 62 + src/xrt/compositor/client/comp_gl_api.c | 10 + src/xrt/compositor/client/comp_gl_api.h | 12 + src/xrt/compositor/client/comp_gl_client.c | 242 ++ src/xrt/compositor/client/comp_gl_client.h | 91 + src/xrt/compositor/client/comp_vk_client.c | 276 ++ src/xrt/compositor/client/comp_vk_client.h | 103 + src/xrt/compositor/client/comp_xlib_client.c | 51 + src/xrt/compositor/client/comp_xlib_client.h | 58 + src/xrt/compositor/common/comp_vk.c | 1003 +++++ src/xrt/compositor/common/comp_vk.h | 339 ++ src/xrt/compositor/common/comp_vk_swapchain.c | 389 ++ src/xrt/compositor/common/comp_vk_swapchain.h | 133 + .../compositor/main/comp_client_interface.h | 30 + src/xrt/compositor/main/comp_compositor.c | 505 +++ src/xrt/compositor/main/comp_compositor.h | 234 ++ src/xrt/compositor/main/comp_distortion.c | 719 ++++ src/xrt/compositor/main/comp_distortion.h | 135 + src/xrt/compositor/main/comp_glue_gl.c | 22 + src/xrt/compositor/main/comp_glue_vk.c | 65 + src/xrt/compositor/main/comp_glue_xlib.c | 36 + src/xrt/compositor/main/comp_renderer.c | 997 +++++ src/xrt/compositor/main/comp_renderer.h | 53 + src/xrt/compositor/main/comp_settings.c | 51 + src/xrt/compositor/main/comp_settings.h | 83 + src/xrt/compositor/main/comp_swapchain.c | 303 ++ src/xrt/compositor/main/comp_window.h | 92 + .../main/comp_window_direct_mode.cpp | 648 +++ .../compositor/main/comp_window_wayland.cpp | 629 +++ src/xrt/compositor/main/comp_window_xcb.cpp | 408 ++ src/xrt/compositor/shaders/CMakeLists.txt | 5 + src/xrt/compositor/shaders/distortion.vert | 34 + src/xrt/compositor/shaders/none.frag | 17 + src/xrt/compositor/shaders/panotools.frag | 77 + src/xrt/compositor/shaders/vive.frag | 84 + src/xrt/drivers/CMakeLists.txt | 37 + src/xrt/drivers/hdk/hdk_device.cpp | 276 ++ src/xrt/drivers/hdk/hdk_device.h | 76 + src/xrt/drivers/hdk/hdk_interface.h | 23 + src/xrt/drivers/hdk/hdk_prober.c | 107 + src/xrt/drivers/ohmd/oh_device.c | 379 ++ src/xrt/drivers/ohmd/oh_device.h | 69 + src/xrt/drivers/ohmd/oh_interface.h | 22 + src/xrt/drivers/ohmd/oh_prober.c | 112 + src/xrt/include/xrt/xrt_compiler.h | 44 + src/xrt/include/xrt/xrt_compositor.h | 341 ++ src/xrt/include/xrt/xrt_config.h | 30 + src/xrt/include/xrt/xrt_defines.h | 196 + src/xrt/include/xrt/xrt_device.h | 174 + src/xrt/include/xrt/xrt_documentation.h | 22 + src/xrt/include/xrt/xrt_gfx_gl.h | 28 + src/xrt/include/xrt/xrt_gfx_vk.h | 53 + src/xrt/include/xrt/xrt_gfx_xlib.h | 39 + src/xrt/include/xrt/xrt_openxr_includes.h | 31 + src/xrt/include/xrt/xrt_prober.h | 42 + src/xrt/include/xrt/xrt_vulkan_includes.h | 13 + src/xrt/state_trackers/CMakeLists.txt | 47 + src/xrt/state_trackers/dev/README.md | 6 + src/xrt/state_trackers/oxr/oxr_api_action.c | 305 ++ src/xrt/state_trackers/oxr/oxr_api_debug.c | 106 + src/xrt/state_trackers/oxr/oxr_api_funcs.h | 534 +++ src/xrt/state_trackers/oxr/oxr_api_instance.c | 219 + .../state_trackers/oxr/oxr_api_negotiate.c | 269 ++ src/xrt/state_trackers/oxr/oxr_api_session.c | 228 + src/xrt/state_trackers/oxr/oxr_api_space.c | 125 + .../state_trackers/oxr/oxr_api_swapchain.c | 146 + src/xrt/state_trackers/oxr/oxr_api_system.c | 297 ++ src/xrt/state_trackers/oxr/oxr_api_verify.h | 157 + src/xrt/state_trackers/oxr/oxr_event.cpp | 148 + src/xrt/state_trackers/oxr/oxr_instance.c | 155 + src/xrt/state_trackers/oxr/oxr_logger.cpp | 158 + src/xrt/state_trackers/oxr/oxr_logger.h | 69 + src/xrt/state_trackers/oxr/oxr_objects.h | 585 +++ src/xrt/state_trackers/oxr/oxr_session.c | 498 +++ src/xrt/state_trackers/oxr/oxr_session_gl.c | 46 + src/xrt/state_trackers/oxr/oxr_session_vk.c | 49 + src/xrt/state_trackers/oxr/oxr_space.c | 260 ++ src/xrt/state_trackers/oxr/oxr_swapchain.c | 115 + src/xrt/state_trackers/oxr/oxr_swapchain_gl.c | 72 + src/xrt/state_trackers/oxr/oxr_swapchain_vk.c | 75 + src/xrt/state_trackers/oxr/oxr_system.c | 192 + src/xrt/state_trackers/oxr/oxr_two_call.h | 40 + src/xrt/state_trackers/oxr/oxr_verify.cpp | 145 + src/xrt/state_trackers/oxr/oxr_vulkan.c | 129 + src/xrt/targets/CMakeLists.txt | 8 + src/xrt/targets/openxr/CMakeLists.txt | 98 + src/xrt/targets/openxr/libopenxr.version | 4 + src/xrt/targets/openxr/target.c | 102 + 122 files changed, 27995 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 CONTRIBUTING.md create mode 100644 cmake/FindHIDAPI.cmake create mode 100644 cmake/FindWayland.cmake create mode 100644 cmake/SPIR-V.cmake create mode 100644 doc/CMakeLists.txt create mode 100644 doc/Doxyfile.in create mode 100644 doc/roadmap.md create mode 100755 scripts/format-project.sh create mode 100644 src/CMakeLists.txt create mode 100644 src/external/glad/gl.c create mode 100644 src/external/glad/gl.h create mode 100644 src/external/openxr_includes/loader_interfaces.h create mode 100644 src/external/openxr_includes/openxr.h create mode 100644 src/external/openxr_includes/openxr_platform.h create mode 100644 src/external/openxr_includes/openxr_platform_defines.h create mode 100644 src/xrt/.clang-format create mode 100644 src/xrt/CMakeLists.txt create mode 100644 src/xrt/auxiliary/CMakeLists.txt create mode 100644 src/xrt/auxiliary/math/m_api.h create mode 100644 src/xrt/auxiliary/math/m_base.cpp create mode 100644 src/xrt/auxiliary/math/m_eigen_interop.h create mode 100644 src/xrt/auxiliary/math/m_optics.c create mode 100644 src/xrt/auxiliary/math/m_quatexpmap.cpp create mode 100644 src/xrt/auxiliary/util/u_debug.c create mode 100644 src/xrt/auxiliary/util/u_debug.h create mode 100644 src/xrt/auxiliary/util/u_device.c create mode 100644 src/xrt/auxiliary/util/u_device.h create mode 100644 src/xrt/auxiliary/util/u_misc.c create mode 100644 src/xrt/auxiliary/util/u_misc.h create mode 100644 src/xrt/auxiliary/util/u_time.cpp create mode 100644 src/xrt/auxiliary/util/u_time.h create mode 100644 src/xrt/compositor/CMakeLists.txt create mode 100644 src/xrt/compositor/client/comp_gl_api.c create mode 100644 src/xrt/compositor/client/comp_gl_api.h create mode 100644 src/xrt/compositor/client/comp_gl_client.c create mode 100644 src/xrt/compositor/client/comp_gl_client.h create mode 100644 src/xrt/compositor/client/comp_vk_client.c create mode 100644 src/xrt/compositor/client/comp_vk_client.h create mode 100644 src/xrt/compositor/client/comp_xlib_client.c create mode 100644 src/xrt/compositor/client/comp_xlib_client.h create mode 100644 src/xrt/compositor/common/comp_vk.c create mode 100644 src/xrt/compositor/common/comp_vk.h create mode 100644 src/xrt/compositor/common/comp_vk_swapchain.c create mode 100644 src/xrt/compositor/common/comp_vk_swapchain.h create mode 100644 src/xrt/compositor/main/comp_client_interface.h create mode 100644 src/xrt/compositor/main/comp_compositor.c create mode 100644 src/xrt/compositor/main/comp_compositor.h create mode 100644 src/xrt/compositor/main/comp_distortion.c create mode 100644 src/xrt/compositor/main/comp_distortion.h create mode 100644 src/xrt/compositor/main/comp_glue_gl.c create mode 100644 src/xrt/compositor/main/comp_glue_vk.c create mode 100644 src/xrt/compositor/main/comp_glue_xlib.c create mode 100644 src/xrt/compositor/main/comp_renderer.c create mode 100644 src/xrt/compositor/main/comp_renderer.h create mode 100644 src/xrt/compositor/main/comp_settings.c create mode 100644 src/xrt/compositor/main/comp_settings.h create mode 100644 src/xrt/compositor/main/comp_swapchain.c create mode 100644 src/xrt/compositor/main/comp_window.h create mode 100644 src/xrt/compositor/main/comp_window_direct_mode.cpp create mode 100644 src/xrt/compositor/main/comp_window_wayland.cpp create mode 100644 src/xrt/compositor/main/comp_window_xcb.cpp create mode 100644 src/xrt/compositor/shaders/CMakeLists.txt create mode 100644 src/xrt/compositor/shaders/distortion.vert create mode 100644 src/xrt/compositor/shaders/none.frag create mode 100644 src/xrt/compositor/shaders/panotools.frag create mode 100644 src/xrt/compositor/shaders/vive.frag create mode 100644 src/xrt/drivers/CMakeLists.txt create mode 100644 src/xrt/drivers/hdk/hdk_device.cpp create mode 100644 src/xrt/drivers/hdk/hdk_device.h create mode 100644 src/xrt/drivers/hdk/hdk_interface.h create mode 100644 src/xrt/drivers/hdk/hdk_prober.c create mode 100644 src/xrt/drivers/ohmd/oh_device.c create mode 100644 src/xrt/drivers/ohmd/oh_device.h create mode 100644 src/xrt/drivers/ohmd/oh_interface.h create mode 100644 src/xrt/drivers/ohmd/oh_prober.c create mode 100644 src/xrt/include/xrt/xrt_compiler.h create mode 100644 src/xrt/include/xrt/xrt_compositor.h create mode 100644 src/xrt/include/xrt/xrt_config.h create mode 100644 src/xrt/include/xrt/xrt_defines.h create mode 100644 src/xrt/include/xrt/xrt_device.h create mode 100644 src/xrt/include/xrt/xrt_documentation.h create mode 100644 src/xrt/include/xrt/xrt_gfx_gl.h create mode 100644 src/xrt/include/xrt/xrt_gfx_vk.h create mode 100644 src/xrt/include/xrt/xrt_gfx_xlib.h create mode 100644 src/xrt/include/xrt/xrt_openxr_includes.h create mode 100644 src/xrt/include/xrt/xrt_prober.h create mode 100644 src/xrt/include/xrt/xrt_vulkan_includes.h create mode 100644 src/xrt/state_trackers/CMakeLists.txt create mode 100644 src/xrt/state_trackers/dev/README.md create mode 100644 src/xrt/state_trackers/oxr/oxr_api_action.c create mode 100644 src/xrt/state_trackers/oxr/oxr_api_debug.c create mode 100644 src/xrt/state_trackers/oxr/oxr_api_funcs.h create mode 100644 src/xrt/state_trackers/oxr/oxr_api_instance.c create mode 100644 src/xrt/state_trackers/oxr/oxr_api_negotiate.c create mode 100644 src/xrt/state_trackers/oxr/oxr_api_session.c create mode 100644 src/xrt/state_trackers/oxr/oxr_api_space.c create mode 100644 src/xrt/state_trackers/oxr/oxr_api_swapchain.c create mode 100644 src/xrt/state_trackers/oxr/oxr_api_system.c create mode 100644 src/xrt/state_trackers/oxr/oxr_api_verify.h create mode 100644 src/xrt/state_trackers/oxr/oxr_event.cpp create mode 100644 src/xrt/state_trackers/oxr/oxr_instance.c create mode 100644 src/xrt/state_trackers/oxr/oxr_logger.cpp create mode 100644 src/xrt/state_trackers/oxr/oxr_logger.h create mode 100644 src/xrt/state_trackers/oxr/oxr_objects.h create mode 100644 src/xrt/state_trackers/oxr/oxr_session.c create mode 100644 src/xrt/state_trackers/oxr/oxr_session_gl.c create mode 100644 src/xrt/state_trackers/oxr/oxr_session_vk.c create mode 100644 src/xrt/state_trackers/oxr/oxr_space.c create mode 100644 src/xrt/state_trackers/oxr/oxr_swapchain.c create mode 100644 src/xrt/state_trackers/oxr/oxr_swapchain_gl.c create mode 100644 src/xrt/state_trackers/oxr/oxr_swapchain_vk.c create mode 100644 src/xrt/state_trackers/oxr/oxr_system.c create mode 100644 src/xrt/state_trackers/oxr/oxr_two_call.h create mode 100644 src/xrt/state_trackers/oxr/oxr_verify.cpp create mode 100644 src/xrt/state_trackers/oxr/oxr_vulkan.c create mode 100644 src/xrt/targets/CMakeLists.txt create mode 100644 src/xrt/targets/openxr/CMakeLists.txt create mode 100644 src/xrt/targets/openxr/libopenxr.version create mode 100644 src/xrt/targets/openxr/target.c 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 <https://www.freedesktop.org/wiki/CodeOfConduct/>, +> 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 <https://www.freedesktop.org/wiki/CodeOfConduct/>, +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 <jakob@collabora.com> + * Ryan Pavlik <ryan.pavlik@collabora.com> +* freedesktop.org contacts: see most recent list at <https://www.freedesktop.org/wiki/CodeOfConduct/> + +## 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 <https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>, +> and from the freedesktop.org-specific version of that code, +> available at <https://www.freedesktop.org/wiki/CodeOfConduct/> +> +> +> 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 <rpavlik@iastate.edu> <abiryan@ryand.net> +# 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 <mgraesslin@kde.org> +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +IF (NOT WIN32) + 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}="<b>\1</b>. \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 <section_label> ... \endif and \cond <section_label> +# ... \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: +# +# <filter> <input-file> +# +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> 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 <access key> + S +# (what the <access key> is depends on the OS and browser, but it is typically +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down +# key> to jump into the search results window, the results can be navigated +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel +# the search. The filter options can be selected when the cursor is inside the +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> +# to select a filter and <Enter> or <escape> 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <glad/gl.h> + +#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(<winapifamily.h>) + #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 <winapifamily.h> + #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 <stddef.h> +#include <KHR/khrplatform.h> +#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 <inttypes.h> +#elif defined(__sun__) || defined(__digital__) +#include <inttypes.h> +#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 <inttypes.h> +#elif defined(__SCO__) || defined(__USLC__) +#include <stdint.h> +#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 <stdint.h> +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include <inttypes.h> +#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 <marky@lunarg.com> +// + +#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 <stddef.h> + +#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 <stdint.h> +#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 <jakob@collabora.com> + * + * @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 <jakob@collabora.com> + * @author Ryan Pavlik <ryan.pavlik@collabora.com> + */ + +#include <Eigen/Core> +#include <Eigen/Geometry> + +#include <assert.h> + +#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<float>::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 <ryan.pavlik@collabora.com> + */ + +#pragma once + +#ifndef __cplusplus +#error "This header only usable from C++" +#endif + +#include "math/m_api.h" + +#include <Eigen/Core> +#include <Eigen/Geometry> + +/*! + * @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<const Eigen::Quaternionf> +map_quat(const struct xrt_quat& q) +{ + return Eigen::Map<const Eigen::Quaternionf>{&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<Eigen::Quaternionf> +map_quat(struct xrt_quat& q) +{ + return Eigen::Map<Eigen::Quaternionf>{&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<const Eigen::Vector3f> +map_vec3(const struct xrt_vec3& v) +{ + return Eigen::Map<const Eigen::Vector3f>{&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<Eigen::Vector3f> +map_vec3(struct xrt_vec3& v) +{ + return Eigen::Map<Eigen::Vector3f>{&v.x}; +} + +/* + * + * Pose deconstruction helpers. + * + */ + +/*! + * Return a Eigen type wrapping a pose's orientation (const). + */ +static inline Eigen::Map<const Eigen::Quaternionf> +orientation(const struct xrt_pose& pose) +{ + return map_quat(pose.orientation); +} + +/*! + * Return a Eigen type wrapping a pose's orientation. + */ +static inline Eigen::Map<Eigen::Quaternionf> +orientation(struct xrt_pose& pose) +{ + return map_quat(pose.orientation); +} + +/*! + * Return a Eigen type wrapping a pose's position (const). + */ +static inline Eigen::Map<const Eigen::Vector3f> +position(const struct xrt_pose& pose) +{ + return map_vec3(pose.position); +} + +/*! + * Return a Eigen type wrapping a pose's position. + */ +static inline Eigen::Map<Eigen::Vector3f> +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 <ryan.pavlik@collabora.com> + */ + + +#include "m_api.h" +#include "util/u_debug.h" +#include <math.h> +#include <assert.h> +#include <stdio.h> + +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 <ryan.pavlik@collabora.com> + * + * Based in part on inc/osvr/Util/EigenQuatExponentialMap.h in OSVR-Core + */ + +#include <Eigen/Core> +#include <Eigen/Geometry> + +#include <assert.h> + +#include "math/m_api.h" +#include "math/m_eigen_interop.h" + +// anonymous namespace for internal types +namespace { +template <typename Scalar> struct FourthRootMachineEps; +template <> struct FourthRootMachineEps<double> +{ + /// machine epsilon is 1e-53, so fourth root is roughly 1e-13 + static double + get() + { + return 1.e-13; + } +}; +template <> struct FourthRootMachineEps<float> +{ + /// 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 <typename Scalar> +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<Scalar>::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 <typename Derived> +inline Eigen::Quaternion<typename Derived::Scalar> +quat_exp(Eigen::MatrixBase<Derived> 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<Scalar> 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 <typename Scalar> +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 <typename Scalar> +inline Eigen::Matrix<Scalar, 3, 1> +quat_ln(Eigen::Quaternion<Scalar> 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<Scalar>(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 <jakob@collabora.com> + * + * Debug get option helpers heavily inspired from mesa ones. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#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 <jakob@collabora.com> + * + * 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 <jakob@collabora.com> + */ + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> + +#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 <jakob@collabora.com> + */ + +#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 <jakob@collabora.com> + */ + +#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 <jakob@collabora.com> + */ + +#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 <ryan.pavlik@collabora.com> + */ + +#include "u_time.h" + +#include <chrono> +#include <new> +#include <assert.h> +#include <stdlib.h> + +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<nanoseconds>(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<seconds>(sinceEpoch); + sinceEpoch -= secondsSinceEpoch; + out->tv_sec = secondsSinceEpoch.count(); + out->tv_nsec = duration_cast<nanoseconds>(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<system_clock, nanoseconds>{ + duration_cast<system_clock::duration>(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<nanoseconds>(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 <ryan.pavlik@collabora.com> + * + * @see time_state + */ + +#pragma once + +#include <stdint.h> +#include <time.h> + +#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 <jakob@collabora.com> + * @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 <jakob@collabora.com> + * @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 <jakob@collabora.com> + * @ingroup comp_client + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#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 <jakob@collabora.com> + * @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 <jakob@collabora.com> + * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com> + * @ingroup comp_client + */ + +#include <stdio.h> +#include <stdlib.h> + +#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 <jakob@collabora.com> + * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com> + * @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 <jakob@collabora.com> + * @ingroup comp_client + */ + +#include <stdio.h> +#include <stdlib.h> + +#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 <jakob@collabora.com> + * @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 <jakob@collabora.com> + * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com> + * @ingroup comp_common + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#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 <jakob@collabora.com> + * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com> + * @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 <lubosz.sarnecki@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup comp_client + */ + + +#include <stdio.h> +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#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 <lubosz.sarnecki@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @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 <jakob@collabora.com> + * @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 <jakob@collabora.com> + * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com> + * @ingroup comp + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +#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 <jakob@collabora.com> + * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com> + * @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 <lubosz.sarnecki@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup comp + */ + +#include <stdio.h> +#include <string.h> + +#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 <lubosz.sarnecki@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @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 <jakob@collabora.com> + * @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 <jakob@collabora.com> + * @ingroup comp + */ + +#include <stdlib.h> + +#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 <jakob@collabora.com> + * @ingroup comp + */ + +#include <stdio.h> +#include <stdlib.h> + +#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 <lubosz.sarnecki@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup comp + */ + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> + +#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 <lubosz.sarnecki@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @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 <lubosz.sarnecki@collabora.com> + * @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 <lubosz.sarnecki@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @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 <jakob@collabora.com> + * @ingroup comp + */ + +#include <stdio.h> +#include <stdlib.h> + +#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 <lubosz.sarnecki@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @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 <lubosz.sarnecki@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup comp + */ + +#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT + +#include <xcb/xcb.h> +#include <xcb/randr.h> +#include <X11/extensions/Xrandr.h> + +#include <map> +#include <string> +#include <vector> +#include <utility> +#include <cstring> + +#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<uint32_t, xcb_randr_mode_info_t> modes = {}; + + std::vector<comp_window_direct_display> 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<uint32_t, xcb_randr_mode_info_t>( + 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 <lubosz.sarnecki@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup comp + */ + +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + +#include <poll.h> +#include <linux/input.h> +#include <wayland-client.h> +#include "xdg-shell-unstable-v6.h" + +#include <map> +#include <vector> +#include <string> +#include <utility> +#include <cstring> + +#include "xrt/xrt_compiler.h" +#include "main/comp_window.h" + + +/* + * + * Private structs. + * + */ + +/*! + * Wayland display mode. + */ +struct comp_window_wayland_mode +{ + std::pair<int, int> size; + int refresh; +}; + +/*! + * A single Wayland display. + */ +struct comp_window_wayland_display +{ + wl_output *output; + std::string make; + std::string model; + std::vector<comp_window_wayland_mode> modes; + std::pair<int, int> physical_size_mm; + std::pair<int, int> 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<comp_window_wayland_display> 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 <lubosz.sarnecki@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup comp + */ + +#ifdef VK_USE_PLATFORM_XCB_KHR + +#include <xcb/xcb.h> +#include <xcb/randr.h> + +#include <string> +#include <vector> +#include <utility> +#include <cstring> + +#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<int16_t, int16_t> position; + std::pair<uint16_t, uint16_t> 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<comp_window_xcb_display> 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 <lubosz.sarnecki@collabora.com> +#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 <jakob@collabora.com> +#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 <jsarrett@gmail.com> +// Author: Bastiaan Olij <mux213@gmail.com> +// Author: Lubosz Sarnecki <lubosz.sarnecki@collabora.com> +#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 <philipp.zabel@gmail.com> +// Author: Lubosz Sarnecki <lubosz.sarnecki@collabora.com> +#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 <ryan.pavlik@collabora.com> + * @author Kevin M. Godby <kevin@godby.org> + */ + + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <type_traits> + +#include <hidapi.h> + +#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 <size_t INTEGER_BITS, size_t FRACTIONAL_BITS, typename IntegerType> +static inline float +fromFixedPoint(IntegerType v) +{ + constexpr size_t SIGN_BIT = std::is_signed<IntegerType>::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<float>(v) / (1 << FRACTIONAL_BITS); +} + +static inline uint16_t +hdk_get_le_uint16(uint8_t *&bufPtr) +{ + assert(bufPtr != nullptr); + uint16_t ret = static_cast<uint16_t>(*bufPtr) | + (static_cast<uint16_t>(*(bufPtr + 1)) << 8); + bufPtr += 2; + return ret; +} + +static inline int16_t +hdk_get_le_int16(uint8_t *&bufPtr) +{ + return static_cast<int16_t>(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 <jakob@collabora.com> + * @author Ryan Pavlik <ryan.pavlik@collabora.com> + */ + +#pragma once + +#include <hidapi.h> + + +#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 <jakob@collabora.com> + * @author Ryan Pavlik <ryan.pavlik@collabora.com> + */ + +#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 <jakob@collabora.com> + * @author Ryan Pavlik <ryan.pavlik@collabora.com> + */ + +#include <stdio.h> +#include <stdlib.h> +#include <wchar.h> + +#include <hidapi.h> +#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 <jakob@collabora.com> + */ + + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "openhmd.h" + +#include "math/m_api.h" +#include "xrt/xrt_device.h" +#include "util/u_misc.h" +#include "util/u_debug.h" +#include "util/u_device.h" + +#include "oh_device.h" + +// Define this if you have the appropriately hacked-up OpenHMD version. +#undef OHMD_HAVE_ANG_VEL + +static void +oh_device_destroy(struct xrt_device *xdev) +{ + struct oh_device *ohd = oh_device(xdev); + + if (ohd->dev != NULL) { + ohmd_close_device(ohd->dev); + ohd->dev = NULL; + } + + free(ohd); +} + +static void +oh_device_get_tracked_pose(struct xrt_device *xdev, + struct xrt_space_relation *out_relation) +{ + struct oh_device *ohd = oh_device(xdev); + struct xrt_quat quat = {0.f, 0.f, 0.f, 1.f}; + ohmd_ctx_update(ohd->ctx); + ohmd_device_getf(ohd->dev, OHMD_ROTATION_QUAT, &quat.x); + out_relation->pose.orientation = quat; + //! @todo assuming that orientation is actually currently tracked. + out_relation->relation_flags = (enum xrt_space_relation_flags)( + XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | + XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT); + +#ifdef OHMD_HAVE_ANG_VEL + if (!ohd->skip_ang_vel) { + struct xrt_vec3 ang_vel; + if (0 == ohmd_device_getf(ohd->dev, OHMD_ANGULAR_VELOCITY, + &ang_vel.x)) { + out_relation->angular_velocity = ang_vel; + out_relation->relation_flags = + (enum xrt_space_relation_flags)( + out_relation->relation_flags | + XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT); + OH_SPEW( + ohd, + "GET_TRACKED_POSE (%f, %f, %f, %f) (%f, %f, %f)", + quat.x, quat.y, quat.z, quat.w, ang_vel.x, + ang_vel.y, ang_vel.z); + return; + } else { + // we now know this device doesn't return angular + // velocity. + ohd->skip_ang_vel = true; + } + } +#endif + OH_SPEW(ohd, "GET_TRACKED_POSE (%f, %f, %f, %f)", quat.x, quat.y, + quat.z, quat.w); +} + +static void +oh_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; +} + +struct display_info +{ + float w_meters; + float h_meters; + int w_pixels; + int h_pixels; +}; + +struct device_info +{ + struct display_info display; + + float lens_horizontal_separation; + float lens_vertical_position; + + float pano_distortion_k[4]; + float pano_aberration_k[4]; + float pano_warp_scale; + + struct + { + float fov; + + struct display_info display; + + float lens_center_x_meters; + float lens_center_y_meters; + } views[2]; +}; + +static struct device_info +get_info(struct oh_device *ohd) +{ + struct device_info info = {0}; + + // clang-format off + ohmd_device_getf(ohd->dev, OHMD_SCREEN_HORIZONTAL_SIZE, &info.display.w_meters); + ohmd_device_getf(ohd->dev, OHMD_SCREEN_VERTICAL_SIZE, &info.display.h_meters); + ohmd_device_getf(ohd->dev, OHMD_LENS_HORIZONTAL_SEPARATION, &info.lens_horizontal_separation); + ohmd_device_getf(ohd->dev, OHMD_LENS_VERTICAL_POSITION, &info.lens_vertical_position); + ohmd_device_getf(ohd->dev, OHMD_LEFT_EYE_FOV, &info.views[0].fov); + ohmd_device_getf(ohd->dev, OHMD_RIGHT_EYE_FOV, &info.views[1].fov); + ohmd_device_geti(ohd->dev, OHMD_SCREEN_HORIZONTAL_RESOLUTION, &info.display.w_pixels); + ohmd_device_geti(ohd->dev, OHMD_SCREEN_VERTICAL_RESOLUTION, &info.display.h_pixels); + ohmd_device_getf(ohd->dev, OHMD_UNIVERSAL_DISTORTION_K, &info.pano_distortion_k[0]); + ohmd_device_getf(ohd->dev, OHMD_UNIVERSAL_ABERRATION_K, &info.pano_aberration_k[0]); + + /* + * Assumptions made here: + * + * - There is a single, continuous, flat display serving both eyes, with + * no dead space/gap between eyes. + * - This single panel is (effectively) perpendicular to the forward + * (-Z) direction, with edges aligned with the X and Y axes. + * - Lens position is symmetrical about the center ("bridge of nose"). + * - Pixels are square and uniform across the entirety of the panel. + * + * If any of these are not true, then either the rendering will + * be inaccurate, or the properties will have to be "fudged" to + * make the math work. + */ + + info.views[0].display.w_meters = info.display.w_meters / 2.0; + info.views[0].display.h_meters = info.display.h_meters; + info.views[1].display.w_meters = info.display.w_meters / 2.0; + info.views[1].display.h_meters = info.display.h_meters; + + info.views[0].display.w_pixels = info.display.w_pixels / 2; + info.views[0].display.h_pixels = info.display.h_pixels; + info.views[1].display.w_pixels = info.display.w_pixels / 2; + info.views[1].display.h_pixels = info.display.h_pixels; + + /* + * Assuming the lenses are centered vertically on the + * display. It's not universal, but 0.5 COP on Y is more + * common than on X, and it looked like many of the + * driver lens_vpos values were copy/pasted or marked + * with FIXME. Safer to fix it to 0.5 than risk an + * extreme geometry mismatch. + */ + + const double cop_y = 0.5; + const double h_1 = cop_y * info.display.h_meters; + + //! @todo This are probably all wrong! + info.views[0].lens_center_x_meters = info.views[0].display.w_meters - info.lens_horizontal_separation / 2.0; + info.views[0].lens_center_y_meters = h_1; + + info.views[1].lens_center_x_meters = info.lens_horizontal_separation / 2.0; + info.views[1].lens_center_y_meters = h_1; + + //! @todo This is most definitely wrong! + //! 3Glasses likes the opposite better. + info.pano_warp_scale = + (info.views[0].lens_center_x_meters > info.views[0].lens_center_x_meters) ? + info.views[0].lens_center_x_meters : + info.views[0].lens_center_x_meters; + // clang-format on + + return info; +} + +struct oh_device * +oh_device_create(ohmd_context *ctx, + ohmd_device *dev, + const char *prod, + bool print_spew, + bool print_debug) +{ + struct oh_device *ohd = + (struct oh_device *)calloc(1, sizeof(struct oh_device)); + ohd->base.destroy = oh_device_destroy; + ohd->base.get_tracked_pose = oh_device_get_tracked_pose; + ohd->base.get_view_pose = oh_device_get_view_pose; + ohd->ctx = ctx; + ohd->dev = dev; + ohd->print_spew = print_spew; + ohd->print_debug = print_debug; + + const struct device_info info = get_info(ohd); + + { + /* right eye */ + if (!math_compute_fovs(info.views[1].display.w_meters, + info.views[1].lens_center_x_meters, + info.views[1].fov, + info.views[1].display.h_meters, + info.views[1].lens_center_y_meters, 0, + &ohd->base.views[1].fov)) { + OH_ERROR( + ohd, + "Failed to compute the partial fields of view."); + free(ohd); + return NULL; + } + } + { + /* left eye - just mirroring right eye now */ + ohd->base.views[0].fov.angle_up = + ohd->base.views[1].fov.angle_up; + ohd->base.views[0].fov.angle_down = + ohd->base.views[1].fov.angle_down; + + ohd->base.views[0].fov.angle_left = + -ohd->base.views[1].fov.angle_right; + ohd->base.views[0].fov.angle_right = + -ohd->base.views[1].fov.angle_left; + } + + // clang-format off + // Main display. + ohd->base.distortion.models = XRT_DISTORTION_MODEL_PANOTOOLS; + ohd->base.distortion.preferred = XRT_DISTORTION_MODEL_PANOTOOLS; + ohd->base.screens[0].w_pixels = info.display.w_pixels; + ohd->base.screens[0].h_pixels = info.display.h_pixels; + ohd->base.distortion.pano.distortion_k[0] = info.pano_distortion_k[0]; + ohd->base.distortion.pano.distortion_k[1] = info.pano_distortion_k[1]; + ohd->base.distortion.pano.distortion_k[2] = info.pano_distortion_k[2]; + ohd->base.distortion.pano.distortion_k[3] = info.pano_distortion_k[3]; + ohd->base.distortion.pano.aberration_k[0] = info.pano_aberration_k[0]; + ohd->base.distortion.pano.aberration_k[1] = info.pano_aberration_k[1]; + ohd->base.distortion.pano.aberration_k[2] = info.pano_aberration_k[2]; + ohd->base.distortion.pano.warp_scale = info.pano_warp_scale; + + // Left + ohd->base.views[0].display.w_meters = info.views[0].display.w_meters; + ohd->base.views[0].display.h_meters = info.views[0].display.h_meters; + ohd->base.views[0].lens_center.x_meters = info.views[0].lens_center_x_meters; + ohd->base.views[0].lens_center.y_meters = info.views[0].lens_center_y_meters; + ohd->base.views[0].display.w_pixels = info.views[0].display.w_pixels; + ohd->base.views[0].display.h_pixels = info.views[0].display.h_pixels; + ohd->base.views[0].viewport.x_pixels = 0; + ohd->base.views[0].viewport.y_pixels = 0; + ohd->base.views[0].viewport.w_pixels = info.views[0].display.w_pixels; + ohd->base.views[0].viewport.h_pixels = info.views[0].display.h_pixels; + ohd->base.views[0].rot = u_device_rotation_ident; + + // Right + ohd->base.views[1].display.w_meters = info.views[1].display.w_meters; + ohd->base.views[1].display.h_meters = info.views[1].display.h_meters; + ohd->base.views[1].lens_center.x_meters = info.views[1].lens_center_x_meters; + ohd->base.views[1].lens_center.y_meters = info.views[1].lens_center_y_meters; + ohd->base.views[1].display.w_pixels = info.views[1].display.w_pixels; + ohd->base.views[1].display.h_pixels = info.views[1].display.h_pixels; + ohd->base.views[1].viewport.x_pixels = info.views[0].display.w_pixels; + ohd->base.views[1].viewport.y_pixels = 0; + ohd->base.views[1].viewport.w_pixels = info.views[1].display.w_pixels; + ohd->base.views[1].viewport.h_pixels = info.views[1].display.h_pixels; + ohd->base.views[1].rot = u_device_rotation_ident; + // clang-format on + + // Find any needed quirks. + bool quirk_rotate_right = false; + bool quirk_rotate_inwards = false; + bool quirk_video_see_through = false; + bool quirk_video_distortion_none = false; + bool quirk_video_distortion_vive = false; + bool quirk_left_center_pano_scale = false; + + // Needs to be rotated. + if (strcmp(prod, "3Glasses-D3V2") == 0) { + quirk_rotate_right = true; + quirk_left_center_pano_scale = true; + } + + if (strcmp(prod, "HTC Vive") == 0) { + quirk_video_distortion_vive = true; + quirk_video_see_through = true; + } + + if (strcmp(prod, "LGR100") == 0) { + quirk_rotate_inwards = true; + } + + if (strcmp(prod, "External Device") == 0) { + quirk_video_distortion_none = true; + } + + // Which blend modes does the device support. + ohd->base.blend_mode |= XRT_BLEND_MODE_OPAQUE; + if (quirk_video_see_through) { + ohd->base.blend_mode |= XRT_BLEND_MODE_ALPHA_BLEND; + } + + if (quirk_video_distortion_vive) { + ohd->base.distortion.models |= XRT_DISTORTION_MODEL_VIVE; + ohd->base.distortion.preferred = XRT_DISTORTION_MODEL_VIVE; + } + + if (quirk_video_distortion_none) { + ohd->base.distortion.models = XRT_DISTORTION_MODEL_NONE; + ohd->base.distortion.preferred = XRT_DISTORTION_MODEL_NONE; + } + + if (quirk_left_center_pano_scale) { + ohd->base.distortion.pano.warp_scale = + info.views[0].lens_center_x_meters; + } + + if (quirk_rotate_right) { + int w = info.display.w_pixels; + int h = info.display.h_pixels; + + ohd->base.screens[0].w_pixels = h; + ohd->base.screens[0].h_pixels = w; + + ohd->base.views[0].viewport.x_pixels = 0; + ohd->base.views[0].viewport.y_pixels = 0; + ohd->base.views[0].viewport.w_pixels = h; + ohd->base.views[0].viewport.h_pixels = w / 2; + ohd->base.views[0].rot = u_device_rotation_right; + + ohd->base.views[1].viewport.x_pixels = 0; + ohd->base.views[1].viewport.y_pixels = w / 2; + ohd->base.views[1].viewport.w_pixels = h; + ohd->base.views[1].viewport.h_pixels = w / 2; + ohd->base.views[1].rot = u_device_rotation_right; + } + + if (quirk_rotate_inwards) { + ohd->base.views[0].rot = u_device_rotation_right; + ohd->base.views[1].rot = u_device_rotation_left; + } + + if (ohd->print_debug) { + u_device_dump_config(&ohd->base, __func__, prod); + } + + return ohd; +} diff --git a/src/xrt/drivers/ohmd/oh_device.h b/src/xrt/drivers/ohmd/oh_device.h new file mode 100644 index 000000000..02974ffb3 --- /dev/null +++ b/src/xrt/drivers/ohmd/oh_device.h @@ -0,0 +1,69 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Interface to OpenHMD driver code. + * @author Jakob Bornecrantz <jakob@collabora.com> + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + +struct oh_device +{ + struct xrt_device base; + ohmd_context *ctx; + ohmd_device *dev; + + bool skip_ang_vel; + + bool print_spew; + bool print_debug; +}; + +static inline struct oh_device * +oh_device(struct xrt_device *xdev) +{ + return (struct oh_device *)xdev; +} + +struct oh_device * +oh_device_create(ohmd_context *ctx, + ohmd_device *dev, + const char *prod, + bool print_spew, + bool print_debug); + +#define OH_SPEW(c, ...) \ + do { \ + if (c->print_spew) { \ + fprintf(stderr, "%s - ", __func__); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + } \ + } while (false) + +#define OH_DEBUG(c, ...) \ + do { \ + if (c->print_debug) { \ + fprintf(stderr, "%s - ", __func__); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + } \ + } while (false) + +#define OH_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/ohmd/oh_interface.h b/src/xrt/drivers/ohmd/oh_interface.h new file mode 100644 index 000000000..3b7f941e5 --- /dev/null +++ b/src/xrt/drivers/ohmd/oh_interface.h @@ -0,0 +1,22 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Interface to OpenHMD driver code. + * @author Jakob Bornecrantz <jakob@collabora.com> + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + +struct xrt_prober* +oh_create_prober(); + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/drivers/ohmd/oh_prober.c b/src/xrt/drivers/ohmd/oh_prober.c new file mode 100644 index 000000000..96df01557 --- /dev/null +++ b/src/xrt/drivers/ohmd/oh_prober.c @@ -0,0 +1,112 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief OpenHMD prober code. + * @author Jakob Bornecrantz <jakob@collabora.com> + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "openhmd.h" +#include "xrt/xrt_prober.h" + +#include "util/u_misc.h" +#include "util/u_debug.h" + +#include "oh_device.h" + + +DEBUG_GET_ONCE_BOOL_OPTION(oh_spew, "OH_PRINT_SPEW", false) +DEBUG_GET_ONCE_BOOL_OPTION(oh_debug, "OH_PRINT_DEBUG", false) + +struct oh_prober +{ + struct xrt_prober base; + ohmd_context *ctx; + bool print_spew; + bool print_debug; +}; + +static inline struct oh_prober * +oh_prober(struct xrt_prober *p) +{ + return (struct oh_prober *)p; +} + +static void +oh_prober_destroy(struct xrt_prober *p) +{ + struct oh_prober *ohp = oh_prober(p); + + if (ohp->ctx != NULL) { + ohmd_ctx_destroy(ohp->ctx); + ohp->ctx = NULL; + } + + free(ohp); +} + +static struct xrt_device * +oh_prober_autoprobe(struct xrt_prober *p) +{ + struct oh_prober *ohp = oh_prober(p); + + int device_idx = -1; + + /* Probe for devices */ + int num_devices = ohmd_ctx_probe(ohp->ctx); + + /* Then loop */ + for (int i = 0; i < num_devices; i++) { + int device_class = 0, device_flags = 0; + + ohmd_list_geti(ohp->ctx, i, OHMD_DEVICE_CLASS, &device_class); + ohmd_list_geti(ohp->ctx, i, OHMD_DEVICE_FLAGS, &device_flags); + + if (device_class != OHMD_DEVICE_CLASS_HMD) { + OH_DEBUG(ohp, "Rejecting device idx %i, is not a HMD.", + i); + continue; + } + + if (device_flags & OHMD_DEVICE_FLAGS_NULL_DEVICE) { + OH_DEBUG(ohp, + "Rejecting device idx %i, is a NULL device.", + i); + continue; + } + + OH_DEBUG(ohp, "Selecting device idx %i", i); + device_idx = i; + break; + } + + if (device_idx < 0) { + return NULL; + } + + const char *prod = ohmd_list_gets(ohp->ctx, device_idx, OHMD_PRODUCT); + ohmd_device *dev = ohmd_list_open_device(ohp->ctx, device_idx); + if (dev == NULL) { + return NULL; + } + + struct oh_device *ohd = oh_device_create( + ohp->ctx, dev, prod, ohp->print_spew, ohp->print_debug); + return &ohd->base; +} + +struct xrt_prober * +oh_create_prober() +{ + struct oh_prober *ohp = calloc(1, sizeof(struct oh_prober)); + ohp->base.destroy = oh_prober_destroy; + ohp->base.lelo_dallas_autoprobe = oh_prober_autoprobe; + ohp->ctx = ohmd_ctx_create(); + ohp->print_spew = debug_get_bool_option_oh_spew(); + ohp->print_debug = debug_get_bool_option_oh_debug(); + + return &ohp->base; +} diff --git a/src/xrt/include/xrt/xrt_compiler.h b/src/xrt/include/xrt/xrt_compiler.h new file mode 100644 index 000000000..344cb8927 --- /dev/null +++ b/src/xrt/include/xrt/xrt_compiler.h @@ -0,0 +1,44 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Header holding common defines. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup xrt_iface + */ + +#pragma once + + +/* + * C99 is not a high bar to reach. + */ +#include <stddef.h> +#include <stdint.h> +#include <stdbool.h> + + +/*! + * Array size helper. + */ +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + + +/* + * Printf helper attribute. + */ +#if defined(__GNUC__) +#define XRT_PRINTF_FORMAT(fmt, list) __attribute__((format(printf, fmt, list))) +#else +#define XRT_PRINTF_FORMAT(fmt, list) +#endif + + +/* + * To silence unused warnings. + */ +#if defined(__GNUC__) +#define XRT_MAYBE_UNUSED __attribute__((unused)) +#else +#define XRT_MAYBE_UNUSED +#endif diff --git a/src/xrt/include/xrt/xrt_compositor.h b/src/xrt/include/xrt/xrt_compositor.h new file mode 100644 index 000000000..23707fc6f --- /dev/null +++ b/src/xrt/include/xrt/xrt_compositor.h @@ -0,0 +1,341 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Header defining a XRT graphics provider. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup xrt_iface + */ + +#pragma once + +#include "xrt/xrt_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! + * Max swapchain images, artificial limit. + * + * @ingroup xrt_iface + */ +#define XRT_MAX_SWAPCHAIN_IMAGES 8 + +/*! + * Max formats supported by a compositor, artificial limit. + * + * @ingroup xrt_iface + */ +#define XRT_MAX_SWAPCHAIN_FORMATS 8 + +/*! + * Special flags for creating swapchain images. + * + * @ingroup xrt_iface + */ +enum xrt_swapchain_create_flags +{ + XRT_SWAPCHAIN_CREATE_STATIC_IMAGE = (1 << 0), +}; + +/*! + * Usage of the swapchain images. + * + * @ingroup xrt_iface + */ +enum xrt_swapchain_usage_bits +{ + XRT_SWAPCHAIN_USAGE_COLOR = (1 << 0), +}; + +/*! + * View type to be rendered to by the compositor. + * + * @ingroup xrt_iface + */ +enum xrt_view_type +{ + XRT_VIEW_TYPE_MONO = 1, + XRT_VIEW_TYPE_STEREO = 2, +}; + +/*! + * Common swapchain base. + * + * @ingroup xrt_iface + */ +struct xrt_swapchain +{ + /*! + * Number of images, the images themselves are on the subclasses. + */ + uint32_t num_images; + + /*! + * Must have called release_image before calling this function. + */ + void (*destroy)(struct xrt_swapchain *sc); + + /*! + * See xrWaitSwapchainImage, must make sure that no image is acquired + * before calling acquire_image. + */ + bool (*acquire_image)(struct xrt_swapchain *xc, uint32_t *index); + + /*! + * See xrWaitSwapchainImage, state tracker needs to track index. + */ + bool (*wait_image)(struct xrt_swapchain *xc, + uint64_t timeout, + uint32_t index); + + /*! + * See xrReleaseSwapchainImage, state tracker needs to track index. + */ + bool (*release_image)(struct xrt_swapchain *xc, uint32_t index); +}; + +/*! + * Common compositor base. + * + * @ingroup xrt_iface + */ +struct xrt_compositor +{ + /*! + * Number of formats. + */ + uint32_t num_formats; + + /*! + * Supported formats. + */ + int64_t formats[XRT_MAX_SWAPCHAIN_FORMATS]; + + /*! + * Create a swapchain with a set of images. + */ + struct xrt_swapchain *(*create_swapchain)( + 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); + + /*! + * Poll events from this compositor. + * + * This function is very much WIP. + */ + void (*poll_events)(struct xrt_compositor *xc, uint64_t *WIP); + + /*! + * This function is implicit in the OpenXR spec but made explicit here. + */ + void (*prepare_session)(struct xrt_compositor *xc); + + /*! + * See xrBeginSession. + */ + void (*begin_session)(struct xrt_compositor *xc, + enum xrt_view_type view_type); + + /*! + * See xrEndSession, unlike the OpenXR one the state tracker is + * responsible to call discard frame before calling this function. See + * discard_frame. + */ + void (*end_session)(struct xrt_compositor *xc); + + /*! + * See xrWaitFrame. + */ + void (*wait_frame)(struct xrt_compositor *xc, + int64_t *predicted_display_time, + int64_t *predicted_display_period); + + /*! + * See xrBeginFrame. + */ + void (*begin_frame)(struct xrt_compositor *xc); + + /*! + * This isn't in the OpenXR API but is explicit in the XRT interfaces. + * + * Two calls to xrBeginFrame will cause the state tracker to call. + * + * ```c + * xc->begin_frame(xc) + * xc->discard_frame(xc) + * xc->begin_frame(xc) + * ``` + */ + void (*discard_frame)(struct xrt_compositor *xc); + + /*! + * See xrEndFrame. + */ + void (*end_frame)(struct xrt_compositor *xc, + enum xrt_blend_mode blend_mode, + struct xrt_swapchain **xscs, + uint32_t *acquired_index, + uint32_t num_swapchains); + + /*! + * Teardown the compositor. + * + * The state tracker must have made sure that no frames or sessions are + * currently pending. See discard_frame, end_frame, end_session. + */ + void (*destroy)(struct xrt_compositor *xc); +}; + + +/* + * + * OpenGL interface. + * + */ + +/*! + * @ingroup xrt_iface comp_client + */ +struct xrt_swapchain_gl +{ + struct xrt_swapchain base; + + // GLuint + unsigned int images[XRT_MAX_SWAPCHAIN_IMAGES]; + // GLuint + unsigned int memory[XRT_MAX_SWAPCHAIN_IMAGES]; +}; + +/*! + * @ingroup xrt_iface comp_client + */ +struct xrt_compositor_gl +{ + struct xrt_compositor base; +}; + +static inline struct xrt_swapchain_gl * +xrt_swapchain_gl(struct xrt_swapchain *xsc) +{ + return (struct xrt_swapchain_gl *)xsc; +} + +static inline struct xrt_compositor_gl * +xrt_compositor_gl(struct xrt_compositor *xc) +{ + return (struct xrt_compositor_gl *)xc; +} + + +/* + * + * Vulkan interface. + * + */ + +typedef struct VkImage_T *VkImage; +typedef struct VkDeviceMemory_T *VkDeviceMemory; + +/*! + * Base clase for a Vulkan client swapchain. + * + * @ingroup xrt_iface comp_client + */ +struct xrt_swapchain_vk +{ + struct xrt_swapchain base; + + VkImage images[XRT_MAX_SWAPCHAIN_IMAGES]; + VkDeviceMemory mems[XRT_MAX_SWAPCHAIN_IMAGES]; +}; + +/*! + * Base clase for a Vulkan client compositor. + * + * @ingroup xrt_iface comp_client + */ +struct xrt_compositor_vk +{ + struct xrt_compositor base; +}; + +static inline struct xrt_swapchain_vk * +xrt_swapchain_vk(struct xrt_swapchain *xsc) +{ + return (struct xrt_swapchain_vk *)xsc; +} + +static inline struct xrt_compositor_vk * +xrt_compositor_vk(struct xrt_compositor *xc) +{ + return (struct xrt_compositor_vk *)xc; +} + + +/* + * + * FD interface, aka DMABUF. + * + */ + +/*! + * A single image of a fd based swapchain. + * + * @ingroup xrt_iface comp + */ +struct xrt_image_fd +{ + size_t size; + int fd; + int _pad; +}; + +/*! + * A swapchain that exposes fd to be imported into a client API. + * + * @ingroup xrt_iface comp + */ +struct xrt_swapchain_fd +{ + struct xrt_swapchain base; + + struct xrt_image_fd images[XRT_MAX_SWAPCHAIN_IMAGES]; +}; + +/*! + * Main compositor. + * + * @ingroup xrt_iface comp + */ +struct xrt_compositor_fd +{ + struct xrt_compositor base; +}; + +static inline struct xrt_swapchain_fd * +xrt_swapchain_fd(struct xrt_swapchain *xsc) +{ + return (struct xrt_swapchain_fd *)xsc; +} + +static inline struct xrt_compositor_fd * +xrt_compositor_fd(struct xrt_compositor *xc) +{ + return (struct xrt_compositor_fd *)xc; +} + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/include/xrt/xrt_config.h b/src/xrt/include/xrt/xrt_config.h new file mode 100644 index 000000000..c67c3d5f4 --- /dev/null +++ b/src/xrt/include/xrt/xrt_config.h @@ -0,0 +1,30 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Auto detect OS and certain features. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup xrt_iface + */ + +#pragma once + + +/* + * + * Auto detect OS. + * + */ + +#if defined(__linux__) +#define XRT_OS_LINUX +#define XRT_OS_UNIX +#define XRT_OS_WAS_AUTODETECTED +#endif + + + +#ifndef XRT_OS_WAS_AUTODETECTED +#error "OS type not found during compile" +#endif +#undef XRT_OS_WAS_AUTODETECTED diff --git a/src/xrt/include/xrt/xrt_defines.h b/src/xrt/include/xrt/xrt_defines.h new file mode 100644 index 000000000..b12452969 --- /dev/null +++ b/src/xrt/include/xrt/xrt_defines.h @@ -0,0 +1,196 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Common defines and enums for XRT. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup xrt_iface + */ + +#pragma once + +#include "xrt/xrt_compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! + * Which blend mode does the device support, used as both a bitfield and value. + * + * @ingroup xrt_iface + */ +enum xrt_blend_mode +{ + // clang-format off + XRT_BLEND_MODE_OPAQUE = 1 << 0, + XRT_BLEND_MODE_ADDITIVE = 1 << 1, + XRT_BLEND_MODE_ALPHA_BLEND = 1 << 2, + // clang-format on +}; + +/*! + * Which distortion model does the device expose, + * used both as a bitfield and value. + */ +enum xrt_distortion_model +{ + // clang-format off + XRT_DISTORTION_MODEL_NONE = 1 << 0, + XRT_DISTORTION_MODEL_PANOTOOLS = 1 << 1, + XRT_DISTORTION_MODEL_VIVE = 1 << 2, + // clang-format on +}; + +/*! + * A quaternion with single floats. + * + * @ingroup xrt_iface math + */ +struct xrt_quat +{ + float x; + float y; + float z; + float w; +}; + +/*! + * A 3 element vector with single floats. + * + * @ingroup xrt_iface math + */ +struct xrt_vec3 +{ + float x; + float y; + float z; +}; + +/*! + * A 2 element vector with single floats. + * + * @ingroup xrt_iface math + */ +struct xrt_vec2 +{ + float x; + float y; +}; + +/*! + * A pose composed of a position and orientation. + * + * @see xrt_qaut + * @see xrt_vec3 + * @ingroup xrt_iface math + */ +struct xrt_pose +{ + struct xrt_quat orientation; + struct xrt_vec3 position; +}; + +/*! + * Describes a projection matrix fov. + * + * @ingroup xrt_iface math + */ +struct xrt_fov +{ + float angle_left; + float angle_right; + float angle_up; + float angle_down; +}; + +/*! + * A tightly packed 2x2 matrix of floats. + * + * @ingroup xrt_iface math + */ +struct xrt_matrix_2x2 +{ + union { + float v[4]; + struct xrt_vec2 vecs[2]; + }; +}; + +/*! + * A tightly packed 4x4 matrix of floats. + * + * @ingroup xrt_iface math + */ +struct xrt_matrix_4x4 +{ + float v[16]; +}; + +/*! + * A range of API versions supported. + * + * @ingroup xrt_iface math + */ +struct xrt_api_requirements +{ + uint32_t min_major; + uint32_t min_minor; + uint32_t min_patch; + + uint32_t max_major; + uint32_t max_minor; + uint32_t max_patch; +}; + +/*! + * Flags of which components of a @ref xrt_space_relation is valid. + * + * @see xrt_space_relation + * @ingroup xrt_iface math + */ +enum xrt_space_relation_flags +{ + XRT_SPACE_RELATION_ORIENTATION_VALID_BIT = 0x00000001, + XRT_SPACE_RELATION_POSITION_VALID_BIT = 0x00000002, + XRT_SPACE_RELATION_LINEAR_VELOCITY_VALID_BIT = 0x00000004, + XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT = 0x00000008, + XRT_SPACE_RELATION_LINEAR_ACCELERATION_VALID_BIT = 0x00000010, + XRT_SPACE_RELATION_ANGULAR_ACCELERATION_VALID_BIT = 0x00000020, + XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT = 0x00000040, + XRT_SPACE_RELATION_POSITION_TRACKED_BIT = 0x00000080, + XRT_SPACE_RELATION_BITMASK_ALL = + XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | + XRT_SPACE_RELATION_POSITION_VALID_BIT | + 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 | + XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT | + XRT_SPACE_RELATION_POSITION_TRACKED_BIT, + XRT_SPACE_RELATION_BITMASK_NONE = 0 +}; + +/*! + * A relation with two spaces, includes velocity and acceleration. + * + * @see xrt_quat + * @see xrt_vec3 + * @see xrt_pose + * @see xrt_space_relation_flags + * @ingroup xrt_iface math + */ +struct xrt_space_relation +{ + enum xrt_space_relation_flags relation_flags; + struct xrt_pose pose; + struct xrt_vec3 linear_velocity; + struct xrt_vec3 angular_velocity; + struct xrt_vec3 linear_acceleration; + struct xrt_vec3 angular_acceleration; +}; + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/include/xrt/xrt_device.h b/src/xrt/include/xrt/xrt_device.h new file mode 100644 index 000000000..f1c5c9aaf --- /dev/null +++ b/src/xrt/include/xrt/xrt_device.h @@ -0,0 +1,174 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Header defining a xrt HMD device. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup xrt_iface + */ + +#pragma once + +#include "xrt/xrt_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! + * A per-lens view information. + * + * @ingroup xrt_iface + */ +struct xrt_view +{ + /*! + * Viewpport position on the screen, in absolute screen coordinates, + * this field is only used by @ref comp to setup the device rendering. + * + * If the view is being rotated by xrt_view.rot 90° right in the + * distortion shader then `display.w_pixels == viewport.h_pixels` & + * `display.h_pixels == viewport.w_pixels`. + */ + struct + { + uint32_t x_pixels; + uint32_t y_pixels; + uint32_t w_pixels; + uint32_t h_pixels; + } viewport; + + /*! + * Pixel and phyisical properties of this display, not in absolute + * screen coordinates that the compositor sees. So before any rotation + * is applied by xrt_view::rot. + * + * The xrt_view::display::w_pixels & xrt_view::display::h_pixels + * become the recommdnded image size for this view. + */ + struct + { + uint32_t w_pixels; + uint32_t h_pixels; + float w_meters; + float h_meters; + } display; + + /*! + * Position in meters relative to display origin, before any rotation + * is applied by xrt_view::rot. + */ + struct + { + float x_meters; + float y_meters; + } lens_center; + + /*! + * Rotation 2d matrix used to rotate the position of the output of the + * distortion shaders onto the screen. Should the distortion shader be + * based on mesh then this matrix rotates the vertex positions. + */ + struct xrt_matrix_2x2 rot; + + /*! + * Fov expressed in OpenXR. + */ + struct xrt_fov fov; +}; + +/*! + * A single HMD device. + * + * @ingroup xrt_iface + */ +struct xrt_device +{ + /*! + * The hmd screen, right now hardcoded to one. + */ + struct + { + int w_pixels; + int h_pixels; + } screens[1]; + + /*! + * Display information. + * + * For now hardcoded display to two. + */ + struct xrt_view views[2]; + + /*! + * Supported blend modes, a bitfield. + */ + enum xrt_blend_mode blend_mode; + + /*! + * Distortion information. + */ + struct + { + //! Supported distortion models, a bitfield. + enum xrt_distortion_model models; + //! Preferred disortion model, single value. + enum xrt_distortion_model preferred; + + struct + { + //! Panotools universal distortion k. + float distortion_k[4]; + //! Panotools post distortion scale, <r, g, b, _>. + float aberration_k[4]; + //! Panotools warp scale. + float warp_scale; + } pano; + + struct + { + // To be filled in. + float temp; + } vive; + + } distortion; + + /*! + * Get relationship of a tracked device to the device "base space". + * + * Right now the base space is assumed to be local space. + * + * This is very very WIP and will need to be made a lot more advanced. + */ + void (*get_tracked_pose)(struct xrt_device *xdev, + struct xrt_space_relation *out_relation); + + /*! + * Get the per view pose in relation to the view space. Does not do any + * device level tracking, use get_tracked_pose for that. + * + * @param eye_relation The interpupillary relation as a 3D position, + * most simple stereo devices would just want to set + * out_puse->position.[x|y|z] = ipd.[x|y|z] / 2.0f. + * Not to be confused with IPD that is absolute + * distance, this is a full 3D relation. + * @param index Index of view. + * @param out_pose Output pose, see ipd argument, and in addition + * orientation most likely identity rotation. + */ + void (*get_view_pose)(struct xrt_device *xdev, + struct xrt_vec3 *eye_relation, + uint32_t view_index, + struct xrt_pose *out_pose); + + /*! + * Destroy device. + */ + void (*destroy)(struct xrt_device *xdev); +}; + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/include/xrt/xrt_documentation.h b/src/xrt/include/xrt/xrt_documentation.h new file mode 100644 index 000000000..7115bea58 --- /dev/null +++ b/src/xrt/include/xrt/xrt_documentation.h @@ -0,0 +1,22 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Header with just documentation. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup xrt + */ + +#pragma once + +/*! + * @defgroup xrt Monado(XRT) + */ + +/*! + * @defgroup xrt_iface XRT interfaces + * + * The main interface shared between the different components of Monado. + * + * @ingroup xrt + */ diff --git a/src/xrt/include/xrt/xrt_gfx_gl.h b/src/xrt/include/xrt/xrt_gfx_gl.h new file mode 100644 index 000000000..853627d53 --- /dev/null +++ b/src/xrt/include/xrt/xrt_gfx_gl.h @@ -0,0 +1,28 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Header for misc OpenGL code, not a complete graphics provider. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup xrt_iface + */ + +#pragma once + +#include "xrt/xrt_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! + * @ingroup xrt_iface + */ +void +xrt_gfx_gl_get_versions(struct xrt_api_requirements *ver); + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/include/xrt/xrt_gfx_vk.h b/src/xrt/include/xrt/xrt_gfx_vk.h new file mode 100644 index 000000000..0df24a33a --- /dev/null +++ b/src/xrt/include/xrt/xrt_gfx_vk.h @@ -0,0 +1,53 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Header defining a XRT graphics provider. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup xrt_iface + */ + +#pragma once + +#include "xrt/xrt_device.h" +#include "xrt/xrt_compositor.h" +#include "xrt/xrt_vulkan_includes.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! + * @ingroup xrt_iface + */ +extern const char *xrt_gfx_vk_instance_extensions; + +/*! + * @ingroup xrt_iface + */ +extern const char *xrt_gfx_vk_device_extensions; + +/*! + * @ingroup xrt_iface + */ +void +xrt_gfx_vk_get_versions(struct xrt_api_requirements *ver); + +/*! + * @ingroup xrt_iface + */ +struct xrt_compositor_vk * +xrt_gfx_vk_provider_create(struct xrt_device *xdev, + VkInstance instance, + PFN_vkGetInstanceProcAddr getProc, + VkPhysicalDevice physicalDevice, + VkDevice device, + uint32_t queueFamilyIndex, + uint32_t queueIndex); + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/include/xrt/xrt_gfx_xlib.h b/src/xrt/include/xrt/xrt_gfx_xlib.h new file mode 100644 index 000000000..66fa1c3eb --- /dev/null +++ b/src/xrt/include/xrt/xrt_gfx_xlib.h @@ -0,0 +1,39 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Header defining a XRT graphics provider. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup xrt_iface + */ + +#pragma once + +#include "xrt/xrt_device.h" +#include "xrt/xrt_compositor.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef void* Display; +typedef void* GLXFBConfig; +typedef void* GLXDrawable; +typedef void* GLXContext; + +/*! + * @ingroup xrt_iface + */ +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); + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/include/xrt/xrt_openxr_includes.h b/src/xrt/include/xrt/xrt_openxr_includes.h new file mode 100644 index 000000000..96e5113d5 --- /dev/null +++ b/src/xrt/include/xrt/xrt_openxr_includes.h @@ -0,0 +1,31 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Include all of the openxr headers in one place. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup xrt_iface + */ + +#pragma once + +// Move these to the build system instead. +#define XR_USE_GRAPHICS_API_OPENGL +#define XR_USE_GRAPHICS_API_VULKAN +#define XR_USE_PLATFORM_XLIB +#define XR_USE_TIMESPEC 1 + +#ifdef XR_USE_PLATFORM_XLIB +typedef void* Display; +typedef void* GLXFBConfig; +typedef void* GLXDrawable; +typedef void* GLXContext; +#endif + +#ifdef XR_USE_TIMESPEC +#include <time.h> +#endif + +#include "openxr_includes/openxr.h" +#include "openxr_includes/openxr_platform.h" +#include "openxr_includes/loader_interfaces.h" diff --git a/src/xrt/include/xrt/xrt_prober.h b/src/xrt/include/xrt/xrt_prober.h new file mode 100644 index 000000000..7e0a9211e --- /dev/null +++ b/src/xrt/include/xrt/xrt_prober.h @@ -0,0 +1,42 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Common interface to probe for devices. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup xrt_iface + */ + +#pragma once + +#include "xrt/xrt_device.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! + * A prober for HMD devices connected to the system. + * + * @ingroup xrt_iface + */ +struct xrt_prober +{ + struct xrt_device *(*lelo_dallas_autoprobe)(struct xrt_prober *xdev); + void (*destroy)(struct xrt_prober *xdev); +}; + +/*! + * Call this function to create the prober. This function is setup in the the + * very small target wrapper.c for each binary. + * + * @ingroup xrt_iface + */ +struct xrt_prober * +xrt_create_prober(); + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/include/xrt/xrt_vulkan_includes.h b/src/xrt/include/xrt/xrt_vulkan_includes.h new file mode 100644 index 000000000..deb086bda --- /dev/null +++ b/src/xrt/include/xrt/xrt_vulkan_includes.h @@ -0,0 +1,13 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Include all of the Vulkan headers in one place. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup xrt_iface + */ + +#pragma once + +#define VK_NO_PROTOTYPES +#include <vulkan/vulkan.h> diff --git a/src/xrt/state_trackers/CMakeLists.txt b/src/xrt/state_trackers/CMakeLists.txt new file mode 100644 index 000000000..c65bfe9a7 --- /dev/null +++ b/src/xrt/state_trackers/CMakeLists.txt @@ -0,0 +1,47 @@ +# Copyright 2019, Collabora, Ltd. +# SPDX-License-Identifier: BSL-1.0 + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../include + ${CMAKE_CURRENT_SOURCE_DIR}/../auxiliary + ${CMAKE_CURRENT_SOURCE_DIR}/../../external + ) + +set(OXR_SOURCE_FILES + oxr/oxr_api_action.c + oxr/oxr_api_debug.c + oxr/oxr_api_funcs.h + oxr/oxr_api_instance.c + oxr/oxr_api_negotiate.c + oxr/oxr_api_session.c + oxr/oxr_api_space.c + oxr/oxr_api_swapchain.c + oxr/oxr_api_system.c + oxr/oxr_api_verify.h + oxr/oxr_event.cpp + oxr/oxr_instance.c + oxr/oxr_logger.cpp + oxr/oxr_logger.h + oxr/oxr_objects.h + oxr/oxr_session.c + oxr/oxr_session_gl.c + oxr/oxr_session_vk.c + oxr/oxr_space.c + oxr/oxr_swapchain.c + oxr/oxr_swapchain_gl.c + oxr/oxr_swapchain_vk.c + oxr/oxr_system.c + oxr/oxr_two_call.h + oxr/oxr_verify.cpp + oxr/oxr_vulkan.c + ) + +# Use OBJECT to not create a archive, since it just gets in the way. +add_library(st_oxr OBJECT ${OXR_SOURCE_FILES}) + +target_include_directories(st_oxr + PRIVATE + ${VULKAN_INCLUDE_DIR} + ) + +set_property(TARGET st_oxr PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/src/xrt/state_trackers/dev/README.md b/src/xrt/state_trackers/dev/README.md new file mode 100644 index 000000000..7e20dee6a --- /dev/null +++ b/src/xrt/state_trackers/dev/README.md @@ -0,0 +1,6 @@ + +# OpenXR device layer integrator + +This is where the device layer integrator code will go. It takes one or more +xrt_device and plugs that into the OpenXR device layer interface, once the +device layer has been finalized. diff --git a/src/xrt/state_trackers/oxr/oxr_api_action.c b/src/xrt/state_trackers/oxr/oxr_api_action.c new file mode 100644 index 000000000..c2cd6825f --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_api_action.c @@ -0,0 +1,305 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Action related API entrypoint functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_api + */ + +#include <stdio.h> + +#include "oxr_objects.h" +#include "oxr_logger.h" + +#include "util/u_debug.h" + +#include "oxr_api_funcs.h" +#include "oxr_api_verify.h" + + +/* + * + * Session - action functions. + * + */ + +XrResult +oxr_xrSyncActionData(XrSession session, + uint32_t countActionSets, + const XrActiveActionSet* actionSets) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrSyncActionData"); + + if (countActionSets == 0) { + return oxr_error(&log, XR_ERROR_VALIDATION_FAILURE, + "(countActionSets == 0)"); + } + + for (uint32_t i = 0; i < countActionSets; i++) { + struct oxr_action_set* act_set; + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, (&actionSets[i]), + XR_TYPE_ACTIVE_ACTION_SET); + OXR_VERIFY_ACTIONSET_NOT_NULL(&log, actionSets[i].actionSet, + act_set); + //! @todo verify path. + } + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +XrResult +oxr_xrSetInteractionProfileSuggestedBindings( + XrSession session, + const XrInteractionProfileSuggestedBinding* suggestedBindings) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG( + &log, session, sess, "xrSetInteractionProfileSuggestedBindings"); + OXR_VERIFY_ARG_TYPE_AND_NULL( + &log, suggestedBindings, + XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING); + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +XrResult +oxr_xrGetCurrentInteractionProfile(XrSession session, + XrPath topLevelUserPath, + XrInteractionProfileInfo* interactionProfile) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrGetCurrentInteractionProfile"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, interactionProfile, + XR_TYPE_INTERACTION_PROFILE_INFO); + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +XrResult +oxr_xrGetInputSourceLocalizedName( + XrSession session, + XrPath source, + XrInputSourceLocalizedNameFlags whichComponents, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + char* buffer) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrGetInputSourceLocalizedName"); + //! @todo verify path + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + + +/* + * + * Action set functions + * + */ + +XrResult +oxr_xrCreateActionSet(XrSession session, + const XrActionSetCreateInfo* createInfo, + XrActionSet* actionSet) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrCreateActionSet"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, createInfo, + XR_TYPE_ACTION_SET_CREATE_INFO); + OXR_VERIFY_ARG_NOT_NULL(&log, actionSet); + OXR_VERIFY_ARG_SINGLE_LEVEL_FIXED_LENGTH_PATH( + &log, createInfo->actionSetName); + OXR_VERIFY_ARG_SINGLE_LEVEL_FIXED_LENGTH_PATH( + &log, createInfo->localizedActionSetName); + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +XrResult +oxr_xrDestroyActionSet(XrActionSet actionSet) +{ + struct oxr_action_set* act_set; + struct oxr_logger log; + OXR_VERIFY_ACTIONSET_AND_INIT_LOG(&log, actionSet, act_set, + "xrDestroyActionSet"); + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + + +/* + * + * Action functions + * + */ + +XrResult +oxr_xrCreateAction(XrActionSet actionSet, + const XrActionCreateInfo* createInfo, + XrAction* action) +{ + struct oxr_action_set* act_set; + struct oxr_logger log; + OXR_VERIFY_ACTIONSET_AND_INIT_LOG(&log, actionSet, act_set, + "xrCreateAction"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, createInfo, + XR_TYPE_ACTION_CREATE_INFO); + OXR_VERIFY_ARG_NOT_NULL(&log, action); + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +XrResult +oxr_xrDestroyAction(XrAction action) +{ + struct oxr_action* act; + struct oxr_logger log; + OXR_VERIFY_ACTION_AND_INIT_LOG(&log, action, act, "xrDestroyAction"); + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +XrResult +oxr_xrGetActionStateBoolean(XrAction action, + uint32_t countSubactionPaths, + const XrPath* subactionPaths, + XrActionStateBoolean* data) +{ + struct oxr_action* act; + struct oxr_logger log; + OXR_VERIFY_ACTION_AND_INIT_LOG(&log, action, act, + "xrGetActionStateBoolean"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, data, XR_TYPE_ACTION_STATE_BOOLEAN); + OXR_VERIFY_SUBACTION_PATHS(&log, countSubactionPaths, subactionPaths); + //! @todo verify paths + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +XrResult +oxr_xrGetActionStateVector1f(XrAction action, + uint32_t countSubactionPaths, + const XrPath* subactionPaths, + XrActionStateVector1f* data) +{ + struct oxr_action* act; + struct oxr_logger log; + OXR_VERIFY_ACTION_AND_INIT_LOG(&log, action, act, + "xrGetActionStateVector1f"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, data, XR_TYPE_ACTION_STATE_VECTOR1F); + OXR_VERIFY_SUBACTION_PATHS(&log, countSubactionPaths, subactionPaths); + //! @todo verify paths + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +XrResult +oxr_xrGetActionStateVector2f(XrAction action, + uint32_t countSubactionPaths, + const XrPath* subactionPaths, + XrActionStateVector2f* data) +{ + struct oxr_action* act; + struct oxr_logger log; + OXR_VERIFY_ACTION_AND_INIT_LOG(&log, action, act, + "xrGetActionStateVector2f"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, data, XR_TYPE_ACTION_STATE_VECTOR2F); + OXR_VERIFY_SUBACTION_PATHS(&log, countSubactionPaths, subactionPaths); + //! @todo verify paths + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +XrResult +oxr_xrGetActionStatePose(XrAction action, + XrPath subactionPath, + XrActionStatePose* data) +{ + struct oxr_action* act; + struct oxr_logger log; + OXR_VERIFY_ACTION_AND_INIT_LOG(&log, action, act, + "xrGetActionStatePose"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, data, XR_TYPE_ACTION_STATE_POSE); + //! @todo verify path + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +XrResult +oxr_xrGetBoundSourcesForAction(XrAction action, + uint32_t sourceCapacityInput, + uint32_t* sourceCountOutput, + XrPath* sources) +{ + struct oxr_action* act; + struct oxr_logger log; + OXR_VERIFY_ACTION_AND_INIT_LOG(&log, action, act, + "xrGetBoundSourcesForAction"); + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + + +/* + * + * Haptic feedback functions. + * + */ + +XrResult +oxr_xrApplyHapticFeedback(XrAction hapticAction, + uint32_t countSubactionPaths, + const XrPath* subactionPaths, + const XrHapticBaseHeader* hapticEvent) +{ + struct oxr_action* hapticAct; + struct oxr_logger log; + OXR_VERIFY_ACTION_AND_INIT_LOG(&log, hapticAction, hapticAct, + "xrApplyHapticFeedback"); + OXR_VERIFY_SUBACTION_PATHS(&log, countSubactionPaths, subactionPaths); + //! @todo verify paths + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +XrResult +oxr_xrStopHapticFeedback(XrAction hapticAction, + uint32_t countSubactionPaths, + const XrPath* subactionPaths) +{ + struct oxr_action* hapticAct; + struct oxr_logger log; + OXR_VERIFY_ACTION_AND_INIT_LOG(&log, hapticAction, hapticAct, + "xrStopHapticFeedback"); + OXR_VERIFY_SUBACTION_PATHS(&log, countSubactionPaths, subactionPaths); + //! @todo verify paths + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} diff --git a/src/xrt/state_trackers/oxr/oxr_api_debug.c b/src/xrt/state_trackers/oxr/oxr_api_debug.c new file mode 100644 index 000000000..0d3f777d9 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_api_debug.c @@ -0,0 +1,106 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Debug messaging entrypoints for the OpenXR state tracker. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_api + */ + +#include "oxr_objects.h" +#include "oxr_logger.h" + +#include "oxr_api_funcs.h" +#include "oxr_api_verify.h" + +#ifdef XR_EXT_debug_utils + + +XrResult +oxr_xrSetDebugUtilsObjectNameEXT(XrInstance instance, + const XrDebugUtilsObjectNameInfoEXT* nameInfo) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrSetDebugUtilsObjectNameEXT"); + + return oxr_error(&log, XR_ERROR_RUNTIME_FAILURE, " not implemented"); +} + +XrResult +oxr_xrCreateDebugUtilsMessengerEXT( + XrInstance instance, + const XrDebugUtilsMessengerCreateInfoEXT* createInfo, + XrDebugUtilsMessengerEXT* messenger) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrCreateDebugUtilsMessengerEXT"); + + return oxr_error(&log, XR_ERROR_RUNTIME_FAILURE, " not implemented"); +} + +XrResult +oxr_xrDestroyDebugUtilsMessengerEXT(XrDebugUtilsMessengerEXT messenger) +{ + struct oxr_debug_messenger* mssngr; + struct oxr_logger log; + OXR_VERIFY_MESSENGER_AND_INIT_LOG(&log, messenger, mssngr, + "xrDestroyDebugUtilsMessengerEXT"); + + return oxr_error(&log, XR_ERROR_RUNTIME_FAILURE, " not implemented"); +} + +XrResult +oxr_xrSubmitDebugUtilsMessageEXT( + XrInstance instance, + XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, + XrDebugUtilsMessageTypeFlagsEXT messageTypes, + const XrDebugUtilsMessengerCallbackDataEXT* callbackData) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrSubmitDebugUtilsMessageEXT"); + + return oxr_error(&log, XR_ERROR_RUNTIME_FAILURE, " not implemented"); +} + +XrResult +oxr_xrSessionBeginDebugUtilsLabelRegionEXT( + XrSession session, const XrDebugUtilsLabelEXT* labelInfo) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG( + &log, session, sess, "xrSessionBeginDebugUtilsLabelRegionEXT"); + + return oxr_error(&log, XR_ERROR_RUNTIME_FAILURE, " not implemented"); +} + +XrResult +oxr_xrSessionEndDebugUtilsLabelRegionEXT(XrSession session) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrSessionEndDebugUtilsLabelRegionEXT"); + + return oxr_error(&log, XR_ERROR_RUNTIME_FAILURE, " not implemented"); +} + +XrResult +oxr_xrSessionInsertDebugUtilsLabelEXT(XrSession session, + const XrDebugUtilsLabelEXT* labelInfo) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrSessionInsertDebugUtilsLabelEXT"); + + return oxr_error(&log, XR_ERROR_RUNTIME_FAILURE, " not implemented"); +} + +#endif diff --git a/src/xrt/state_trackers/oxr/oxr_api_funcs.h b/src/xrt/state_trackers/oxr/oxr_api_funcs.h new file mode 100644 index 000000000..0355f42fc --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_api_funcs.h @@ -0,0 +1,534 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Header defining all API functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_api + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! + * @defgroup oxr_api OpenXR entrypoints + * + * Gets called from the client application, does most verification and routes + * calls into @ref oxr_main functions. + * + * @ingroup oxr + * @{ + */ + + +/* + * + * oxr_api_negotiate.c + * + */ + +//! OpenXR API function @ep{xrGetInstanceProcAddr} +XrResult +oxr_xrGetInstanceProcAddr(XrInstance instance, + const char* name, + PFN_xrVoidFunction* function); + +//! OpenXR API function @ep{xrEnumerateApiLayerProperties} +XrResult +oxr_xrEnumerateApiLayerProperties(uint32_t propertyCapacityInput, + uint32_t* propertyCountOutput, + XrApiLayerProperties* properties); + + +/* + * + * oxr_api_instance.c + * + */ + +//! OpenXR API function @ep{xrEnumerateInstanceExtensionProperties} +XrResult +oxr_xrEnumerateInstanceExtensionProperties(const char* layerName, + uint32_t propertyCapacityInput, + uint32_t* propertyCountOutput, + XrExtensionProperties* properties); + +//! OpenXR API function @ep{xrCreateInstance} +XrResult +oxr_xrCreateInstance(const XrInstanceCreateInfo* createInfo, + XrInstance* instance); + +//! OpenXR API function @ep{xrDestroyInstance} +XrResult +oxr_xrDestroyInstance(XrInstance instance); + +//! OpenXR API function @ep{xrGetInstanceProperties} +XrResult +oxr_xrGetInstanceProperties(XrInstance instance, + XrInstanceProperties* instanceProperties); + +//! OpenXR API function @ep{xrPollEvent} +XrResult +oxr_xrPollEvent(XrInstance instance, XrEventDataBuffer* eventData); + +//! OpenXR API function @ep{xrResultToString} +XrResult +oxr_xrResultToString(XrInstance instance, + XrResult value, + char buffer[XR_MAX_RESULT_STRING_SIZE]); + +//! OpenXR API function @ep{xrStructureTypeToString} +XrResult +oxr_xrStructureTypeToString(XrInstance instance, + XrStructureType value, + char buffer[XR_MAX_STRUCTURE_NAME_SIZE]); + +//! OpenXR API function @ep{xrStringToPath} +XrResult +oxr_xrStringToPath(XrInstance instance, const char* pathString, XrPath* path); + +//! OpenXR API function @ep{xrPathToString} +XrResult +oxr_xrPathToString(XrInstance instance, + XrPath path, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + char* buffer); + +//! OpenXR API function @ep{xrConvertTimespecTimeToTimeKHR} +XrResult +oxr_xrConvertTimespecTimeToTimeKHR(XrInstance instance, + const struct timespec* timespecTime, + XrTime* time); + +//! OpenXR API function @ep{xrConvertTimeToTimespecTimeKHR} +XrResult +oxr_xrConvertTimeToTimespecTimeKHR(XrInstance instance, + XrTime time, + struct timespec* timespecTime); + +/* + * + * oxr_api_system.c + * + */ + +//! OpenXR API function @ep{xrGetSystem} +XrResult +oxr_xrGetSystem(XrInstance instance, + const XrSystemGetInfo* getInfo, + XrSystemId* systemId); + +//! OpenXR API function @ep{xrGetSystemProperties} +XrResult +oxr_xrGetSystemProperties(XrInstance instance, + XrSystemId systemId, + XrSystemProperties* properties); + +//! OpenXR API function @ep{xrEnumerateViewConfigurations} +XrResult +oxr_xrEnumerateViewConfigurations( + XrInstance instance, + XrSystemId systemId, + uint32_t viewConfigurationTypeCapacityInput, + uint32_t* viewConfigurationTypeCountOutput, + XrViewConfigurationType* viewConfigurationTypes); + +//! OpenXR API function @ep{xrGetViewConfigurationProperties} +XrResult +oxr_xrGetViewConfigurationProperties( + XrInstance instance, + XrSystemId systemId, + XrViewConfigurationType viewConfigurationType, + XrViewConfigurationProperties* configurationProperties); + +//! OpenXR API function @ep{xrEnumerateViewConfigurationViews} +XrResult +oxr_xrEnumerateViewConfigurationViews( + XrInstance instance, + XrSystemId systemId, + XrViewConfigurationType viewConfigurationType, + uint32_t viewCapacityInput, + uint32_t* viewCountOutput, + XrViewConfigurationView* views); + +//! OpenXR API function @ep{xrEnumerateEnvironmentBlendModes} +XrResult +oxr_xrEnumerateEnvironmentBlendModes( + XrInstance instance, + XrSystemId systemId, + uint32_t environmentBlendModeCapacityInput, + uint32_t* environmentBlendModeCountOutput, + XrEnvironmentBlendMode* environmentBlendModes); + +#ifdef XR_USE_GRAPHICS_API_OPENGL +//! OpenXR API function @ep{xrGetOpenGLGraphicsRequirementsKHR} +XrResult +oxr_xrGetOpenGLGraphicsRequirementsKHR( + XrInstance instance, + XrSystemId systemId, + XrGraphicsRequirementsOpenGLKHR* graphicsRequirements); +#endif + +#ifdef XR_USE_GRAPHICS_API_VULKAN +//! OpenXR API function @ep{xrGetVulkanInstanceExtensionsKHR} +XrResult +oxr_xrGetVulkanInstanceExtensionsKHR(XrInstance instance, + XrSystemId systemId, + uint32_t namesCapacityInput, + uint32_t* namesCountOutput, + char* namesString); + +//! OpenXR API function @ep{xrGetVulkanDeviceExtensionsKHR} +XrResult +oxr_xrGetVulkanDeviceExtensionsKHR(XrInstance instance, + XrSystemId systemId, + uint32_t namesCapacityInput, + uint32_t* namesCountOutput, + char* namesString); + +//! OpenXR API function @ep{xrGetVulkanGraphicsDeviceKHR} +XrResult +oxr_xrGetVulkanGraphicsDeviceKHR(XrInstance instance, + XrSystemId systemId, + VkInstance vkInstance, + VkPhysicalDevice* vkPhysicalDevice); + +//! OpenXR API function @ep{xrGetVulkanGraphicsRequirementsKHR} +XrResult +oxr_xrGetVulkanGraphicsRequirementsKHR( + XrInstance instance, + XrSystemId systemId, + XrGraphicsRequirementsVulkanKHR* graphicsRequirements); +#endif + + +/* + * + * oxr_api_session.c + * + */ + +//! OpenXR API function @ep{xrCreateSession} +XrResult +oxr_xrCreateSession(XrInstance instance, + const XrSessionCreateInfo* createInfo, + XrSession* session); + +//! OpenXR API function @ep{xrDestroySession} +XrResult +oxr_xrDestroySession(XrSession session); + +//! OpenXR API function @ep{xrBeginSession} +XrResult +oxr_xrBeginSession(XrSession session, const XrSessionBeginInfo* beginInfo); + +//! OpenXR API function @ep{xrEndSession} +XrResult +oxr_xrEndSession(XrSession session); + +//! OpenXR API function @ep{xrWaitFrame} +XrResult +oxr_xrWaitFrame(XrSession session, + const XrFrameWaitInfo* frameWaitInfo, + XrFrameState* frameState); + +//! OpenXR API function @ep{xrBeginFrame} +XrResult +oxr_xrBeginFrame(XrSession session, const XrFrameBeginInfo* frameBeginInfo); + +//! OpenXR API function @ep{xrEndFrame} +XrResult +oxr_xrEndFrame(XrSession session, const XrFrameEndInfo* frameEndInfo); + +//! OpenXR API function @ep{xrLocateViews} +XrResult +oxr_xrLocateViews(XrSession session, + const XrViewLocateInfo* viewLocateInfo, + XrViewState* viewState, + uint32_t viewCapacityInput, + uint32_t* viewCountOutput, + XrView* views); + +#ifdef XR_KHR_visibility_mask +//! OpenXR API function @ep{xrGetVisibilityMaskKHR} +XrResult +oxr_xrGetVisibilityMaskKHR(XrSession session, + XrViewConfigurationType viewConfigurationType, + uint32_t viewIndex, + XrVisibilityMaskTypeKHR visibilityMaskType, + XrVisibilityMaskKHR* visibilityMask); +#endif + +#ifdef XR_EXT_performance_settings +//! OpenXR API function @ep{xrPerfSettingsSetPerformanceLevelEXT} +XrResult +oxr_xrPerfSettingsSetPerformanceLevelEXT(XrSession session, + XrPerfSettingsDomainEXT domain, + XrPerfSettingsLevelEXT level); +#endif + +#ifdef XR_EXT_thermal_query +//! OpenXR API function @ep{xrThermalGetTemperatureTrendEXT} +XrResult +oxr_xrThermalGetTemperatureTrendEXT( + XrSession session, + XrPerfSettingsDomainEXT domain, + XrPerfSettingsNotificationLevelEXT* notificationLevel, + float* tempHeadroom, + float* tempSlope); +#endif + + +/* + * + * oxr_api_space.c + * + */ + +//! OpenXR API function @ep{xrEnumerateReferenceSpaces} +XrResult +oxr_xrEnumerateReferenceSpaces(XrSession session, + uint32_t spaceCapacityInput, + uint32_t* spaceCountOutput, + XrReferenceSpaceType* spaces); + +//! OpenXR API function @ep{xrGetReferenceSpaceBoundsRect} +XrResult +oxr_xrGetReferenceSpaceBoundsRect(XrSession session, + XrReferenceSpaceType referenceSpaceType, + XrExtent2Df* bounds); + +//! OpenXR API function @ep{xrCreateReferenceSpace} +XrResult +oxr_xrCreateReferenceSpace(XrSession session, + const XrReferenceSpaceCreateInfo* createInfo, + XrSpace* space); + +//! OpenXR API function @ep{xrLocateSpace} +XrResult +oxr_xrLocateSpace(XrSpace space, + XrSpace baseSpace, + XrTime time, + XrSpaceRelation* relation); + +//! OpenXR API function @ep{xrDestroySpace} +XrResult +oxr_xrDestroySpace(XrSpace space); + + +/* + * + * oxr_api_swapchain.c + * + */ + +//! OpenXR API function @ep{xrEnumerateSwapchainFormats} +XrResult +oxr_xrEnumerateSwapchainFormats(XrSession session, + uint32_t formatCapacityInput, + uint32_t* formatCountOutput, + int64_t* formats); + +//! OpenXR API function @ep{xrCreateSwapchain} +XrResult +oxr_xrCreateSwapchain(XrSession session, + const XrSwapchainCreateInfo* createInfo, + XrSwapchain* swapchain); + +//! OpenXR API function @ep{xrDestroySwapchain} +XrResult +oxr_xrDestroySwapchain(XrSwapchain swapchain); + +//! OpenXR API function @ep{xrEnumerateSwapchainImages} +XrResult +oxr_xrEnumerateSwapchainImages(XrSwapchain swapchain, + uint32_t imageCapacityInput, + uint32_t* imageCountOutput, + XrSwapchainImageBaseHeader* images); + +//! OpenXR API function @ep{xrAcquireSwapchainImage} +XrResult +oxr_xrAcquireSwapchainImage(XrSwapchain swapchain, + const XrSwapchainImageAcquireInfo* acquireInfo, + uint32_t* index); + +//! OpenXR API function @ep{xrWaitSwapchainImage} +XrResult +oxr_xrWaitSwapchainImage(XrSwapchain swapchain, + const XrSwapchainImageWaitInfo* waitInfo); + +//! OpenXR API function @ep{xrReleaseSwapchainImage} +XrResult +oxr_xrReleaseSwapchainImage(XrSwapchain swapchain, + const XrSwapchainImageReleaseInfo* releaseInfo); + + +/* + * + * oxr_api_debug.c + * + */ + +#ifdef XR_EXT_debug_utils + +//! OpenXR API function @ep{xrSetDebugUtilsObjectNameEXT} +XrResult +oxr_xrSetDebugUtilsObjectNameEXT(XrInstance instance, + const XrDebugUtilsObjectNameInfoEXT* nameInfo); + +//! OpenXR API function @ep{xrCreateDebugUtilsMessengerEXT} +XrResult +oxr_xrCreateDebugUtilsMessengerEXT( + XrInstance instance, + const XrDebugUtilsMessengerCreateInfoEXT* createInfo, + XrDebugUtilsMessengerEXT* messenger); + +//! OpenXR API function @ep{xrDestroyDebugUtilsMessengerEXT} +XrResult +oxr_xrDestroyDebugUtilsMessengerEXT(XrDebugUtilsMessengerEXT messenger); + +//! OpenXR API function @ep{xrSubmitDebugUtilsMessageEXT} +XrResult +oxr_xrSubmitDebugUtilsMessageEXT( + XrInstance instance, + XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, + XrDebugUtilsMessageTypeFlagsEXT messageTypes, + const XrDebugUtilsMessengerCallbackDataEXT* callbackData); + +//! OpenXR API function @ep{xrSessionBeginDebugUtilsLabelRegionEXT} +XrResult +oxr_xrSessionBeginDebugUtilsLabelRegionEXT( + XrSession session, const XrDebugUtilsLabelEXT* labelInfo); + +//! OpenXR API function @ep{xrSessionEndDebugUtilsLabelRegionEXT} +XrResult +oxr_xrSessionEndDebugUtilsLabelRegionEXT(XrSession session); + +//! OpenXR API function @ep{xrSessionInsertDebugUtilsLabelEXT} +XrResult +oxr_xrSessionInsertDebugUtilsLabelEXT(XrSession session, + const XrDebugUtilsLabelEXT* labelInfo); +#endif + + +/* + * + * oxr_api_action.c + * + */ + +//! OpenXR API function @ep{xrCreateActionSpace} +XrResult +oxr_xrCreateActionSpace(XrAction action, + const XrActionSpaceCreateInfo* createInfo, + XrSpace* space); + +//! OpenXR API function @ep{xrCreateActionSet} +XrResult +oxr_xrCreateActionSet(XrSession session, + const XrActionSetCreateInfo* createInfo, + XrActionSet* actionSet); + +//! OpenXR API function @ep{xrDestroyActionSet} +XrResult +oxr_xrDestroyActionSet(XrActionSet actionSet); + +//! OpenXR API function @ep{xrCreateAction} +XrResult +oxr_xrCreateAction(XrActionSet actionSet, + const XrActionCreateInfo* createInfo, + XrAction* action); + +//! OpenXR API function @ep{xrDestroyAction} +XrResult +oxr_xrDestroyAction(XrAction action); + +//! OpenXR API function @ep{xrSetInteractionProfileSuggestedBindings} +XrResult +oxr_xrSetInteractionProfileSuggestedBindings( + XrSession session, + const XrInteractionProfileSuggestedBinding* suggestedBindings); + +//! OpenXR API function @ep{xrGetCurrentInteractionProfile} +XrResult +oxr_xrGetCurrentInteractionProfile( + XrSession session, + XrPath topLevelUserPath, + XrInteractionProfileInfo* interactionProfile); + +//! OpenXR API function @ep{xrGetActionStateBoolean} +XrResult +oxr_xrGetActionStateBoolean(XrAction action, + uint32_t countSubactionPaths, + const XrPath* subactionPaths, + XrActionStateBoolean* data); + +//! OpenXR API function @ep{xrGetActionStateVector1f} +XrResult +oxr_xrGetActionStateVector1f(XrAction action, + uint32_t countSubactionPaths, + const XrPath* subactionPaths, + XrActionStateVector1f* data); + +//! OpenXR API function @ep{xrGetActionStateVector2f} +XrResult +oxr_xrGetActionStateVector2f(XrAction action, + uint32_t countSubactionPaths, + const XrPath* subactionPaths, + XrActionStateVector2f* data); + +//! OpenXR API function @ep{xrGetActionStatePose} +XrResult +oxr_xrGetActionStatePose(XrAction action, + XrPath subactionPath, + XrActionStatePose* data); + +//! OpenXR API function @ep{xrSyncActionData} +XrResult +oxr_xrSyncActionData(XrSession session, + uint32_t countActionSets, + const XrActiveActionSet* actionSets); + +//! OpenXR API function @ep{xrGetBoundSourcesForAction} +XrResult +oxr_xrGetBoundSourcesForAction(XrAction action, + uint32_t sourceCapacityInput, + uint32_t* sourceCountOutput, + XrPath* sources); + +//! OpenXR API function @ep{xrGetInputSourceLocalizedName} +XrResult +oxr_xrGetInputSourceLocalizedName( + XrSession session, + XrPath source, + XrInputSourceLocalizedNameFlags whichComponents, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + char* buffer); + +//! OpenXR API function @ep{xrApplyHapticFeedback} +XrResult +oxr_xrApplyHapticFeedback(XrAction hapticAction, + uint32_t countSubactionPaths, + const XrPath* subactionPaths, + const XrHapticBaseHeader* hapticEvent); + +//! OpenXR API function @ep{xrStopHapticFeedback} +XrResult +oxr_xrStopHapticFeedback(XrAction hapticAction, + uint32_t countSubactionPaths, + const XrPath* subactionPaths); + +/*! + * @} + */ + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/state_trackers/oxr/oxr_api_instance.c b/src/xrt/state_trackers/oxr/oxr_api_instance.c new file mode 100644 index 000000000..efce9c48c --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_api_instance.c @@ -0,0 +1,219 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Holds instance related entrypoints. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_api + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xrt/xrt_compiler.h" +#include "xrt/xrt_prober.h" + +#include "util/u_debug.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" +#include "oxr_two_call.h" + +#include "oxr_api_funcs.h" +#include "oxr_api_verify.h" + + +static const XrExtensionProperties extension_properties[] = { +#ifdef XR_USE_GRAPHICS_API_OPENGL + {XR_TYPE_EXTENSION_PROPERTIES, NULL, XR_KHR_OPENGL_ENABLE_EXTENSION_NAME, + XR_KHR_opengl_enable_SPEC_VERSION}, +#endif +#ifdef XR_USE_GRAPHICS_API_VULKAN + {XR_TYPE_EXTENSION_PROPERTIES, NULL, XR_KHR_VULKAN_ENABLE_EXTENSION_NAME, + XR_KHR_vulkan_enable_SPEC_VERSION}, +#endif + {XR_TYPE_EXTENSION_PROPERTIES, NULL, XR_KHR_HEADLESS_EXTENSION_NAME, + XR_KHR_headless_SPEC_VERSION}, +#ifdef XR_USE_TIMESPEC + {XR_TYPE_EXTENSION_PROPERTIES, NULL, + XR_KHR_CONVERT_TIMESPEC_TIME_EXTENSION_NAME, + XR_KHR_convert_timespec_time_SPEC_VERSION}, +#endif +}; + +XrResult +oxr_xrEnumerateInstanceExtensionProperties(const char* layerName, + uint32_t propertyCapacityInput, + uint32_t* propertyCountOutput, + XrExtensionProperties* properties) +{ + struct oxr_logger log; + oxr_log_init(&log, "xrEnumerateInstanceExtensionProperties"); + + OXR_TWO_CALL_HELPER(&log, propertyCapacityInput, propertyCountOutput, + properties, ARRAY_SIZE(extension_properties), + extension_properties); +} + +XrResult +oxr_xrCreateInstance(const XrInstanceCreateInfo* createInfo, + XrInstance* out_instance) +{ + XrResult ret; + struct oxr_logger log; + oxr_log_init(&log, "xrCreateInstance"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, createInfo, + XR_TYPE_INSTANCE_CREATE_INFO); + struct oxr_instance* inst; + + ret = oxr_instance_create(&log, createInfo, &inst); + if (ret != XR_SUCCESS) { + return ret; + } + + *out_instance = oxr_instance_to_openxr(inst); + + return XR_SUCCESS; +} + +XrResult +oxr_xrDestroyInstance(XrInstance instance) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrDestroyInstance"); + + return oxr_instance_destroy(&log, inst); +} + +XrResult +oxr_xrGetInstanceProperties(XrInstance instance, + XrInstanceProperties* instanceProperties) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrGetInstanceProperties"); + + return oxr_instance_get_properties(&log, inst, instanceProperties); +} + +XrResult +oxr_xrPollEvent(XrInstance instance, XrEventDataBuffer* eventData) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, "xrPollEvent"); + OXR_VERIFY_ARG_NOT_NULL(&log, eventData); + + return oxr_poll_event(&log, inst, eventData); +} + +XrResult +oxr_xrResultToString(XrInstance instance, + XrResult value, + char buffer[XR_MAX_RESULT_STRING_SIZE]) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrResultToString"); + + OXR_WARN_ONCE(&log, "fill in properly"); + buffer[0] = '\0'; + + return XR_SUCCESS; +} + +XrResult +oxr_xrStructureTypeToString(XrInstance instance, + XrStructureType value, + char buffer[XR_MAX_STRUCTURE_NAME_SIZE]) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrStructureTypeToString"); + + OXR_WARN_ONCE(&log, "fill in properly"); + buffer[0] = '\0'; + + return XR_SUCCESS; +} + +XrResult +oxr_xrStringToPath(XrInstance instance, const char* pathString, XrPath* path) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrStringToPath"); + + OXR_WARN_ONCE(&log, "fill in properly"); + + return XR_SUCCESS; +} + +XrResult +oxr_xrPathToString(XrInstance instance, + XrPath path, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + char* buffer) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrPathToString"); + + OXR_WARN_ONCE(&log, "fill in properly"); + + if (bufferCountOutput != NULL) { + *bufferCountOutput = 1; + } + + if (buffer != NULL && bufferCapacityInput > 0) { + buffer[0] = '\0'; + } + + return XR_SUCCESS; +} + +// ---- XR_KHR_convert_timespec_time extension +#ifdef XR_USE_TIMESPEC +XrResult +oxr_xrConvertTimespecTimeToTimeKHR(XrInstance instance, + const struct timespec* timespecTime, + XrTime* time) +{ + //! @todo do we need to check and see if this extension was enabled + //! first? + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrConvertTimespecTimeToTimeKHR"); + OXR_VERIFY_ARG_NOT_NULL(&log, timespecTime); + OXR_VERIFY_ARG_NOT_NULL(&log, time); + return oxr_instance_convert_timespec_to_time(&log, inst, timespecTime, + time); +} + + +XrResult +oxr_xrConvertTimeToTimespecTimeKHR(XrInstance instance, + XrTime time, + struct timespec* timespecTime) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrConvertTimeToTimespecTimeKHR"); + OXR_VERIFY_ARG_NOT_NULL(&log, timespecTime); + return oxr_instance_convert_time_to_timespec(&log, inst, time, + timespecTime); +} + +#endif // XR_USE_TIMESPEC diff --git a/src/xrt/state_trackers/oxr/oxr_api_negotiate.c b/src/xrt/state_trackers/oxr/oxr_api_negotiate.c new file mode 100644 index 000000000..75497699c --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_api_negotiate.c @@ -0,0 +1,269 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief File for negotiating with the loader. + * @author Ryan Pavlik <ryan.pavlik@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_api + */ + + +#include <stdio.h> +#include <string.h> + +#include "xrt/xrt_compiler.h" +#include "util/u_debug.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" + +#include "oxr_api_funcs.h" +#include "oxr_api_verify.h" + + + +DEBUG_GET_ONCE_BOOL_OPTION(negotiate, "OXR_DEBUG_NEGOTIATE", false) + +#define PRINT_NEGOTIATE(...) \ + do { \ + if (debug_get_bool_option_negotiate()) { \ + fprintf(stderr, __VA_ARGS__); \ + } \ + } while (false) + + +XrResult +xrNegotiateLoaderRuntimeInterface(const XrNegotiateLoaderInfo* loaderInfo, + XrNegotiateRuntimeRequest* runtimeRequest) +{ + PRINT_NEGOTIATE("xrNegotiateLoaderRuntimeInterface\n"); + + // Make sure that we understand the structs passed to this function. + if (loaderInfo->structType != XR_LOADER_INTERFACE_STRUCT_LOADER_INFO || + loaderInfo->structVersion != XR_LOADER_INFO_STRUCT_VERSION || + loaderInfo->structSize != sizeof(XrNegotiateLoaderInfo)) { + PRINT_NEGOTIATE("\tloaderInfo bad!\n"); + return XR_ERROR_INITIALIZATION_FAILED; + } + + // Make sure that we understand the structs passed to this function. + if (runtimeRequest->structType != + XR_LOADER_INTERFACE_STRUCT_RUNTIME_REQUEST || + runtimeRequest->structVersion != + XR_CURRENT_LOADER_RUNTIME_VERSION || + runtimeRequest->structSize != sizeof(XrNegotiateRuntimeRequest)) { + PRINT_NEGOTIATE("\truntimeRequest bad!\n"); + return XR_ERROR_INITIALIZATION_FAILED; + } + + // TODO: properly define what we support + uint16_t supported_major = XR_VERSION_MAJOR(XR_CURRENT_API_VERSION); + uint16_t supported_minor = XR_VERSION_MINOR(XR_CURRENT_API_VERSION); + + uint16_t requested_min_major = + XR_VERSION_MAJOR(loaderInfo->minInterfaceVersion); + uint16_t requested_min_minor = + XR_VERSION_MINOR(loaderInfo->minInterfaceVersion); + + uint16_t requested_max_major = + XR_VERSION_MAJOR(loaderInfo->maxInterfaceVersion); + uint16_t requested_max_minor = + XR_VERSION_MINOR(loaderInfo->maxInterfaceVersion); + + if (supported_major > requested_max_major || + supported_major < requested_min_major) { + PRINT_NEGOTIATE( + "\tXRT - OpenXR doesn't support requested version %d.%d <= " + "%d.%d <= %d.%d", + requested_min_major, requested_min_minor, supported_major, + supported_minor, requested_max_major, requested_max_minor); + return XR_ERROR_INITIALIZATION_FAILED; + } + + runtimeRequest->getInstanceProcAddr = oxr_xrGetInstanceProcAddr; + runtimeRequest->runtimeInterfaceVersion = + XR_CURRENT_LOADER_RUNTIME_VERSION; + runtimeRequest->runtimeXrVersion = + XR_MAKE_VERSION(0, XR_HEADER_VERSION, 0); + + PRINT_NEGOTIATE("\tall ok!\n"); + + return XR_SUCCESS; +} + +XrResult +oxr_xrEnumerateApiLayerProperties(uint32_t propertyCapacityInput, + uint32_t* propertyCountOutput, + XrApiLayerProperties* properties) +{ + struct oxr_logger log; + oxr_log_init(&log, "xrEnumerateApiLayerProperties"); + + /* We have no layers inbuilt. */ + if (propertyCountOutput != NULL) { + *propertyCountOutput = 0; + } + + return XR_SUCCESS; +} + +/*! + * @brief Helper define for generating that GetInstanceProcAddr function. + */ +#define ENTRY_IF(funcName) \ + if (strcmp(name, #funcName) == 0) { \ + PFN_##funcName ret = &oxr_##funcName; \ + *function = (PFN_xrVoidFunction)(ret); \ + } + +/*! + * @brief Helper define for generating that GetInstanceProcAddr function. + */ +#define ENTRY_ELSE_IF(funcName) \ + else if (strcmp(name, #funcName) == 0) \ + { \ + PFN_##funcName ret = &oxr_##funcName; \ + *function = (PFN_xrVoidFunction)(ret); \ + } + +/*! + * Handle a non-null instance pointer. + */ +static XrResult +handle_none_null(struct oxr_logger* log, + const char* name, + PFN_xrVoidFunction* function) +{ + ENTRY_IF(xrGetInstanceProcAddr) + ENTRY_ELSE_IF(xrEnumerateApiLayerProperties) + ENTRY_ELSE_IF(xrEnumerateInstanceExtensionProperties) + ENTRY_ELSE_IF(xrCreateInstance) + ENTRY_ELSE_IF(xrDestroyInstance) + ENTRY_ELSE_IF(xrGetInstanceProperties) + ENTRY_ELSE_IF(xrPollEvent) + ENTRY_ELSE_IF(xrResultToString) + ENTRY_ELSE_IF(xrStructureTypeToString) + ENTRY_ELSE_IF(xrGetSystem) + ENTRY_ELSE_IF(xrGetSystemProperties) + ENTRY_ELSE_IF(xrEnumerateEnvironmentBlendModes) + ENTRY_ELSE_IF(xrCreateSession) + ENTRY_ELSE_IF(xrDestroySession) + ENTRY_ELSE_IF(xrEnumerateReferenceSpaces) + ENTRY_ELSE_IF(xrCreateReferenceSpace) + ENTRY_ELSE_IF(xrGetReferenceSpaceBoundsRect) + ENTRY_ELSE_IF(xrCreateActionSpace) + ENTRY_ELSE_IF(xrLocateSpace) + ENTRY_ELSE_IF(xrDestroySpace) + ENTRY_ELSE_IF(xrEnumerateViewConfigurations) + ENTRY_ELSE_IF(xrGetViewConfigurationProperties) + ENTRY_ELSE_IF(xrEnumerateViewConfigurationViews) + ENTRY_ELSE_IF(xrEnumerateSwapchainFormats) + ENTRY_ELSE_IF(xrCreateSwapchain) + ENTRY_ELSE_IF(xrDestroySwapchain) + ENTRY_ELSE_IF(xrEnumerateSwapchainImages) + ENTRY_ELSE_IF(xrAcquireSwapchainImage) + ENTRY_ELSE_IF(xrWaitSwapchainImage) + ENTRY_ELSE_IF(xrReleaseSwapchainImage) + ENTRY_ELSE_IF(xrBeginSession) + ENTRY_ELSE_IF(xrEndSession) + ENTRY_ELSE_IF(xrWaitFrame) + ENTRY_ELSE_IF(xrBeginFrame) + ENTRY_ELSE_IF(xrEndFrame) + ENTRY_ELSE_IF(xrLocateViews) + ENTRY_ELSE_IF(xrStringToPath) + ENTRY_ELSE_IF(xrPathToString) + ENTRY_ELSE_IF(xrCreateActionSet) + ENTRY_ELSE_IF(xrDestroyActionSet) + ENTRY_ELSE_IF(xrCreateAction) + ENTRY_ELSE_IF(xrDestroyAction) + ENTRY_ELSE_IF(xrSetInteractionProfileSuggestedBindings) + ENTRY_ELSE_IF(xrGetCurrentInteractionProfile) + ENTRY_ELSE_IF(xrGetActionStateBoolean) + ENTRY_ELSE_IF(xrGetActionStateVector1f) + ENTRY_ELSE_IF(xrGetActionStateVector2f) + ENTRY_ELSE_IF(xrGetActionStatePose) + ENTRY_ELSE_IF(xrSyncActionData) + ENTRY_ELSE_IF(xrGetBoundSourcesForAction) + ENTRY_ELSE_IF(xrGetInputSourceLocalizedName) + ENTRY_ELSE_IF(xrApplyHapticFeedback) + ENTRY_ELSE_IF(xrStopHapticFeedback) +#ifdef XR_KHR_visibility_mask + ENTRY_ELSE_IF(xrGetVisibilityMaskKHR) +#endif +#ifdef XR_USE_TIMESPEC + ENTRY_ELSE_IF(xrConvertTimespecTimeToTimeKHR) + ENTRY_ELSE_IF(xrConvertTimeToTimespecTimeKHR) +#endif +#ifdef XR_EXT_performance_settings + ENTRY_ELSE_IF(xrPerfSettingsSetPerformanceLevelEXT) +#endif +#ifdef XR_EXT_thermal_query + ENTRY_ELSE_IF(xrThermalGetTemperatureTrendEXT) +#endif +#ifdef XR_EXT_debug_utils + ENTRY_ELSE_IF(xrSetDebugUtilsObjectNameEXT) + ENTRY_ELSE_IF(xrCreateDebugUtilsMessengerEXT) + ENTRY_ELSE_IF(xrDestroyDebugUtilsMessengerEXT) + ENTRY_ELSE_IF(xrSubmitDebugUtilsMessageEXT) + ENTRY_ELSE_IF(xrSessionBeginDebugUtilsLabelRegionEXT) + ENTRY_ELSE_IF(xrSessionEndDebugUtilsLabelRegionEXT) + ENTRY_ELSE_IF(xrSessionInsertDebugUtilsLabelEXT) +#endif +#ifdef XR_USE_GRAPHICS_API_OPENGL + ENTRY_ELSE_IF(xrGetOpenGLGraphicsRequirementsKHR) +#endif +#ifdef XR_USE_GRAPHICS_API_VULKAN + ENTRY_ELSE_IF(xrGetVulkanInstanceExtensionsKHR) + ENTRY_ELSE_IF(xrGetVulkanDeviceExtensionsKHR) + ENTRY_ELSE_IF(xrGetVulkanGraphicsDeviceKHR) + ENTRY_ELSE_IF(xrGetVulkanGraphicsRequirementsKHR) +#endif + + + if ((*function) == NULL) { + return oxr_error(log, XR_ERROR_FUNCTION_UNSUPPORTED, + "(name = \"%s\")", name); + } + + return XR_SUCCESS; +} + +/*! + * Special case a null instance pointer. + */ +static XrResult +handle_null(struct oxr_logger* log, + const char* name, + PFN_xrVoidFunction* function) +{ + ENTRY_IF(xrCreateInstance) + ENTRY_ELSE_IF(xrEnumerateInstanceExtensionProperties) + + if ((*function) == NULL) { + return oxr_error(log, XR_ERROR_FUNCTION_UNSUPPORTED, + "(name = \"%s\")", name); + } + + return XR_SUCCESS; +} + +XrResult +oxr_xrGetInstanceProcAddr(XrInstance instance, + const char* name, + PFN_xrVoidFunction* function) +{ + if (instance == NULL) { + struct oxr_logger log; + oxr_log_init(&log, "xrGetInstanceProcAddr"); + + return handle_null(&log, name, function); + } else { + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrGetInstanceProcAddr"); + + return handle_none_null(&log, name, function); + } +} diff --git a/src/xrt/state_trackers/oxr/oxr_api_session.c b/src/xrt/state_trackers/oxr/oxr_api_session.c new file mode 100644 index 000000000..afe2b5a0c --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_api_session.c @@ -0,0 +1,228 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Session entrypoints for the OpenXR state tracker. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_api + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xrt/xrt_compiler.h" + +#include "util/u_debug.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" +#include "oxr_two_call.h" + +#include "oxr_api_funcs.h" +#include "oxr_api_verify.h" + + + +XrResult +oxr_xrCreateSession(XrInstance instance, + const XrSessionCreateInfo* createInfo, + XrSession* out_session) +{ + XrResult ret; + struct oxr_instance* inst; + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrCreateSession"); + + ret = oxr_verify_XrSessionCreateInfo(&log, createInfo); + if (ret != XR_SUCCESS) { + return ret; + } + + ret = oxr_session_create(&log, &inst->system, + (XrStructureType*)createInfo->next, &sess); + if (ret != XR_SUCCESS) { + return ret; + } + + *out_session = oxr_session_to_openxr(sess); + + return XR_SUCCESS; +} + +XrResult +oxr_xrDestroySession(XrSession session) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrDestroySession"); + + return oxr_session_destroy(&log, sess); +} + +XrResult +oxr_xrBeginSession(XrSession session, const XrSessionBeginInfo* beginInfo) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrBeginSession"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, beginInfo, + XR_TYPE_SESSION_BEGIN_INFO); + + return oxr_session_begin(&log, sess, beginInfo); +} + +XrResult +oxr_xrEndSession(XrSession session) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrEndSession"); + + return oxr_session_end(&log, sess); +} + +XrResult +oxr_xrWaitFrame(XrSession session, + const XrFrameWaitInfo* frameWaitInfo, + XrFrameState* frameState) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrWaitFrame"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, frameState, XR_TYPE_FRAME_STATE); + OXR_VERIFY_ARG_NOT_NULL(&log, frameState); + + return oxr_session_frame_wait(&log, sess, frameState); +} + +XrResult +oxr_xrBeginFrame(XrSession session, const XrFrameBeginInfo* frameBeginInfo) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrBeginFrame"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, frameBeginInfo, + XR_TYPE_FRAME_BEGIN_INFO); + + return oxr_session_frame_begin(&log, sess); +} + +XrResult +oxr_xrEndFrame(XrSession session, const XrFrameEndInfo* frameEndInfo) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrEndFrame"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, frameEndInfo, + XR_TYPE_FRAME_END_INFO); + + return oxr_session_frame_end(&log, sess, frameEndInfo); +} + +XrResult +oxr_xrLocateViews(XrSession session, + const XrViewLocateInfo* viewLocateInfo, + XrViewState* viewState, + uint32_t viewCapacityInput, + uint32_t* viewCountOutput, + XrView* views) +{ + struct oxr_session* sess; + struct oxr_space* spc; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrLocateViews"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, viewLocateInfo, + XR_TYPE_VIEW_LOCATE_INFO); + OXR_VERIFY_SPACE_NOT_NULL(&log, viewLocateInfo->space, spc); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, viewState, XR_TYPE_VIEW_STATE); + + if (viewCapacityInput == 0) { + OXR_VERIFY_ARG_NOT_NULL(&log, viewCountOutput); + } else { + OXR_VERIFY_ARG_NOT_NULL(&log, views); + } + + return oxr_session_views(&log, sess, viewLocateInfo, viewState, + viewCapacityInput, viewCountOutput, views); +} + + +/* + * + * XR_KHR_visibility_mask + * + */ + +#ifdef XR_KHR_visibility_mask + +XrResult +oxr_xrGetVisibilityMaskKHR(XrSession session, + XrViewConfigurationType viewConfigurationType, + uint32_t viewIndex, + XrVisibilityMaskTypeKHR visibilityMaskType, + XrVisibilityMaskKHR* visibilityMask) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrGetVisibilityMaskKHR"); + + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +#endif + + +/* + * + * XR_EXT_performance_settings + * + */ + +#ifdef XR_EXT_performance_settings + +XrResult +oxr_xrPerfSettingsSetPerformanceLevelEXT(XrSession session, + XrPerfSettingsDomainEXT domain, + XrPerfSettingsLevelEXT level) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrPerfSettingsSetPerformanceLevelEXT"); + + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +#endif + + +/* + * + * XR_EXT_thermal_query + * + */ + +#ifdef XR_EXT_thermal_query + +XrResult +oxr_xrThermalGetTemperatureTrendEXT( + XrSession session, + XrPerfSettingsDomainEXT domain, + XrPerfSettingsNotificationLevelEXT* notificationLevel, + float* tempHeadroom, + float* tempSlope) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrThermalGetTemperatureTrendEXT"); + + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +#endif diff --git a/src/xrt/state_trackers/oxr/oxr_api_space.c b/src/xrt/state_trackers/oxr/oxr_api_space.c new file mode 100644 index 000000000..54e0e9992 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_api_space.c @@ -0,0 +1,125 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Space, space, space, SPAAAAAAAAAAAAAAAAAAAAAAAAAACE! + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_api + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xrt/xrt_compiler.h" + +#include "util/u_debug.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" +#include "oxr_two_call.h" + +#include "oxr_api_funcs.h" +#include "oxr_api_verify.h" + + +XrResult +oxr_xrCreateActionSpace(XrAction action, + const XrActionSpaceCreateInfo* createInfo, + XrSpace* space) +{ + struct oxr_action* act; + struct oxr_logger log; + OXR_VERIFY_ACTION_AND_INIT_LOG(&log, action, act, + "xrCreateActionSpace"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, createInfo, + XR_TYPE_ACTION_SPACE_CREATE_INFO); + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +static const XrReferenceSpaceType session_spaces[] = { + XR_REFERENCE_SPACE_TYPE_VIEW, + XR_REFERENCE_SPACE_TYPE_LOCAL, + XR_REFERENCE_SPACE_TYPE_STAGE, +}; + +XrResult +oxr_xrEnumerateReferenceSpaces(XrSession session, + uint32_t spaceCapacityInput, + uint32_t* spaceCountOutput, + XrReferenceSpaceType* spaces) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrEnumerateReferenceSpaces"); + + OXR_TWO_CALL_HELPER(&log, spaceCapacityInput, spaceCountOutput, spaces, + ARRAY_SIZE(session_spaces), session_spaces); +} + +XrResult +oxr_xrGetReferenceSpaceBoundsRect(XrSession session, + XrReferenceSpaceType referenceSpaceType, + XrExtent2Df* bounds) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrGetReferenceSpaceBoundsRect"); + + //! @todo Implement + return oxr_error(&log, XR_ERROR_HANDLE_INVALID, " not implemented"); +} + +XrResult +oxr_xrCreateReferenceSpace(XrSession session, + const XrReferenceSpaceCreateInfo* createInfo, + XrSpace* out_space) +{ + XrResult ret; + struct oxr_session* sess; + struct oxr_space* spc; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrCreateReferenceSpace"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, createInfo, + XR_TYPE_REFERENCE_SPACE_CREATE_INFO); + + ret = oxr_space_reference_create(&log, sess, createInfo, &spc); + if (ret != XR_SUCCESS) { + return ret; + } + + *out_space = oxr_space_to_openxr(spc); + + return XR_SUCCESS; +} + +XrResult +oxr_xrLocateSpace(XrSpace space, + XrSpace baseSpace, + XrTime time, + XrSpaceRelation* relation) +{ + struct oxr_space* spc; + struct oxr_space* baseSpc; + struct oxr_logger log; + OXR_VERIFY_SPACE_AND_INIT_LOG(&log, space, spc, "xrLocateSpace"); + OXR_VERIFY_SPACE_NOT_NULL(&log, baseSpace, baseSpc); + OXR_VERIFY_ARG_NOT_NULL(&log, relation); + + return oxr_space_locate(&log, spc, baseSpc, time, relation); +} + +XrResult +oxr_xrDestroySpace(XrSpace space) +{ + struct oxr_space* spc; + struct oxr_logger log; + OXR_VERIFY_SPACE_AND_INIT_LOG(&log, space, spc, "xrDestroySpace"); + + return oxr_space_destroy(&log, spc); +} diff --git a/src/xrt/state_trackers/oxr/oxr_api_swapchain.c b/src/xrt/state_trackers/oxr/oxr_api_swapchain.c new file mode 100644 index 000000000..6d4f221bd --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_api_swapchain.c @@ -0,0 +1,146 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Swapchain entrypoints for the OpenXR state tracker. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_api + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xrt/xrt_compiler.h" + +#include "util/u_debug.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" +#include "oxr_two_call.h" + +#include "oxr_api_funcs.h" +#include "oxr_api_verify.h" + + +XrResult +oxr_xrEnumerateSwapchainFormats(XrSession session, + uint32_t formatCapacityInput, + uint32_t* formatCountOutput, + int64_t* formats) +{ + struct oxr_session* sess; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrEnumerateSwapchainFormats"); + + return oxr_session_enumerate_formats(&log, sess, formatCapacityInput, + formatCountOutput, formats); +} + +XrResult +oxr_xrCreateSwapchain(XrSession session, + const XrSwapchainCreateInfo* createInfo, + XrSwapchain* out_swapchain) +{ + XrResult ret; + struct oxr_session* sess; + struct oxr_swapchain* sc; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, + "xrCreateSwapchain"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, createInfo, + XR_TYPE_SWAPCHAIN_CREATE_INFO); + OXR_VERIFY_ARG_NOT_NULL(&log, out_swapchain); + + ret = sess->create_swapchain(&log, sess, createInfo, &sc); + if (ret != XR_SUCCESS) { + return ret; + } + + *out_swapchain = oxr_swapchain_to_openxr(sc); + + return XR_SUCCESS; +} + +XrResult +oxr_xrDestroySwapchain(XrSwapchain swapchain) +{ + struct oxr_swapchain* sc; + struct oxr_logger log; + OXR_VERIFY_SWAPCHAIN_AND_INIT_LOG(&log, swapchain, sc, + "xrDestroySwapchain"); + + return sc->destroy(&log, sc); +} + +XrResult +oxr_xrEnumerateSwapchainImages(XrSwapchain swapchain, + uint32_t imageCapacityInput, + uint32_t* imageCountOutput, + XrSwapchainImageBaseHeader* images) +{ + struct oxr_swapchain* sc; + struct oxr_logger log; + OXR_VERIFY_SWAPCHAIN_AND_INIT_LOG(&log, swapchain, sc, + "xrEnumerateSwapchainImages"); + struct xrt_swapchain* xsc = sc->swapchain; + + if (imageCountOutput != NULL) { + *imageCountOutput = xsc->num_images; + } + if (imageCapacityInput == 0) { + return XR_SUCCESS; + } + if (imageCapacityInput < xsc->num_images) { + return oxr_error(&log, XR_ERROR_SIZE_INSUFFICIENT, + "(imageCapacityInput = %u)", + imageCapacityInput); + } + + return sc->enumerate_images(&log, sc, xsc->num_images, images); +} + +XrResult +oxr_xrAcquireSwapchainImage(XrSwapchain swapchain, + const XrSwapchainImageAcquireInfo* acquireInfo, + uint32_t* index) +{ + struct oxr_swapchain* sc; + struct oxr_logger log; + OXR_VERIFY_SWAPCHAIN_AND_INIT_LOG(&log, swapchain, sc, + "xrAcquireSwapchainImage"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, acquireInfo, + XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO); + OXR_VERIFY_ARG_NOT_NULL(&log, index); + + return sc->acquire_image(&log, sc, acquireInfo, index); +} + +XrResult +oxr_xrWaitSwapchainImage(XrSwapchain swapchain, + const XrSwapchainImageWaitInfo* waitInfo) +{ + struct oxr_swapchain* sc; + struct oxr_logger log; + OXR_VERIFY_SWAPCHAIN_AND_INIT_LOG(&log, swapchain, sc, + "xrWaitSwapchainImage"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, waitInfo, + XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO); + + return sc->wait_image(&log, sc, waitInfo); +} + +XrResult +oxr_xrReleaseSwapchainImage(XrSwapchain swapchain, + const XrSwapchainImageReleaseInfo* releaseInfo) +{ + struct oxr_swapchain* sc; + struct oxr_logger log; + OXR_VERIFY_SWAPCHAIN_AND_INIT_LOG(&log, swapchain, sc, + "xrReleaseSwapchainImage"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, releaseInfo, + XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO); + + return sc->release_image(&log, sc, releaseInfo); +} diff --git a/src/xrt/state_trackers/oxr/oxr_api_system.c b/src/xrt/state_trackers/oxr/oxr_api_system.c new file mode 100644 index 000000000..52b272328 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_api_system.c @@ -0,0 +1,297 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Holds system related entrypoints. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_api + */ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xrt/xrt_compiler.h" +#include "xrt/xrt_gfx_gl.h" +#include "util/u_debug.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" +#include "oxr_two_call.h" + +#include "oxr_api_funcs.h" +#include "oxr_api_verify.h" + + +/*! + * A helper defines that allocates a logger on the stack and verifies both the + * instance and systemId. + */ +#define OXR_VERIFY_SYSTEM_AND_GET(log, inst, sysId, system) \ + struct oxr_system* system = NULL; \ + do { \ + XrResult ret = verify_system_id(log, inst, sysId, &system); \ + if (ret != XR_SUCCESS) { \ + return ret; \ + } \ + assert(system != NULL); \ + } while (false) + +/*! + * Function that does the actual verifing. + */ +static XrResult +verify_system_id(struct oxr_logger* log, + struct oxr_instance* inst, + XrSystemId systemId, + struct oxr_system** system) +{ + if (systemId != 1) { + return oxr_error(log, XR_ERROR_SYSTEM_INVALID, + "invalid system %lu", systemId); + } + + *system = &inst->system; + + return XR_SUCCESS; +} + +XrResult +oxr_xrGetSystem(XrInstance instance, + const XrSystemGetInfo* getInfo, + XrSystemId* systemId) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, "xrGetSystem"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, getInfo, XR_TYPE_SYSTEM_GET_INFO); + OXR_VERIFY_ARG_NOT_NULL(&log, systemId); + + struct oxr_system* selected = NULL; + struct oxr_system* systems[1] = {&inst->system}; + uint32_t num_systems = 1; + + XrResult ret = oxr_system_select(&log, systems, num_systems, + getInfo->formFactor, &selected); + if (ret != XR_SUCCESS) { + return ret; + } + + *systemId = selected->systemId; + + return XR_SUCCESS; +} + +XrResult +oxr_xrGetSystemProperties(XrInstance instance, + XrSystemId systemId, + XrSystemProperties* properties) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrGetSystemProperties"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, properties, + XR_TYPE_SYSTEM_PROPERTIES); + OXR_VERIFY_SYSTEM_AND_GET(&log, inst, systemId, sys); + + return oxr_system_get_properties(&log, sys, properties); +} + +XrResult +oxr_xrEnumerateViewConfigurations( + XrInstance instance, + XrSystemId systemId, + uint32_t viewConfigurationTypeCapacityInput, + uint32_t* viewConfigurationTypeCountOutput, + XrViewConfigurationType* viewConfigurationTypes) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrEnumerateViewConfigurations"); + OXR_VERIFY_SYSTEM_AND_GET(&log, inst, systemId, sys); + + return oxr_system_enumerate_view_confs( + &log, sys, viewConfigurationTypeCapacityInput, + viewConfigurationTypeCountOutput, viewConfigurationTypes); +} + +XrResult +oxr_xrEnumerateEnvironmentBlendModes( + XrInstance instance, + XrSystemId systemId, + uint32_t environmentBlendModeCapacityInput, + uint32_t* environmentBlendModeCountOutput, + XrEnvironmentBlendMode* environmentBlendModes) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrEnumerateEnvironmentBlendModes"); + OXR_VERIFY_SYSTEM_AND_GET(&log, inst, systemId, sys); + + return oxr_system_enumerate_blend_modes( + &log, sys, environmentBlendModeCapacityInput, + environmentBlendModeCountOutput, environmentBlendModes); +} + +XrResult +oxr_xrGetViewConfigurationProperties( + XrInstance instance, + XrSystemId systemId, + XrViewConfigurationType viewConfigurationType, + XrViewConfigurationProperties* configurationProperties) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrGetViewConfigurationProperties"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, configurationProperties, + XR_TYPE_VIEW_CONFIGURATION_PROPERTIES); + OXR_VERIFY_SYSTEM_AND_GET(&log, inst, systemId, sys); + + return oxr_system_get_view_conf_properties( + &log, sys, viewConfigurationType, configurationProperties); +} + +XrResult +oxr_xrEnumerateViewConfigurationViews( + XrInstance instance, + XrSystemId systemId, + XrViewConfigurationType viewConfigurationType, + uint32_t viewCapacityInput, + uint32_t* viewCountOutput, + XrViewConfigurationView* views) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrEnumerateViewConfigurationViews"); + OXR_VERIFY_SYSTEM_AND_GET(&log, inst, systemId, sys); + + return oxr_system_enumerate_view_conf_views( + &log, sys, viewConfigurationType, viewCapacityInput, + viewCountOutput, views); +} + + +/* + * + * OpenGL + * + */ + +#ifdef XR_USE_GRAPHICS_API_OPENGL + +XrResult +oxr_xrGetOpenGLGraphicsRequirementsKHR( + XrInstance instance, + XrSystemId systemId, + XrGraphicsRequirementsOpenGLKHR* graphicsRequirements) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrGetOpenGLGraphicsRequirementsKHR"); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, graphicsRequirements, + XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR); + OXR_VERIFY_SYSTEM_AND_GET(&log, inst, systemId, sys); + + struct xrt_api_requirements ver; + + xrt_gfx_gl_get_versions(&ver); + + graphicsRequirements->minApiVersionSupported = + XR_MAKE_VERSION(ver.min_major, ver.min_minor, ver.min_patch); + graphicsRequirements->maxApiVersionSupported = + XR_MAKE_VERSION(ver.max_major, ver.max_minor, ver.max_patch); + + return XR_SUCCESS; +} + +#endif + + +/* + * + * Vulkan + * + */ + +#ifdef XR_USE_GRAPHICS_API_VULKAN + +XrResult +oxr_xrGetVulkanInstanceExtensionsKHR(XrInstance instance, + XrSystemId systemId, + uint32_t namesCapacityInput, + uint32_t* namesCountOutput, + char* namesString) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrGetVulkanInstanceExtensionsKHR"); + OXR_VERIFY_SYSTEM_AND_GET(&log, inst, systemId, sys); + + return oxr_vk_get_instance_exts(&log, sys, namesCapacityInput, + namesCountOutput, namesString); +} + +XrResult +oxr_xrGetVulkanDeviceExtensionsKHR(XrInstance instance, + XrSystemId systemId, + uint32_t namesCapacityInput, + uint32_t* namesCountOutput, + char* namesString) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrGetVulkanDeviceExtensionsKHR"); + OXR_VERIFY_SYSTEM_AND_GET(&log, inst, systemId, sys); + + return oxr_vk_get_device_exts(&log, sys, namesCapacityInput, + namesCountOutput, namesString); +} + +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL +vkGetInstanceProcAddr(VkInstance instance, const char* pName); + +XrResult +oxr_xrGetVulkanGraphicsDeviceKHR(XrInstance instance, + XrSystemId systemId, + VkInstance vkInstance, + VkPhysicalDevice* vkPhysicalDevice) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrGetVulkanGraphicsDeviceKHR"); + OXR_VERIFY_SYSTEM_AND_GET(&log, inst, systemId, sys); + OXR_VERIFY_ARG_NOT_NULL(&log, vkPhysicalDevice); + + return oxr_vk_get_physical_device(&log, inst, sys, vkInstance, + vkGetInstanceProcAddr, + vkPhysicalDevice); +} + +XrResult +oxr_xrGetVulkanGraphicsRequirementsKHR( + XrInstance instance, + XrSystemId systemId, + XrGraphicsRequirementsVulkanKHR* graphicsRequirements) +{ + struct oxr_instance* inst; + struct oxr_logger log; + OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, + "xrGetVulkanGraphicsRequirementsKHR"); + OXR_VERIFY_SYSTEM_AND_GET(&log, inst, systemId, sys); + OXR_VERIFY_ARG_TYPE_AND_NULL(&log, graphicsRequirements, + XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR); + + return oxr_vk_get_requirements(&log, sys, graphicsRequirements); +} + +#endif diff --git a/src/xrt/state_trackers/oxr/oxr_api_verify.h b/src/xrt/state_trackers/oxr/oxr_api_verify.h new file mode 100644 index 000000000..bf0b88865 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_api_verify.h @@ -0,0 +1,157 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief File for verifing app input into api functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_api + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + +#define _OXR_VERIFY_AND_SET_AND_INIT(log, thing, new_thing, THING, name, \ + lookup) \ + do { \ + oxr_log_init(log, name); \ + if (thing == NULL) { \ + return oxr_error(log, XR_ERROR_HANDLE_INVALID, \ + "(" #thing " == NULL)"); \ + } \ + new_thing = (typeof(new_thing))thing; \ + if (new_thing->debug != OXR_XR_DEBUG_##THING) { \ + return oxr_error(log, XR_ERROR_HANDLE_INVALID, \ + "(" #thing " == %p)", \ + (void*)new_thing); \ + } \ + oxr_log_set_instance(log, lookup); \ + } while (0) + +#define _OXR_VERIFY_SET(log, arg, new_arg, THING) \ + do { \ + if (arg == NULL) { \ + return oxr_error(log, XR_ERROR_HANDLE_INVALID, \ + "(" #arg " == NULL)"); \ + } \ + new_arg = (typeof(new_arg))arg; \ + if (new_arg->debug != OXR_XR_DEBUG_##THING) { \ + return oxr_error(log, XR_ERROR_HANDLE_INVALID, \ + "(" #arg " == %p)", (void*)new_arg); \ + } \ + } while (0) + + +/*! + * @ingroup oxr_api + * @{ + */ + +// clang-format off +#define OXR_VERIFY_INSTANCE_AND_INIT_LOG(log, thing, new_thing, name) \ + _OXR_VERIFY_AND_SET_AND_INIT(log, thing, new_thing, INSTANCE, name, new_thing) +#define OXR_VERIFY_MESSENGER_AND_INIT_LOG(log, thing, new_thing, name) \ + _OXR_VERIFY_AND_SET_AND_INIT(log, thing, new_thing, MESSENGER, name, new_thing->inst) +#define OXR_VERIFY_SESSION_AND_INIT_LOG(log, thing, new_thing, name) \ + _OXR_VERIFY_AND_SET_AND_INIT(log, thing, new_thing, SESSION, name, new_thing->sys->inst) +#define OXR_VERIFY_SPACE_AND_INIT_LOG(log, thing, new_thing, name) \ + _OXR_VERIFY_AND_SET_AND_INIT(log, thing, new_thing, SPACE, name, new_thing->sess->sys->inst) +#define OXR_VERIFY_ACTION_AND_INIT_LOG(log, thing, new_thing, name) \ + _OXR_VERIFY_AND_SET_AND_INIT(log, thing, new_thing, ACTION, name, new_thing->act_set->sess->sys->inst) +#define OXR_VERIFY_SWAPCHAIN_AND_INIT_LOG(log, thing, new_thing, name) \ + _OXR_VERIFY_AND_SET_AND_INIT(log, thing, new_thing, SWAPCHAIN, name, new_thing->sess->sys->inst) +#define OXR_VERIFY_ACTIONSET_AND_INIT_LOG(log, thing, new_thing, name) \ + _OXR_VERIFY_AND_SET_AND_INIT(log, thing, new_thing, ACTIONSET, name, new_thing->sess->sys->inst) + +#define OXR_VERIFY_INSTANCE_NOT_NULL(log, arg, new_arg) _OXR_VERIFY_SET(log, arg, new_arg, INSTANCE); +#define OXR_VERIFY_MESSENGER_NOT_NULL(log, arg, new_arg) _OXR_VERIFY_SET(log, arg, new_arg, MESSENGER); +#define OXR_VERIFY_SESSION_NOT_NULL(log, arg, new_arg) _OXR_VERIFY_SET(log, arg, new_arg, SESSION); +#define OXR_VERIFY_SPACE_NOT_NULL(log, arg, new_arg) _OXR_VERIFY_SET(log, arg, new_arg, SPACE); +#define OXR_VERIFY_ACTION_NOT_NULL(log, arg, new_arg) _OXR_VERIFY_SET(log, arg, new_arg, ACTION); +#define OXR_VERIFY_SWAPCHAIN_NOT_NULL(log, arg, new_arg) _OXR_VERIFY_SET(log, arg, new_arg, SWAPCHAIN); +#define OXR_VERIFY_ACTIONSET_NOT_NULL(log, arg, new_arg) _OXR_VERIFY_SET(log, arg, new_arg, ACTIONSET); +// clang-format on + + +#define OXR_VERIFY_ARG_NOT_NULL(log, arg) \ + do { \ + if (arg == NULL) { \ + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, \ + "(" #arg " == NULL)"); \ + } \ + } while (false) + +#define OXR_VERIFY_ARG_TYPE_AND_NULL(log, arg, type_enum) \ + do { \ + if (arg == NULL) { \ + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, \ + "(" #arg "== NULL)"); \ + } \ + if (arg->type != type_enum) { \ + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, \ + "(" #arg "->type = %u)", arg->type); \ + } \ + if (arg->next != NULL) { \ + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, \ + "(" #arg "->next = %p)", arg->next); \ + } \ + } while (false) + +#define OXR_VERIFY_SUBACTION_PATHS(log, count, paths) \ + do { \ + if (count == 0 && paths != NULL) { \ + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, \ + " " #count " is zero but " #paths \ + " is not NULL"); \ + } \ + if (count > 0 && paths == NULL) { \ + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, \ + " " #count " is not zero but " #paths \ + " is NULL"); \ + } \ + } while (false) + +#define OXR_VERIFY_ARG_SINGLE_LEVEL_FIXED_LENGTH_PATH(log, path) \ + do { \ + XrResult verify_ret = oxr_verify_fixed_size_single_level_path( \ + log, path, ARRAY_SIZE(path), #path); \ + if (verify_ret != XR_SUCCESS) { \ + return verify_ret; \ + } \ + } while (false) + + +/* + * + * Implementation in oxr_verify.cpp + * + */ + +XrResult +oxr_verify_fixed_size_single_level_path(struct oxr_logger*, + const char* path, + uint32_t size, + const char* name); + +XrResult +oxr_verify_XrSessionCreateInfo(struct oxr_logger*, const XrSessionCreateInfo*); + +XrResult +oxr_verify_XrGraphicsBindingOpenGLXlibKHR( + struct oxr_logger*, const XrGraphicsBindingOpenGLXlibKHR*); + +XrResult +oxr_verify_XrGraphicsBindingVulkanKHR(struct oxr_logger*, + const XrGraphicsBindingVulkanKHR*); + +/*! + * @} + */ + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/state_trackers/oxr/oxr_event.cpp b/src/xrt/state_trackers/oxr/oxr_event.cpp new file mode 100644 index 000000000..7ba29bf92 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_event.cpp @@ -0,0 +1,148 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Holds event related functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + */ + +#include <cstdio> +#include <cstring> +#include <cstdlib> + +#include "oxr_objects.h" +#include "oxr_logger.h" + + + +struct oxr_event +{ +public: + struct oxr_event *next; + size_t length; + + +public: + inline void * + ptr() + { + return &this[1]; + } +}; + + +void +lock(struct oxr_instance *inst) +{} + +void +unlock(struct oxr_instance *inst) +{} + +struct oxr_event * +pop(struct oxr_instance *inst) +{ + auto ret = inst->next_event; + if (ret == NULL) { + return NULL; + } + + inst->next_event = ret->next; + ret->next = NULL; + + if (ret == inst->last_event) { + inst->last_event = NULL; + } + + return ret; +} + +void +push(struct oxr_instance *inst, struct oxr_event *event) +{ + auto last = inst->last_event; + if (last != NULL) { + last->next = event; + } + inst->last_event = event; + + if (inst->next_event == NULL) { + inst->next_event = event; + } +} + +#define ALLOC(log, inst, event, extra) \ + do { \ + XrResult ret = \ + oxr_event_alloc(log, inst, sizeof(**extra), event); \ + if (ret != XR_SUCCESS) { \ + return ret; \ + } \ + *extra = (typeof(*extra))(*event)->ptr(); \ + } while (false) + +static XrResult +oxr_event_alloc(struct oxr_logger *log, + struct oxr_instance *inst, + size_t size, + struct oxr_event **out_event) +{ + struct oxr_event *event = + (struct oxr_event *)calloc(1, sizeof(struct oxr_event) + size); + + if (event == NULL) { + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, + " out of memory"); + } + + event->next = NULL; + event->length = size; + + *out_event = event; + + return XR_SUCCESS; +} + +XrResult +oxr_event_push_XrEventDataSessionStateChanged(struct oxr_logger *log, + struct oxr_session *sess, + XrSessionState state, + XrTime time) +{ + struct oxr_instance *inst = sess->sys->inst; + XrEventDataSessionStateChanged *changed; + struct oxr_event *event; + + ALLOC(log, inst, &event, &changed); + + changed->type = XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED; + changed->session = oxr_session_to_openxr(sess); + changed->state = state; + changed->time = time; + + lock(inst); + push(inst, event); + unlock(inst); + + return XR_SUCCESS; +} + +XrResult +oxr_poll_event(struct oxr_logger *log, + struct oxr_instance *inst, + XrEventDataBuffer *eventData) +{ + lock(inst); + auto event = pop(inst); + unlock(inst); + + if (event == NULL) { + return XR_EVENT_UNAVAILABLE; + } + + memcpy(eventData, event->ptr(), event->length); + free(event); + + return XR_SUCCESS; +} diff --git a/src/xrt/state_trackers/oxr/oxr_instance.c b/src/xrt/state_trackers/oxr/oxr_instance.c new file mode 100644 index 000000000..96d31a093 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_instance.c @@ -0,0 +1,155 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Holds session related functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <math.h> + +#include "util/u_debug.h" +#include "util/u_time.h" + +#include "xrt/xrt_compiler.h" +#include "xrt/xrt_prober.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" + +DEBUG_GET_ONCE_FLOAT_OPTION(lfov_left, "OXR_OVERRIDE_LFOV_LEFT", 0.0f) +DEBUG_GET_ONCE_FLOAT_OPTION(lfov_right, "OXR_OVERRIDE_LFOV_RIGHT", 0.0f) +DEBUG_GET_ONCE_FLOAT_OPTION(lfov_up, "OXR_OVERRIDE_LFOV_UP", 0.0f) +DEBUG_GET_ONCE_FLOAT_OPTION(lfov_down, "OXR_OVERRIDE_LFOV_DOWN", 0.0f) + +static inline int32_t +radtodeg_for_display(float radians) +{ + return (int32_t)(radians * 180 * M_1_PI); +} + +XrResult +oxr_instance_create(struct oxr_logger *log, + const XrInstanceCreateInfo *createInfo, + struct oxr_instance **out_instance) +{ + struct oxr_instance *inst = + (struct oxr_instance *)calloc(1, sizeof(struct oxr_instance)); + inst->debug = OXR_XR_DEBUG_INSTANCE; + inst->prober = xrt_create_prober(); + + struct xrt_device *dev = + inst->prober->lelo_dallas_autoprobe(inst->prober); + + const float left_override = debug_get_float_option_lfov_left(); + if (left_override != 0.0f) { + printf( + "Overriding left eye angle_left with %f radians (%i°), " + "and right eye angle_right with %f radians (%i°)\n", + left_override, radtodeg_for_display(left_override), + -left_override, radtodeg_for_display(-left_override)); + dev->views[0].fov.angle_left = left_override; + dev->views[1].fov.angle_right = -left_override; + } + + const float right_override = debug_get_float_option_lfov_right(); + if (right_override != 0.0f) { + printf( + "Overriding left eye angle_right with %f radians (%i°), " + "and right eye angle_left with %f radians (%i°)\n", + right_override, radtodeg_for_display(right_override), + -right_override, radtodeg_for_display(-right_override)); + dev->views[0].fov.angle_right = right_override; + dev->views[1].fov.angle_left = -right_override; + } + + const float up_override = debug_get_float_option_lfov_up(); + if (up_override != 0.0f) { + printf("Overriding both eyes angle_up with %f radians (%i°)\n", + up_override, radtodeg_for_display(up_override)); + dev->views[0].fov.angle_up = up_override; + dev->views[1].fov.angle_up = up_override; + } + + const float down_override = debug_get_float_option_lfov_down(); + if (down_override != 0.0f) { + printf( + "Overriding both eyes angle_down with %f radians (%i°)\n", + down_override, radtodeg_for_display(down_override)); + dev->views[0].fov.angle_down = down_override; + dev->views[1].fov.angle_down = down_override; + } + + oxr_system_fill_in(log, inst, 1, &inst->system, dev); + + inst->timekeeping = time_state_create(); + + //! @todo check if this (and other creates) failed? + + *out_instance = inst; + + return XR_SUCCESS; +} + +XrResult +oxr_instance_destroy(struct oxr_logger *log, struct oxr_instance *inst) +{ + struct xrt_prober *prober = inst->prober; + struct xrt_device *dev = inst->system.device; + + if (dev != NULL) { + dev->destroy(dev); + inst->system.device = NULL; + } + + if (prober != NULL) { + prober->destroy(prober); + inst->prober = NULL; + } + + time_state_destroy(inst->timekeeping); + inst->timekeeping = NULL; + + free(inst); + + return XR_SUCCESS; +} + +XrResult +oxr_instance_get_properties(struct oxr_logger *log, + struct oxr_instance *inst, + XrInstanceProperties *instanceProperties) +{ + instanceProperties->runtimeVersion = XR_MAKE_VERSION(0, 0, 42); + strncpy(instanceProperties->runtimeName, + "Monado(XRT) by Collabora et al", XR_MAX_RUNTIME_NAME_SIZE - 1); + + return XR_SUCCESS; +} + +#ifdef XR_USE_TIMESPEC + +XrResult +oxr_instance_convert_time_to_timespec(struct oxr_logger *log, + struct oxr_instance *inst, + XrTime time, + struct timespec *timespecTime) +{ + time_state_to_timespec(inst->timekeeping, time, timespecTime); + return XR_SUCCESS; +} + +XrResult +oxr_instance_convert_timespec_to_time(struct oxr_logger *log, + struct oxr_instance *inst, + const struct timespec *timespecTime, + XrTime *time) +{ + *time = time_state_from_timespec(inst->timekeeping, timespecTime); + return XR_SUCCESS; +} +#endif // XR_USE_TIMESPEC diff --git a/src/xrt/state_trackers/oxr/oxr_logger.cpp b/src/xrt/state_trackers/oxr/oxr_logger.cpp new file mode 100644 index 000000000..bf30dc24f --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_logger.cpp @@ -0,0 +1,158 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Logging functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + */ + +#include <stdio.h> +#include <stdarg.h> + +#include "xrt/xrt_compiler.h" +#include "util/u_debug.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" + + +DEBUG_GET_ONCE_BOOL_OPTION(entrypoints, "OXR_DEBUG_ENTRYPOINTS", false) + +static const char * +oxr_result_to_string(XrResult result); + + +void +oxr_log_init(struct oxr_logger *logger, const char *api_func_name) +{ + if (debug_get_bool_option_entrypoints()) { + fprintf(stderr, "%s\n", api_func_name); + } + + logger->inst = NULL; + logger->api_func_name = api_func_name; +} + +void +oxr_log_set_instance(struct oxr_logger *logger, struct oxr_instance *inst) +{ + logger->inst = inst; +} + +void +oxr_log(struct oxr_logger *logger, const char *fmt, ...) +{ + if (logger->api_func_name != NULL) { + fprintf(stderr, " in %s", logger->api_func_name); + } + + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + fprintf(stderr, "\n"); +} + +void +oxr_warn(struct oxr_logger *logger, const char *fmt, ...) +{ + if (logger->api_func_name != NULL) { + fprintf(stderr, "%s WARNING: ", logger->api_func_name); + } else { + fprintf(stderr, "WARNING: "); + } + + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + fprintf(stderr, "\n"); +} + +XrResult +oxr_error(struct oxr_logger *logger, XrResult result, const char *fmt, ...) +{ + if (debug_get_bool_option_entrypoints()) { + fprintf(stderr, "\t"); + } + + fprintf(stderr, "%s", oxr_result_to_string(result)); + + if (logger->api_func_name != NULL) { + fprintf(stderr, " in %s", logger->api_func_name); + } + + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + fprintf(stderr, "\n"); + return result; +} + +static const char * +oxr_result_to_string(XrResult result) +{ + // clang-format off + switch (result) { + case XR_SUCCESS: return "XR_SUCCESS"; + case XR_TIMEOUT_EXPIRED: return "XR_TIMEOUT_EXPIRED"; + case XR_SESSION_VISIBILITY_UNAVAILABLE: return "XR_SESSION_VISIBILITY_UNAVAILABLE"; + case XR_SESSION_LOSS_PENDING: return "XR_SESSION_LOSS_PENDING"; + case XR_EVENT_UNAVAILABLE: return "XR_EVENT_UNAVAILABLE"; + case XR_STATE_UNAVAILABLE: return "XR_STATE_UNAVAILABLE"; + case XR_STATE_TYPE_UNAVAILABLE: return "XR_STATE_TYPE_UNAVAILABLE"; + case XR_SPACE_BOUNDS_UNAVAILABLE: return "XR_SPACE_BOUNDS_UNAVAILABLE"; + case XR_SESSION_NOT_FOCUSED: return "XR_SESSION_NOT_FOCUSED"; + case XR_FRAME_DISCARDED: return "XR_FRAME_DISCARDED"; + case XR_ERROR_VALIDATION_FAILURE: return "XR_ERROR_VALIDATION_FAILURE"; + case XR_ERROR_RUNTIME_FAILURE: return "XR_ERROR_RUNTIME_FAILURE"; + case XR_ERROR_OUT_OF_MEMORY: return "XR_ERROR_OUT_OF_MEMORY"; + case XR_ERROR_RUNTIME_VERSION_INCOMPATIBLE: return "XR_ERROR_RUNTIME_VERSION_INCOMPATIBLE"; + case XR_ERROR_DRIVER_INCOMPATIBLE: return "XR_ERROR_DRIVER_INCOMPATIBLE"; + case XR_ERROR_INITIALIZATION_FAILED: return "XR_ERROR_INITIALIZATION_FAILED"; + case XR_ERROR_FUNCTION_UNSUPPORTED: return "XR_ERROR_FUNCTION_UNSUPPORTED"; + case XR_ERROR_FEATURE_UNSUPPORTED: return "XR_ERROR_FEATURE_UNSUPPORTED"; + case XR_ERROR_EXTENSION_NOT_PRESENT: return "XR_ERROR_EXTENSION_NOT_PRESENT"; + case XR_ERROR_LIMIT_REACHED: return "XR_ERROR_LIMIT_REACHED"; + case XR_ERROR_SIZE_INSUFFICIENT: return "XR_ERROR_SIZE_INSUFFICIENT"; + case XR_ERROR_HANDLE_INVALID: return "XR_ERROR_HANDLE_INVALID"; + case XR_ERROR_INSTANCE_LOST: return "XR_ERROR_INSTANCE_LOST"; + case XR_ERROR_SESSION_RUNNING: return "XR_ERROR_SESSION_RUNNING"; + case XR_ERROR_SESSION_NOT_RUNNING: return "XR_ERROR_SESSION_NOT_RUNNING"; + case XR_ERROR_SESSION_LOST: return "XR_ERROR_SESSION_LOST"; + case XR_ERROR_SYSTEM_INVALID: return "XR_ERROR_SYSTEM_INVALID"; + case XR_ERROR_PATH_INVALID: return "XR_ERROR_PATH_INVALID"; + case XR_ERROR_PATH_COUNT_EXCEEDED: return "XR_ERROR_PATH_COUNT_EXCEEDED"; + case XR_ERROR_PATH_FORMAT_INVALID: return "XR_ERROR_PATH_FORMAT_INVALID"; + case XR_ERROR_LAYER_INVALID: return "XR_ERROR_LAYER_INVALID"; + case XR_ERROR_LAYER_LIMIT_EXCEEDED: return "XR_ERROR_LAYER_LIMIT_EXCEEDED"; + case XR_ERROR_SWAPCHAIN_RECT_INVALID: return "XR_ERROR_SWAPCHAIN_RECT_INVALID"; + case XR_ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED: return "XR_ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED"; + case XR_ERROR_ACTION_TYPE_MISMATCH: return "XR_ERROR_ACTION_TYPE_MISMATCH"; + case XR_ERROR_REFERENCE_SPACE_UNSUPPORTED: return "XR_ERROR_REFERENCE_SPACE_UNSUPPORTED"; + case XR_ERROR_FILE_ACCESS_ERROR: return "XR_ERROR_FILE_ACCESS_ERROR"; + case XR_ERROR_FILE_CONTENTS_INVALID: return "XR_ERROR_FILE_CONTENTS_INVALID"; + case XR_ERROR_FORM_FACTOR_UNSUPPORTED: return "XR_ERROR_FORM_FACTOR_UNSUPPORTED"; + case XR_ERROR_FORM_FACTOR_UNAVAILABLE: return "XR_ERROR_FORM_FACTOR_UNAVAILABLE"; + case XR_ERROR_API_LAYER_NOT_PRESENT: return "XR_ERROR_API_LAYER_NOT_PRESENT"; + case XR_ERROR_CALL_ORDER_INVALID: return "XR_ERROR_CALL_ORDER_INVALID"; + case XR_ERROR_GRAPHICS_DEVICE_INVALID: return "XR_ERROR_GRAPHICS_DEVICE_INVALID"; + case XR_ERROR_POSE_INVALID: return "XR_ERROR_POSE_INVALID"; + case XR_ERROR_INDEX_OUT_OF_RANGE: return "XR_ERROR_INDEX_OUT_OF_RANGE"; + case XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED: return "XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED"; + case XR_ERROR_ENVIRONMENT_BLEND_MODE_UNSUPPORTED: return "XR_ERROR_ENVIRONMENT_BLEND_MODE_UNSUPPORTED"; + case XR_ERROR_BINDINGS_DUPLICATED: return "XR_ERROR_BINDINGS_DUPLICATED"; + case XR_ERROR_NAME_DUPLICATED: return "XR_ERROR_NAME_DUPLICATED"; + case XR_ERROR_NAME_INVALID: return "XR_ERROR_NAME_INVALID"; + case XR_ERROR_ANDROID_THREAD_SETTINGS_ID_INVALID_KHR: return "XR_ERROR_ANDROID_THREAD_SETTINGS_ID_INVALID_KHR"; + case XR_ERROR_ANDROID_THREAD_SETTINGS_FAILURE_KHR: return "XR_ERROR_ANDROID_THREAD_SETTINGS_FAILURE_KHR"; + case XR_ERROR_DEBUG_UTILS_MESSENGER_INVALID_EXT: return "XR_ERROR_DEBUG_UTILS_MESSENGER_INVALID_EXT"; + default: return "<UNKNOWN>"; + } + // clang-format on +} diff --git a/src/xrt/state_trackers/oxr/oxr_logger.h b/src/xrt/state_trackers/oxr/oxr_logger.h new file mode 100644 index 000000000..b955cb639 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_logger.h @@ -0,0 +1,69 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Logging functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! + * Helper macro to log a warning just once. + * + * @ingroup oxr_main + */ +#define OXR_WARN_ONCE(log, ...) \ + do { \ + static bool _once = false; \ + if (!_once) { \ + _once = true; \ + oxr_warn(log, __VA_ARGS__); \ + } \ + } while (false) + +/*! + * Logger struct that lives on the stack, one for each call client call. + * + * @ingroup oxr_main + */ +struct oxr_logger +{ + struct oxr_instance *inst; + const char *api_func_name; +}; + + +/*! + * @ingroup oxr_main + * @{ + */ + +void +oxr_log_init(struct oxr_logger *logger, const char *api_func_name); +void +oxr_log_set_instance(struct oxr_logger *logger, struct oxr_instance *inst); +void +oxr_log(struct oxr_logger *logger, const char *fmt, ...) + XRT_PRINTF_FORMAT(2, 3); +void +oxr_warn(struct oxr_logger *logger, const char *fmt, ...) + XRT_PRINTF_FORMAT(2, 3); +XrResult +oxr_error(struct oxr_logger *logger, XrResult result, const char *fmt, ...) + XRT_PRINTF_FORMAT(3, 4); + +/*! + * @} + */ + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/state_trackers/oxr/oxr_objects.h b/src/xrt/state_trackers/oxr/oxr_objects.h new file mode 100644 index 000000000..815df7f72 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_objects.h @@ -0,0 +1,585 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Contains the instance struct that a lot of things hangs of on. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + */ + +#pragma once + +#include "xrt/xrt_device.h" +#include "xrt/xrt_compositor.h" +#include "xrt/xrt_vulkan_includes.h" +#include "xrt/xrt_openxr_includes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! + * @defgroup oxr OpenXR state tracker + * + * Client application facing code. + * + * @ingroup xrt + */ + +/*! + * @defgroup oxr_main OpenXR main code + * + * Gets called from @ref oxr_api functions and talks to devices and + * @ref comp using @ref xrt_iface. + * + * @ingroup oxr + * @{ + */ + +// For corruption and layer checking. +// clang-format off +#define OXR_XR_DEBUG_INSTANCE (*(uint64_t *)"oxrinst\0") +#define OXR_XR_DEBUG_SESSION (*(uint64_t *)"oxrsess\0") +#define OXR_XR_DEBUG_SPACE (*(uint64_t *)"oxrspac\0") +#define OXR_XR_DEBUG_ACTION (*(uint64_t *)"oxracti\0") +#define OXR_XR_DEBUG_SWAPCHAIN (*(uint64_t *)"oxrswap\0") +#define OXR_XR_DEBUG_ACTIONSET (*(uint64_t *)"oxraset\0") +#define OXR_XR_DEBUG_MESSENGER (*(uint64_t *)"oxrmess\0") +// clang-format on + + +/* + * + * Forward declare structs. + * + */ + +struct oxr_logger; +struct oxr_instance; +struct oxr_system; +struct oxr_session; +struct oxr_event; +struct oxr_swapchain; +struct oxr_space; +struct oxr_action_set; +struct oxr_action; +struct time_state; + + +/* + * + * oxr_instance.c + * + */ + +/*! + * To go back to a OpenXR object. + */ +XRT_MAYBE_UNUSED static inline XrInstance +oxr_instance_to_openxr(struct oxr_instance *inst) +{ + return (XrInstance)inst; +} + +XrResult +oxr_instance_create(struct oxr_logger *log, + const XrInstanceCreateInfo *createInfo, + struct oxr_instance **out_inst); + +XrResult +oxr_instance_destroy(struct oxr_logger *log, struct oxr_instance *inst); + +XrResult +oxr_instance_get_properties(struct oxr_logger *log, + struct oxr_instance *inst, + XrInstanceProperties *instanceProperties); + +#if XR_USE_TIMESPEC + +XrResult +oxr_instance_convert_time_to_timespec(struct oxr_logger *log, + struct oxr_instance *inst, + XrTime time, + struct timespec *timespecTime); +XrResult +oxr_instance_convert_timespec_to_time(struct oxr_logger *log, + struct oxr_instance *inst, + const struct timespec *timespecTime, + XrTime *time); +#endif // XR_USE_TIMESPEC + +/* + * + * oxr_session.c + * + */ + +/*! + * To go back to a OpenXR object. + */ +XRT_MAYBE_UNUSED static inline XrSession +oxr_session_to_openxr(struct oxr_session *sess) +{ + return (XrSession)sess; +} + +XrResult +oxr_session_create(struct oxr_logger *log, + struct oxr_system *sys, + XrStructureType *next, + struct oxr_session **out_session); + +XrResult +oxr_session_destroy(struct oxr_logger *log, struct oxr_session *sess); + +XrResult +oxr_session_enumerate_formats(struct oxr_logger *log, + struct oxr_session *sess, + uint32_t formatCapacityInput, + uint32_t *formatCountOutput, + int64_t *formats); + +XrResult +oxr_session_begin(struct oxr_logger *log, + struct oxr_session *sess, + const XrSessionBeginInfo *beginInfo); + +XrResult +oxr_session_end(struct oxr_logger *log, struct oxr_session *sess); + +/*! + * Get the view space position at the given time in relation to the + * local or stage space. + */ +XrResult +oxr_session_get_view_pose_at(struct oxr_logger *, + struct oxr_session *sess, + XrTime at_time, + struct xrt_pose *); + +XrResult +oxr_session_views(struct oxr_logger *log, + struct oxr_session *sess, + const XrViewLocateInfo *viewLocateInfo, + XrViewState *viewState, + uint32_t viewCapacityInput, + uint32_t *viewCountOutput, + XrView *views); + +XrResult +oxr_session_frame_wait(struct oxr_logger *log, + struct oxr_session *sess, + XrFrameState *frameState); + +XrResult +oxr_session_frame_begin(struct oxr_logger *log, struct oxr_session *sess); + +XrResult +oxr_session_frame_end(struct oxr_logger *log, + struct oxr_session *sess, + const XrFrameEndInfo *frameEndInfo); + + +/* + * + * oxr_space.c + * + */ + +/*! + * To go back to a OpenXR object. + */ +XRT_MAYBE_UNUSED static inline XrSpace +oxr_space_to_openxr(struct oxr_space *spc) +{ + return (XrSpace)spc; +} + +XrResult +oxr_space_reference_create(struct oxr_logger *log, + struct oxr_session *sess, + const XrReferenceSpaceCreateInfo *createInfo, + struct oxr_space **out_space); + +XrResult +oxr_space_destroy(struct oxr_logger *log, struct oxr_space *spc); + +XrResult +oxr_space_locate(struct oxr_logger *log, + struct oxr_space *spc, + struct oxr_space *baseSpc, + XrTime time, + XrSpaceRelation *relation); + +XrResult +oxr_space_ref_relation(struct oxr_logger *log, + struct oxr_session *sess, + XrReferenceSpaceType space, + XrReferenceSpaceType baseSpc, + XrTime time, + struct xrt_space_relation *out_relation); + + +/* + * + * oxr_swapchain.c + * + */ + +/*! + * To go back to a OpenXR object. + */ +XRT_MAYBE_UNUSED static inline XrSwapchain +oxr_swapchain_to_openxr(struct oxr_swapchain *sc) +{ + return (XrSwapchain)sc; +} + +XrResult +oxr_create_swapchain(struct oxr_logger *, + struct oxr_session *sess, + const XrSwapchainCreateInfo *, + struct oxr_swapchain **sc); + + +/* + * + * oxr_system.c + * + */ + +XrResult +oxr_system_select(struct oxr_logger *log, + struct oxr_system **systems, + uint32_t num_systems, + XrFormFactor form_factor, + struct oxr_system **out_selected); + +XrResult +oxr_system_fill_in(struct oxr_logger *log, + struct oxr_instance *inst, + XrSystemId systemId, + struct oxr_system *sys, + struct xrt_device *dev); + +XrResult +oxr_system_get_properties(struct oxr_logger *log, + struct oxr_system *sys, + XrSystemProperties *properties); + +XrResult +oxr_system_enumerate_view_confs( + struct oxr_logger *log, + struct oxr_system *sys, + uint32_t viewConfigurationTypeCapacityInput, + uint32_t *viewConfigurationTypeCountOutput, + XrViewConfigurationType *viewConfigurationTypes); + +XrResult +oxr_system_enumerate_blend_modes(struct oxr_logger *log, + struct oxr_system *sys, + uint32_t environmentBlendModeCapacityInput, + uint32_t *environmentBlendModeCountOutput, + XrEnvironmentBlendMode *environmentBlendModes); + +XrResult +oxr_system_get_view_conf_properties( + struct oxr_logger *log, + struct oxr_system *sys, + XrViewConfigurationType viewConfigurationType, + XrViewConfigurationProperties *configurationProperties); + +XrResult +oxr_system_enumerate_view_conf_views( + struct oxr_logger *log, + struct oxr_system *sys, + XrViewConfigurationType viewConfigurationType, + uint32_t viewCapacityInput, + uint32_t *viewCountOutput, + XrViewConfigurationView *views); + + +/* + * + * oxr_event.cpp + * + */ + +XrResult +oxr_poll_event(struct oxr_logger *log, + struct oxr_instance *inst, + XrEventDataBuffer *eventData); + +XrResult +oxr_event_push_XrEventDataSessionStateChanged(struct oxr_logger *log, + struct oxr_session *sess, + XrSessionState state, + XrTime time); + + +/* + * + * OpenGL, located in various files. + * + */ + +#ifdef XR_USE_GRAPHICS_API_OPENGL +#ifdef XR_USE_PLATFORM_XLIB + +XrResult +oxr_session_create_gl_xlib(struct oxr_logger *log, + struct oxr_system *sys, + XrGraphicsBindingOpenGLXlibKHR *next, + struct oxr_session **out_session); +#endif + +XrResult +oxr_swapchain_gl_create(struct oxr_logger *, + struct oxr_session *sess, + const XrSwapchainCreateInfo *, + struct oxr_swapchain **out_swapchain); + +#endif + + +/* + * + * Vulkan, located in various files. + * + */ + +#ifdef XR_USE_GRAPHICS_API_VULKAN + +XrResult +oxr_vk_get_instance_exts(struct oxr_logger *log, + struct oxr_system *sys, + uint32_t namesCapacityInput, + uint32_t *namesCountOutput, + char *namesString); + +XrResult +oxr_vk_get_device_exts(struct oxr_logger *log, + struct oxr_system *sys, + uint32_t namesCapacityInput, + uint32_t *namesCountOutput, + char *namesString); + +XrResult +oxr_vk_get_requirements(struct oxr_logger *log, + struct oxr_system *sys, + XrGraphicsRequirementsVulkanKHR *graphicsRequirements); + +XrResult +oxr_vk_get_physical_device(struct oxr_logger *log, + struct oxr_instance *inst, + struct oxr_system *sys, + VkInstance vkInstance, + PFN_vkGetInstanceProcAddr getProc, + VkPhysicalDevice *vkPhysicalDevice); + +XrResult +oxr_session_create_vk(struct oxr_logger *log, + struct oxr_system *sys, + XrGraphicsBindingVulkanKHR *next, + struct oxr_session **out_session); + +XrResult +oxr_swapchain_vk_create(struct oxr_logger *, + struct oxr_session *sess, + const XrSwapchainCreateInfo *, + struct oxr_swapchain **out_swapchain); + +#endif + + +/* + * + * Structs + * + */ + +/*! + * Single or multiple devices grouped together to form a system that sessions + * can be created from. Might need to open devices in order to get all + * properties from it, but shouldn't. + * + * @obj{XrSystemId} + */ +struct oxr_system +{ + struct oxr_instance *inst; + struct xrt_device *device; + XrSystemId systemId; + + XrFormFactor form_factor; + XrViewConfigurationType view_config_type; + XrViewConfigurationView views[2]; + uint32_t num_blend_modes; + XrEnvironmentBlendMode blend_modes[3]; +}; + +/*! + * Main object that ties everything together. + * + * @obj{XrInstance} + */ +struct oxr_instance +{ + uint64_t debug; + struct xrt_prober *prober; + + // Hardcoded single system. + struct oxr_system system; + + struct time_state *timekeeping; + + // Event queue. + struct oxr_event *last_event; + struct oxr_event *next_event; +}; + +/*! + * Object that client program interact with. + * + * @obj{XrSession} + */ +struct oxr_session +{ + uint64_t debug; + struct oxr_system *sys; + struct xrt_compositor *compositor; + + XrSessionState state; + bool frame_started; + + /*! + * IPD, to be expanded to a proper 3D relation. + */ + float ipd_meters; + + uint64_t nominal_frame_interval_ns; + float static_prediction_s; + + /*! + * To pipe swapchain creation to right code. + */ + XrResult (*create_swapchain)(struct oxr_logger *, + struct oxr_session *sess, + const XrSwapchainCreateInfo *, + struct oxr_swapchain **); +}; + +/*! + * Can be one of 3 references or a space that are bound to actions. + * + * @obj{XrSpace} + */ +struct oxr_space +{ + //! Magic value for debugging. + uint64_t debug; + + //! Onwer of this space. + struct oxr_session *sess; + + //! Pose that was given during creation. + struct xrt_pose pose; + + //! What kind of reference space is this, if any. + XrReferenceSpaceType type; + + //! Is this a reference space? + bool is_reference; +}; + +/*! + * A set of images used for rendering. + * + * @obj{XrSwapchain} + */ +struct oxr_swapchain +{ + //! Magic value for debugging. + uint64_t debug; + + //! Onwer of this swapchain. + struct oxr_session *sess; + + //! Compositor swapchain. + struct xrt_swapchain *swapchain; + + //! Actual state tracked! :D + int acquired_index; + + XrResult (*destroy)(struct oxr_logger *, struct oxr_swapchain *); + + XrResult (*enumerate_images)(struct oxr_logger *, + struct oxr_swapchain *, + uint32_t, + XrSwapchainImageBaseHeader *); + + XrResult (*acquire_image)(struct oxr_logger *, + struct oxr_swapchain *, + const XrSwapchainImageAcquireInfo *, + uint32_t *); + + XrResult (*wait_image)(struct oxr_logger *, + struct oxr_swapchain *, + const XrSwapchainImageWaitInfo *); + + XrResult (*release_image)(struct oxr_logger *, + struct oxr_swapchain *, + const XrSwapchainImageReleaseInfo *); +}; + +/*! + * A group of actions. + * + * @obj{XrActionSet} + */ +struct oxr_action_set +{ + //! Magic value for debugging. + uint64_t debug; + + //! Onwer of this messenger. + struct oxr_session *sess; +}; + +/*! + * A single action. + * + * @obj{XrAction} + */ +struct oxr_action +{ + //! Magic value for debugging. + uint64_t debug; + + //! Onwer of this messenger. + struct oxr_action_set *act_set; +}; + +/*! + * Debug object created by the client program. + * + * @obj{XrDebugUtilsMessengerEXT} + */ +struct oxr_debug_messenger +{ + //! Magic value for debugging. + uint64_t debug; + + //! Onwer of this messenger. + struct oxr_instance *inst; +}; + +/*! + * @} + */ + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/state_trackers/oxr/oxr_session.c b/src/xrt/state_trackers/oxr/oxr_session.c new file mode 100644 index 000000000..7babcae4a --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_session.c @@ -0,0 +1,498 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Holds session related functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + */ + + +#include <stdio.h> +#include <stdlib.h> + +#include "util/u_debug.h" +#include "math/m_api.h" +#include "util/u_time.h" + +#include "xrt/xrt_device.h" +#include "xrt/xrt_gfx_xlib.h" +#include "xrt/xrt_gfx_vk.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" +#include "oxr_two_call.h" + + +DEBUG_GET_ONCE_BOOL_OPTION(views, "OXR_DEBUG_VIEWS", false) +DEBUG_GET_ONCE_NUM_OPTION(ipd, "OXR_DEBUG_IPD_MM", 63) +DEBUG_GET_ONCE_NUM_OPTION(prediction_ms, "OXR_DEBUG_PREDICTION_MS", 11) + +static bool +is_running(XrSessionState state) +{ + switch (state) { + case XR_SESSION_STATE_RUNNING: return true; + case XR_SESSION_STATE_VISIBLE: return true; + case XR_SESSION_STATE_FOCUSED: return true; + default: return false; + } +} + +XrResult +oxr_session_enumerate_formats(struct oxr_logger *log, + struct oxr_session *sess, + uint32_t formatCapacityInput, + uint32_t *formatCountOutput, + int64_t *formats) +{ + struct xrt_compositor *xc = sess->compositor; + + OXR_TWO_CALL_HELPER(log, formatCapacityInput, formatCountOutput, + formats, xc->num_formats, xc->formats); +} + +XrResult +oxr_session_begin(struct oxr_logger *log, + struct oxr_session *sess, + const XrSessionBeginInfo *beginInfo) +{ + if (is_running(sess->state)) { + return oxr_error(log, XR_ERROR_SESSION_RUNNING, + " session is already running"); + } + + struct xrt_compositor *xc = sess->compositor; + xc->begin_session( + xc, (enum xrt_view_type)beginInfo->primaryViewConfigurationType); + + oxr_event_push_XrEventDataSessionStateChanged( + log, sess, XR_SESSION_STATE_RUNNING, 0); + oxr_event_push_XrEventDataSessionStateChanged( + log, sess, XR_SESSION_STATE_VISIBLE, 0); + oxr_event_push_XrEventDataSessionStateChanged( + log, sess, XR_SESSION_STATE_FOCUSED, 0); + + sess->state = XR_SESSION_STATE_FOCUSED; + + return XR_SUCCESS; +} + +XrResult +oxr_session_end(struct oxr_logger *log, struct oxr_session *sess) +{ + struct xrt_compositor *xc = sess->compositor; + + if (!is_running(sess->state)) { + return oxr_error(log, XR_ERROR_SESSION_NOT_RUNNING, + " session is not running"); + } + + if (sess->frame_started) { + xc->discard_frame(xc); + sess->frame_started = false; + } + + xc->end_session(xc); + + oxr_event_push_XrEventDataSessionStateChanged( + log, sess, XR_SESSION_STATE_STOPPING, 0); + oxr_event_push_XrEventDataSessionStateChanged(log, sess, + XR_SESSION_STATE_IDLE, 0); + oxr_event_push_XrEventDataSessionStateChanged( + log, sess, XR_SESSION_STATE_READY, 0); + + sess->state = XR_SESSION_STATE_READY; + + return XR_SUCCESS; +} + +XrResult +oxr_session_get_view_pose_at(struct oxr_logger *log, + struct oxr_session *sess, + XrTime at_time, + struct xrt_pose *pose) +{ + // @todo This function needs to be massively expanded to support all + // use cases this drive. The main use of this function is to get + // either the predicted position of the headset device. Right now + // it only returns the current position. But it must also deal + // with past values are allowed by the spec. See displayTime + // argument on the xrLocateViews function. It will also drive + // the function xrLocateSpace view using the view space. + // @todo If using orientation tracking only implement a neck model to + // get at least a slightly better position. + + struct xrt_device *xdev = sess->sys->device; + struct xrt_space_relation relation; + xdev->get_tracked_pose(xdev, &relation); + if ((relation.relation_flags & + XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) != 0) { + pose->orientation = relation.pose.orientation; + } else { + pose->orientation.x = 0; + pose->orientation.y = 0; + pose->orientation.z = 0; + pose->orientation.w = 1; + } + if ((relation.relation_flags & XRT_SPACE_RELATION_POSITION_VALID_BIT) != + 0) { + pose->position = relation.pose.position; + } else { + // "nominal height" 1.6m + pose->position.x = 0.0f; + pose->position.y = 1.60f; + pose->position.z = 0.0f; + } + + if ((relation.relation_flags & + XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT) != 0) { + //! @todo Forcing a fixed amount of prediction for now since + //! devices don't tell us timestamps yet. + struct xrt_quat predicted; + math_quat_integrate_velocity( + &pose->orientation, &relation.angular_velocity, + sess->static_prediction_s, &predicted); + if (debug_get_bool_option_views()) { + + fprintf( + stderr, + "\toriginal quat = {%f, %f, %f, %f} predicted = " + "{%f, %f, %f, %f}\n", + pose->orientation.x, pose->orientation.y, + pose->orientation.z, pose->orientation.w, + predicted.x, predicted.y, predicted.z, predicted.w); + } + pose->orientation = predicted; + } + + return XR_SUCCESS; +} + +void +print_view_fov(uint32_t index, const struct xrt_fov *fov) +{ + if (!debug_get_bool_option_views()) { + return; + } + + fprintf(stderr, "\tviews[%i].fov = {%f, %f, %f, %f}\n", index, + fov->angle_left, fov->angle_right, fov->angle_up, + fov->angle_down); +} + +void +print_view_pose(uint32_t index, const struct xrt_pose *pose) +{ + if (!debug_get_bool_option_views()) { + return; + } + + fprintf(stderr, "\tviews[%i].pose = {{%f, %f, %f, %f}, {%f, %f, %f}}\n", + index, pose->orientation.x, pose->orientation.y, + pose->orientation.z, pose->orientation.w, pose->position.x, + pose->position.y, pose->position.z); +} + + +XrResult +oxr_session_views(struct oxr_logger *log, + struct oxr_session *sess, + const XrViewLocateInfo *viewLocateInfo, + XrViewState *viewState, + uint32_t viewCapacityInput, + uint32_t *viewCountOutput, + XrView *views) +{ + struct xrt_device *xdev = sess->sys->device; + struct oxr_space *baseSpc = (struct oxr_space *)viewLocateInfo->space; + uint32_t num_views = 2; + + // Does this apply for all calls? + if (!baseSpc->is_reference) { + viewState->viewStateFlags = 0; + return XR_SUCCESS; + } + + // Start two call handling. + if (viewCountOutput != NULL) { + *viewCountOutput = num_views; + } + if (viewCapacityInput == 0) { + return XR_SUCCESS; + } + if (viewCapacityInput < num_views) { + return oxr_error(log, XR_ERROR_SIZE_INSUFFICIENT, + "(viewCapacityInput == %u) need %u", + viewCapacityInput, num_views); + } + // End two call handling. + + if (debug_get_bool_option_views()) { + fprintf(stderr, "%s\n", __func__); + fprintf(stderr, "\tviewLocateInfo->displayTime %lu\n", + viewLocateInfo->displayTime); + } + + // Get the viewLocateInfo->space to view space relation. + struct xrt_space_relation pure_relation; + oxr_space_ref_relation(log, sess, XR_REFERENCE_SPACE_TYPE_VIEW, + baseSpc->type, viewLocateInfo->displayTime, + &pure_relation); + + struct xrt_pose pure = pure_relation.pose; + + // @todo the fov information that we get from xdev->views[i].fov is not + // properly filled out in oh_device.c, fix before wasting time on + // debugging weird rendering when adding stuff here. + + for (uint32_t i = 0; i < num_views; i++) { + //! @todo Do not hardcode IPD. + struct xrt_vec3 eye_relation = { + sess->ipd_meters, + 0.0f, + 0.0f, + }; + struct xrt_pose view_pose; + + // Get the per view pose from the device. + xdev->get_view_pose(xdev, &eye_relation, i, &view_pose); + + // Do the magical space relation dance here. + math_pose_openxr_locate(&view_pose, &pure, &baseSpc->pose, + (struct xrt_pose *)&views[i].pose); + + // Copy the fov information directly from the device. + views[i].fov = *(XrFovf *)&xdev->views[i].fov; + + print_view_fov(i, (struct xrt_fov *)&views[i].fov); + print_view_pose(i, (struct xrt_pose *)&views[i].pose); + } + + // @todo Add tracking bit once we have them. + viewState->viewStateFlags = 0; + viewState->viewStateFlags |= XR_VIEW_STATE_POSITION_VALID_BIT; + viewState->viewStateFlags |= XR_VIEW_STATE_ORIENTATION_VALID_BIT; + + return XR_SUCCESS; +} + +XrResult +oxr_session_frame_wait(struct oxr_logger *log, + struct oxr_session *sess, + XrFrameState *frameState) +{ + if (!is_running(sess->state)) { + return oxr_error(log, XR_ERROR_SESSION_NOT_RUNNING, + " session is not running"); + } + + // OK to update this here because xrWaitFrame must be externally + // synchronized by the app. + timepoint_ns now = + time_state_get_now_and_update(sess->sys->inst->timekeeping); + + // Set defaults - may be overridden by compositor. + frameState->predictedDisplayPeriod = sess->nominal_frame_interval_ns; + frameState->predictedDisplayTime = + now + frameState->predictedDisplayPeriod; + + struct xrt_compositor *xc = sess->compositor; + xc->wait_frame(xc, &frameState->predictedDisplayTime, + &frameState->predictedDisplayPeriod); + + return XR_SUCCESS; +} + +XrResult +oxr_session_frame_begin(struct oxr_logger *log, struct oxr_session *sess) +{ + if (!is_running(sess->state)) { + return oxr_error(log, XR_ERROR_SESSION_NOT_RUNNING, + " session is not running"); + } + + struct xrt_compositor *xc = sess->compositor; + + XrResult ret; + if (sess->frame_started) { + ret = XR_FRAME_DISCARDED; + xc->discard_frame(xc); + } else { + ret = XR_SUCCESS; + sess->frame_started = true; + } + + xc->begin_frame(xc); + + return ret; +} + +static enum xrt_blend_mode +oxr_blend_mode_to_xrt(XrEnvironmentBlendMode blend_mode) +{ + // clang-format off + switch (blend_mode) { + case XR_ENVIRONMENT_BLEND_MODE_OPAQUE: return XRT_BLEND_MODE_OPAQUE; + case XR_ENVIRONMENT_BLEND_MODE_ADDITIVE: return XRT_BLEND_MODE_ADDITIVE; + case XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND: return XRT_BLEND_MODE_ALPHA_BLEND; + default: return (enum xrt_blend_mode)0; + } + // clang-format on +} + +XrResult +oxr_session_frame_end(struct oxr_logger *log, + struct oxr_session *sess, + const XrFrameEndInfo *frameEndInfo) +{ + /* + * Session state and call order. + */ + + if (!is_running(sess->state)) { + return oxr_error(log, XR_ERROR_SESSION_NOT_RUNNING, + " session is not running"); + } + if (!sess->frame_started) { + return oxr_error(log, XR_ERROR_CALL_ORDER_INVALID, + " frame not begun with xrBeginFrame"); + } + + struct xrt_compositor *xc = sess->compositor; + + /* + * Early out for discarded frame if layer count is 0, + * since then blend mode, etc. doesn't matter. + */ + if (frameEndInfo->layerCount == 0) { + xc->discard_frame(xc); + sess->frame_started = false; + + return XR_SUCCESS; + } + + /* + * Blend mode. + */ + + enum xrt_blend_mode blend_mode = + oxr_blend_mode_to_xrt(frameEndInfo->environmentBlendMode); + + if (blend_mode == 0) { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "(frameEndInfo->environmentBlendMode) " + "unknown environment blend mode"); + } + + if ((blend_mode & sess->sys->device->blend_mode) == 0) { + return oxr_error(log, + XR_ERROR_ENVIRONMENT_BLEND_MODE_UNSUPPORTED, + "(frameEndInfo->environmentBlendMode) " + "is not supported"); + } + + + /* + * Layers. + */ + + if (frameEndInfo->layers == NULL) { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "(frameEndInfo->layers == NULL)"); + } + if (frameEndInfo->layers[0]->type != + XR_TYPE_COMPOSITION_LAYER_PROJECTION) { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "(frameEndInfo->layers[0]->type)"); + } + + XrCompositionLayerProjection *proj = + (XrCompositionLayerProjection *)frameEndInfo->layers[0]; + + if (proj->viewCount != 2) { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "(frameEndInfo->layers[0]->viewCount == %u)" + " must be 2", + proj->viewCount); + } + + + /* + * Doing the real work. + */ + + struct xrt_swapchain *chains[2]; + uint32_t acquired_index[2]; + uint32_t num_chains = ARRAY_SIZE(chains); + + for (uint32_t i = 0; i < num_chains; i++) { + //! @todo Validate this above. + struct oxr_swapchain *sc = + (struct oxr_swapchain *)proj->views[i].subImage.swapchain; + chains[i] = sc->swapchain; + acquired_index[i] = proj->views[i].subImage.imageArrayIndex; + } + + xc->end_frame(xc, blend_mode, chains, acquired_index, num_chains); + + sess->frame_started = false; + + return XR_SUCCESS; +} + +XrResult +oxr_session_create(struct oxr_logger *log, + struct oxr_system *sys, + XrStructureType *next, + struct oxr_session **out_session) +{ + struct oxr_session *sess; + XrResult ret; + +#ifdef XR_USE_PLATFORM_XLIB + if (*next == XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR) { + ret = oxr_session_create_gl_xlib( + log, sys, (XrGraphicsBindingOpenGLXlibKHR *)next, &sess); + } else +#endif +#ifdef XR_USE_GRAPHICS_API_VULKAN + if (*next == XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR) { + ret = oxr_session_create_vk( + log, sys, (XrGraphicsBindingVulkanKHR *)next, &sess); + } else +#endif + { + ret = oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "(createInfo->next->type)"); + } + + if (ret != XR_SUCCESS) { + return ret; + } + + sess->ipd_meters = debug_get_num_option_ipd() / 1000.0f; + //! @todo hard-coding 90Hz + sess->nominal_frame_interval_ns = 11111111; + sess->static_prediction_s = + debug_get_num_option_prediction_ms() / 1000.0f; + + oxr_event_push_XrEventDataSessionStateChanged(log, sess, + XR_SESSION_STATE_IDLE, 0); + oxr_event_push_XrEventDataSessionStateChanged( + log, sess, XR_SESSION_STATE_READY, 0); + sess->state = XR_SESSION_STATE_READY; + + *out_session = sess; + + return ret; +} + +XrResult +oxr_session_destroy(struct oxr_logger *log, struct oxr_session *sess) +{ + sess->compositor->destroy(sess->compositor); + free(sess); + + return XR_SUCCESS; +} diff --git a/src/xrt/state_trackers/oxr/oxr_session_gl.c b/src/xrt/state_trackers/oxr/oxr_session_gl.c new file mode 100644 index 000000000..e1761a953 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_session_gl.c @@ -0,0 +1,46 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Holds OpenGL-specific session functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + * @ingroup comp_client + */ + +#include <stdlib.h> + +#include "xrt/xrt_gfx_xlib.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" +#include "oxr_two_call.h" + + +XrResult +oxr_session_create_gl_xlib(struct oxr_logger *log, + struct oxr_system *sys, + XrGraphicsBindingOpenGLXlibKHR *next, + struct oxr_session **out_session) +{ + struct xrt_compositor_gl *xcgl = xrt_gfx_provider_create_gl_xlib( + sys->device, next->xDisplay, next->visualid, next->glxFBConfig, + next->glxDrawable, next->glxContext); + + if (xcgl == NULL) { + return oxr_error(log, XR_ERROR_INITIALIZATION_FAILED, + " failed create a compositor"); + } + + struct oxr_session *sess = + (struct oxr_session *)calloc(1, sizeof(struct oxr_session)); + + sess->debug = OXR_XR_DEBUG_SESSION; + sess->sys = sys; + sess->compositor = &xcgl->base; + sess->create_swapchain = oxr_swapchain_gl_create; + + *out_session = sess; + + return XR_SUCCESS; +} diff --git a/src/xrt/state_trackers/oxr/oxr_session_vk.c b/src/xrt/state_trackers/oxr/oxr_session_vk.c new file mode 100644 index 000000000..9f2a83a06 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_session_vk.c @@ -0,0 +1,49 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Holds Vulkan specific session functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + * @ingroup comp_client + */ + +#include <stdlib.h> + +#include "xrt/xrt_gfx_vk.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" +#include "oxr_two_call.h" + + +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL +vkGetInstanceProcAddr(VkInstance instance, const char *pName); + +XrResult +oxr_session_create_vk(struct oxr_logger *log, + struct oxr_system *sys, + XrGraphicsBindingVulkanKHR *next, + struct oxr_session **out_session) +{ + struct xrt_compositor_vk *xcvk = xrt_gfx_vk_provider_create( + sys->device, next->instance, vkGetInstanceProcAddr, + next->physicalDevice, next->device, next->queueFamilyIndex, + next->queueIndex); + + if (xcvk == NULL) { + return oxr_error(log, XR_ERROR_INITIALIZATION_FAILED, + " failed create a compositor"); + } + + struct oxr_session *sess = + (struct oxr_session *)calloc(1, sizeof(struct oxr_session)); + sess->debug = OXR_XR_DEBUG_SESSION; + sess->sys = sys; + sess->compositor = &xcvk->base; + sess->create_swapchain = oxr_swapchain_vk_create; + + *out_session = sess; + + return XR_SUCCESS; +} diff --git a/src/xrt/state_trackers/oxr/oxr_space.c b/src/xrt/state_trackers/oxr/oxr_space.c new file mode 100644 index 000000000..db2654f84 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_space.c @@ -0,0 +1,260 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief So much space! + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "math/m_api.h" +#include "util/u_debug.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" + + +DEBUG_GET_ONCE_BOOL_OPTION(space, "OXR_DEBUG_SPACE", false) + +const struct xrt_pose origin = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}}; + +static XrResult +check_reference_space_type(struct oxr_logger *log, XrReferenceSpaceType type) +{ + switch (type) { + case XR_REFERENCE_SPACE_TYPE_VIEW: return XR_SUCCESS; + case XR_REFERENCE_SPACE_TYPE_LOCAL: return XR_SUCCESS; + case XR_REFERENCE_SPACE_TYPE_STAGE: return XR_SUCCESS; +#if 0 + return oxr_error(log, XR_ERROR_REFERENCE_SPACE_UNSUPPORTED, + "(createInfo->referenceSpaceType = " + "XR_REFERENCE_SPACE_TYPE_STAGE)"); +#endif + default: + return oxr_error(log, XR_ERROR_REFERENCE_SPACE_UNSUPPORTED, + "(createInfo->referenceSpaceType = " + "<UNKNOWN>)"); + } +} + +XrResult +oxr_space_reference_create(struct oxr_logger *log, + struct oxr_session *sess, + const XrReferenceSpaceCreateInfo *createInfo, + struct oxr_space **out_space) +{ + XrResult ret; + + ret = check_reference_space_type(log, createInfo->referenceSpaceType); + if (ret != XR_SUCCESS) { + return ret; + } + + if (!math_pose_validate( + (struct xrt_pose *)&createInfo->poseInReferenceSpace)) { + return oxr_error(log, XR_ERROR_POSE_INVALID, + "(createInfo->poseInReferenceSpace)"); + } + + struct oxr_space *spc = + (struct oxr_space *)calloc(1, sizeof(struct oxr_space)); + spc->debug = OXR_XR_DEBUG_SPACE; + spc->sess = sess; + spc->is_reference = true; + spc->type = createInfo->referenceSpaceType; + memcpy(&spc->pose, &createInfo->poseInReferenceSpace, + sizeof(spc->pose)); + + *out_space = spc; + + return XR_SUCCESS; +} + +XrResult +oxr_space_destroy(struct oxr_logger *log, struct oxr_space *spc) +{ + free(spc); + return XR_SUCCESS; +} + +static const char * +get_ref_space_type_short_str(struct oxr_space *spc) +{ + if (!spc->is_reference) { + return "action?"; + } + + switch (spc->type) { + case XR_REFERENCE_SPACE_TYPE_VIEW: return "view"; + case XR_REFERENCE_SPACE_TYPE_LOCAL: return "local"; + case XR_REFERENCE_SPACE_TYPE_STAGE: return "stage"; + default: return "unknown"; + } +} + +/*! + * This returns only the relation between two spaces without any of the app + * given relations applied, assumes that both spaces are reference spaces. + */ +XrResult +oxr_space_ref_relation(struct oxr_logger *log, + struct oxr_session *sess, + XrReferenceSpaceType space, + XrReferenceSpaceType baseSpc, + XrTime time, + struct xrt_space_relation *out_relation) +{ + // Treat stage space as the local space. + if (space == XR_REFERENCE_SPACE_TYPE_STAGE) { + space = XR_REFERENCE_SPACE_TYPE_LOCAL; + } + + // Treat stage space as the local space. + if (baseSpc == XR_REFERENCE_SPACE_TYPE_STAGE) { + baseSpc = XR_REFERENCE_SPACE_TYPE_LOCAL; + } + + math_relation_reset(out_relation); + + if (space == XR_REFERENCE_SPACE_TYPE_VIEW && + baseSpc == XR_REFERENCE_SPACE_TYPE_LOCAL) { + oxr_session_get_view_pose_at(log, sess, time, + &out_relation->pose); + + out_relation->relation_flags = (enum xrt_space_relation_flags)( + XRT_SPACE_RELATION_POSITION_VALID_BIT | + XRT_SPACE_RELATION_POSITION_TRACKED_BIT | + XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | + XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT); + + } else if (space == XR_REFERENCE_SPACE_TYPE_LOCAL && + baseSpc == XR_REFERENCE_SPACE_TYPE_VIEW) { + oxr_session_get_view_pose_at(log, sess, time, + &out_relation->pose); + math_pose_invert(&out_relation->pose, &out_relation->pose); + + out_relation->relation_flags = (enum xrt_space_relation_flags)( + XRT_SPACE_RELATION_POSITION_VALID_BIT | + XRT_SPACE_RELATION_POSITION_TRACKED_BIT | + XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | + XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT); + + } else if (space == baseSpc) { + // math_relation_reset() sets to identity. + + } else { + out_relation->relation_flags = 0; + return XR_SUCCESS; + } + + return XR_SUCCESS; +} + +/*! + * This returns only the relation between two directly-associated spaces without + * any of the app given relations applied. + */ +static XrResult +get_pure_space_relation(struct oxr_logger *log, + struct oxr_space *spc, + struct oxr_space *baseSpc, + XrTime time, + struct xrt_space_relation *out_relation) +{ + struct oxr_session *sess = spc->sess; + + if (spc->is_reference && baseSpc->is_reference) { + return oxr_space_ref_relation( + log, sess, spc->type, baseSpc->type, time, out_relation); + } else if (!spc->is_reference && !baseSpc->is_reference) { + // @todo Deal with action to action by keeping a true_space that + // we can always go via. Aka poor mans space graph. + // WARNING order not thought through here! + // struct xrt_pose pose1; + // struct xrt_pose pose2; + // get_pure_space_relation(log, session->true_space, baseSpc, + // time, &pose1); + // get_pure_space_relation(log, space, session->true_space, + // time, &pose2); + // math_pose_relate_2(&pose1, &pose2, out_pose); + out_relation->relation_flags = 0; + return XR_SUCCESS; + } else { + // @todo deal with action space poses. + out_relation->relation_flags = 0; + return XR_SUCCESS; + } +} + +static void +print_pose(const char *prefix, struct xrt_pose *pose) +{ + if (!debug_get_bool_option_space()) { + return; + } + + struct xrt_vec3 *p = &pose->position; + struct xrt_quat *q = &pose->orientation; + + fprintf(stderr, "%s (%f, %f, %f) (%f, %f, %f, %f)\n", prefix, p->x, + p->y, p->z, q->x, q->y, q->z, q->w); +} + +static void +print_space(const char *name, struct oxr_space *spc) +{ + if (!debug_get_bool_option_space()) { + return; + } + + const char *type_str = get_ref_space_type_short_str(spc); + fprintf(stderr, "\t%s->type %s\n\t%s->pose", name, type_str, name); + print_pose("", &spc->pose); +} + +XrResult +oxr_space_locate(struct oxr_logger *log, + struct oxr_space *spc, + struct oxr_space *baseSpc, + XrTime time, + XrSpaceRelation *relation) +{ + if (debug_get_bool_option_space()) { + fprintf(stderr, "%s\n", __func__); + } + print_space("space", spc); + print_space("baseSpace", baseSpc); + + // Get the pure space relation. + //! @todo for longer paths in "space graph" than one edge, this will be + //! a loop. + struct xrt_space_relation pure; + XrResult ret = get_pure_space_relation(log, spc, baseSpc, time, &pure); + if (ret != XR_SUCCESS) { + relation->relationFlags = 0; + return ret; + } + + // Combine space and base space poses with pure relation + struct xrt_space_relation result; + math_relation_openxr_locate(&spc->pose, &pure, &baseSpc->pose, &result); + + // Copy + relation->pose = *(XrPosef *)&result.pose; + relation->linearVelocity = *(XrVector3f *)&result.linear_velocity; + relation->angularVelocity = *(XrVector3f *)&result.angular_velocity; + relation->linearAcceleration = + *(XrVector3f *)&result.linear_acceleration; + relation->angularAcceleration = + *(XrVector3f *)&result.angular_acceleration; + relation->relationFlags = result.relation_flags; + + print_pose("\trelation->pose", (struct xrt_pose *)&relation->pose); + + return XR_SUCCESS; +} diff --git a/src/xrt/state_trackers/oxr/oxr_swapchain.c b/src/xrt/state_trackers/oxr/oxr_swapchain.c new file mode 100644 index 000000000..55ad5d03f --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_swapchain.c @@ -0,0 +1,115 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Holds swapchain related functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + */ + +#include <stdlib.h> + +#include "xrt/xrt_gfx_xlib.h" +#include "util/u_debug.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" + + +static XrResult +oxr_swapchain_acquire_image(struct oxr_logger *log, + struct oxr_swapchain *sc, + const XrSwapchainImageAcquireInfo *acquireInfo, + uint32_t *out_index) +{ + uint32_t index; + if (sc->acquired_index >= 0) { + return oxr_error(log, XR_ERROR_CALL_ORDER_INVALID, + " image already acquired"); + } + + struct xrt_swapchain *xsc = (struct xrt_swapchain *)sc->swapchain; + if (!xsc->acquire_image(xsc, &index)) { + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, + " call to xsc->acquire_image failed"); + } + + sc->acquired_index = (int)index; + *out_index = index; + + return XR_SUCCESS; +} + +static XrResult +oxr_swapchain_wait_image(struct oxr_logger *log, + struct oxr_swapchain *sc, + const XrSwapchainImageWaitInfo *waitInfo) +{ + if (sc->acquired_index < 0) { + return oxr_error(log, XR_ERROR_CALL_ORDER_INVALID, + " no image acquired"); + } + + struct xrt_swapchain *xsc = (struct xrt_swapchain *)sc->swapchain; + if (!xsc->wait_image(xsc, waitInfo->timeout, + (uint32_t)sc->acquired_index)) { + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, + " call to xsc->wait_image failed"); + } + + return XR_SUCCESS; +} + +static XrResult +oxr_swapchain_release_image(struct oxr_logger *log, + struct oxr_swapchain *sc, + const XrSwapchainImageReleaseInfo *releaseInfo) +{ + if (sc->acquired_index < 0) { + return oxr_error(log, XR_ERROR_CALL_ORDER_INVALID, + " no image acquired"); + } + + struct xrt_swapchain *xsc = (struct xrt_swapchain *)sc->swapchain; + if (!xsc->release_image(xsc, (uint32_t)sc->acquired_index)) { + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, + " call to xsc->release_image failed"); + } + sc->acquired_index = -1; + + return XR_SUCCESS; +} + +XrResult +oxr_create_swapchain(struct oxr_logger *log, + struct oxr_session *sess, + const XrSwapchainCreateInfo *createInfo, + struct oxr_swapchain **out_swapchain) +{ + struct xrt_swapchain *xsc = sess->compositor->create_swapchain( + sess->compositor, + (enum xrt_swapchain_create_flags)createInfo->createFlags, + (enum xrt_swapchain_usage_bits)createInfo->usageFlags, + createInfo->format, createInfo->sampleCount, createInfo->width, + createInfo->height, createInfo->faceCount, createInfo->arraySize, + createInfo->mipCount); + + if (xsc == NULL) { + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, + " failed to create swapchain"); + } + + struct oxr_swapchain *sc = + (struct oxr_swapchain *)calloc(1, sizeof(struct oxr_swapchain)); + sc->debug = OXR_XR_DEBUG_SWAPCHAIN; + sc->sess = sess; + sc->swapchain = xsc; + sc->acquire_image = oxr_swapchain_acquire_image; + sc->wait_image = oxr_swapchain_wait_image; + sc->release_image = oxr_swapchain_release_image; + sc->acquired_index = -1; + + *out_swapchain = sc; + + return XR_SUCCESS; +} diff --git a/src/xrt/state_trackers/oxr/oxr_swapchain_gl.c b/src/xrt/state_trackers/oxr/oxr_swapchain_gl.c new file mode 100644 index 000000000..c4075c8ac --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_swapchain_gl.c @@ -0,0 +1,72 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Holds OpenGL swapchain related functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + * @ingroup comp_client + */ + +#include <stdlib.h> + +#include "xrt/xrt_gfx_xlib.h" +#include "util/u_debug.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" + + +static XrResult +oxr_swapchain_gl_destroy(struct oxr_logger *log, struct oxr_swapchain *sc) +{ + if (sc->acquired_index >= 0) { + sc->release_image(log, sc, NULL); + } + + if (sc->swapchain != NULL) { + sc->swapchain->destroy(sc->swapchain); + sc->swapchain = NULL; + } + + return XR_SUCCESS; +} + +static XrResult +oxr_swapchain_gl_enumerate_images(struct oxr_logger *log, + struct oxr_swapchain *sc, + uint32_t count, + XrSwapchainImageBaseHeader *images) +{ + struct xrt_swapchain_gl *xsc = (struct xrt_swapchain_gl *)sc->swapchain; + XrSwapchainImageOpenGLKHR *gl_imgs = + (XrSwapchainImageOpenGLKHR *)images; + + for (uint32_t i = 0; i < count; i++) { + gl_imgs[i].image = xsc->images[i]; + } + + return XR_SUCCESS; +} + +XrResult +oxr_swapchain_gl_create(struct oxr_logger *log, + struct oxr_session *sess, + const XrSwapchainCreateInfo *createInfo, + struct oxr_swapchain **out_swapchain) +{ + struct oxr_swapchain *sc; + XrResult ret; + + ret = oxr_create_swapchain(log, sess, createInfo, &sc); + if (ret != XR_SUCCESS) { + return ret; + } + + sc->destroy = oxr_swapchain_gl_destroy; + sc->enumerate_images = oxr_swapchain_gl_enumerate_images; + + *out_swapchain = sc; + + return XR_SUCCESS; +} diff --git a/src/xrt/state_trackers/oxr/oxr_swapchain_vk.c b/src/xrt/state_trackers/oxr/oxr_swapchain_vk.c new file mode 100644 index 000000000..8d63ccdfb --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_swapchain_vk.c @@ -0,0 +1,75 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Holds Vulkan swapchain related functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + * @ingroup comp_client + */ + +#include <stdlib.h> + +#include "xrt/xrt_gfx_xlib.h" +#include "util/u_debug.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" + + +static XrResult +oxr_swapchain_vk_destroy(struct oxr_logger *log, struct oxr_swapchain *sc) +{ + if (sc->acquired_index >= 0) { + sc->release_image(log, sc, NULL); + } + + sc->acquired_index = 0; + + if (sc->swapchain != NULL) { + sc->swapchain->destroy(sc->swapchain); + sc->swapchain = NULL; + } + + return XR_SUCCESS; +} + +static XrResult +oxr_swapchain_vk_enumerate_images(struct oxr_logger *log, + struct oxr_swapchain *sc, + uint32_t count, + XrSwapchainImageBaseHeader *images) +{ + struct xrt_swapchain_vk *xscvk = + (struct xrt_swapchain_vk *)sc->swapchain; + XrSwapchainImageVulkanKHR *vk_imgs = + (XrSwapchainImageVulkanKHR *)images; + + for (uint32_t i = 0; i < count; i++) { + vk_imgs[i].image = xscvk->images[i]; + } + + return XR_SUCCESS; +} + +XrResult +oxr_swapchain_vk_create(struct oxr_logger *log, + struct oxr_session *sess, + const XrSwapchainCreateInfo *createInfo, + struct oxr_swapchain **out_swapchain) +{ + struct oxr_swapchain *sc; + XrResult ret; + + ret = oxr_create_swapchain(log, sess, createInfo, &sc); + if (ret != XR_SUCCESS) { + return ret; + } + + sc->destroy = oxr_swapchain_vk_destroy; + sc->enumerate_images = oxr_swapchain_vk_enumerate_images; + + *out_swapchain = sc; + + return XR_SUCCESS; +} diff --git a/src/xrt/state_trackers/oxr/oxr_system.c b/src/xrt/state_trackers/oxr/oxr_system.c new file mode 100644 index 000000000..26e935abc --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_system.c @@ -0,0 +1,192 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Holds system related entrypoints. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "xrt/xrt_device.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" +#include "oxr_two_call.h" + + +static bool +oxr_system_matches(struct oxr_logger *log, + struct oxr_system *sys, + XrFormFactor form_factor) +{ + return form_factor == sys->form_factor; +} + +XrResult +oxr_system_select(struct oxr_logger *log, + struct oxr_system **systems, + uint32_t num_systems, + XrFormFactor form_factor, + struct oxr_system **out_selected) +{ + struct oxr_system *selected = NULL; + for (uint32_t i = 0; i < num_systems; i++) { + if (oxr_system_matches(log, systems[i], form_factor)) { + selected = systems[i]; + break; + } + } + + if (selected == NULL) { + return oxr_error(log, XR_ERROR_FORM_FACTOR_UNSUPPORTED, + "(getInfo->formFactor) no matching system"); + } + + *out_selected = selected; + + return XR_SUCCESS; +} + +XrResult +oxr_system_fill_in(struct oxr_logger *log, + struct oxr_instance *inst, + XrSystemId systemId, + struct oxr_system *sys, + struct xrt_device *xdev) +{ + if (xdev == NULL) { + return oxr_error(log, XR_ERROR_INITIALIZATION_FAILED, + " failed to probe device"); + } + + sys->device = xdev; + sys->inst = inst; + sys->systemId = systemId; + + // clang-format off + sys->form_factor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY; + sys->view_config_type = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO; + + sys->views[0].recommendedImageRectWidth = xdev->views[0].display.w_pixels; + sys->views[0].maxImageRectWidth = xdev->views[0].display.w_pixels; + sys->views[0].recommendedImageRectHeight = xdev->views[0].display.h_pixels; + sys->views[0].maxImageRectHeight = xdev->views[0].display.h_pixels; + sys->views[0].recommendedSwapchainSampleCount = 1; + sys->views[0].maxSwapchainSampleCount = 1; + + sys->views[1].recommendedImageRectWidth = xdev->views[1].display.w_pixels; + sys->views[1].maxImageRectWidth = xdev->views[1].display.w_pixels; + sys->views[1].recommendedImageRectHeight = xdev->views[1].display.h_pixels; + sys->views[1].maxImageRectHeight = xdev->views[1].display.h_pixels; + sys->views[1].recommendedSwapchainSampleCount = 1; + sys->views[1].maxSwapchainSampleCount = 1; + + uint32_t i = 0; + if (xdev->blend_mode & XRT_BLEND_MODE_OPAQUE) { + sys->blend_modes[i++] = XR_ENVIRONMENT_BLEND_MODE_OPAQUE; + } + if (xdev->blend_mode & XRT_BLEND_MODE_ADDITIVE) { + sys->blend_modes[i++] = XR_ENVIRONMENT_BLEND_MODE_ADDITIVE; + } + if (xdev->blend_mode & XRT_BLEND_MODE_ALPHA_BLEND) { + sys->blend_modes[i++] = XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND; + } + sys->num_blend_modes = i; + + assert(i < ARRAY_SIZE(sys->blend_modes)); + + // clang-format on + + return XR_SUCCESS; +} + +XrResult +oxr_system_get_properties(struct oxr_logger *log, + struct oxr_system *sys, + XrSystemProperties *properties) +{ + properties->vendorId = 42; + properties->systemId = sys->systemId; + properties->graphicsProperties.maxViewCount = 2; + /*! + * @todo conforming implementations must support at + * leastXR_MIN_COMPOSITION_LAYERS_SUPPORTED layers. + */ + properties->graphicsProperties.maxLayerCount = 1; + properties->graphicsProperties.maxSwapchainImageWidth = 1024 * 16; + properties->graphicsProperties.maxSwapchainImageHeight = 1024 * 16; + properties->trackingProperties.orientationTracking = XR_TRUE; + properties->trackingProperties.positionTracking = XR_FALSE; + + return XR_SUCCESS; +} + +XrResult +oxr_system_enumerate_view_confs(struct oxr_logger *log, + struct oxr_system *sys, + uint32_t viewConfigurationTypeCapacityInput, + uint32_t *viewConfigurationTypeCountOutput, + XrViewConfigurationType *viewConfigurationTypes) +{ + OXR_TWO_CALL_HELPER(log, viewConfigurationTypeCapacityInput, + viewConfigurationTypeCountOutput, + viewConfigurationTypes, 1, &sys->view_config_type); +} + +XrResult +oxr_system_enumerate_blend_modes(struct oxr_logger *log, + struct oxr_system *sys, + uint32_t environmentBlendModeCapacityInput, + uint32_t *environmentBlendModeCountOutput, + XrEnvironmentBlendMode *environmentBlendModes) +{ + OXR_TWO_CALL_HELPER(log, environmentBlendModeCapacityInput, + environmentBlendModeCountOutput, + environmentBlendModes, sys->num_blend_modes, + sys->blend_modes); +} + +XrResult +oxr_system_get_view_conf_properties( + struct oxr_logger *log, + struct oxr_system *sys, + XrViewConfigurationType viewConfigurationType, + XrViewConfigurationProperties *configurationProperties) +{ + if (viewConfigurationType != sys->view_config_type) { + return oxr_error(log, + XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED, + "invalid view configuration type"); + } + + // clang-format off + configurationProperties->viewConfigurationType = sys->view_config_type; + configurationProperties->fovMutable = false; + // clang-format on + + return XR_SUCCESS; +} + +XrResult +oxr_system_enumerate_view_conf_views( + struct oxr_logger *log, + struct oxr_system *sys, + XrViewConfigurationType viewConfigurationType, + uint32_t viewCapacityInput, + uint32_t *viewCountOutput, + XrViewConfigurationView *views) +{ + if (viewConfigurationType != sys->view_config_type) { + return oxr_error(log, + XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED, + "invalid view configuration type"); + } + + OXR_TWO_CALL_HELPER(log, viewCapacityInput, viewCountOutput, views, 2, + sys->views); +} diff --git a/src/xrt/state_trackers/oxr/oxr_two_call.h b/src/xrt/state_trackers/oxr/oxr_two_call.h new file mode 100644 index 000000000..0ab83c516 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_two_call.h @@ -0,0 +1,40 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Two call helper functions. + * @author Ryan Pavlik <ryan.pavlik@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + +#define OXR_TWO_CALL_HELPER(log, cnt_input, cnt_output, output, count, data) \ + do { \ + if (cnt_output != NULL) { \ + *cnt_output = count; \ + } \ + if (cnt_input == 0) { \ + return XR_SUCCESS; \ + } \ + if (cnt_input < count) { \ + return oxr_error(log, XR_ERROR_SIZE_INSUFFICIENT, \ + #cnt_input); \ + } \ + for (uint32_t i = 0; i < count; i++) { \ + (output)[i] = (data)[i]; \ + } \ + return XR_SUCCESS; \ + } while (false) + + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/state_trackers/oxr/oxr_verify.cpp b/src/xrt/state_trackers/oxr/oxr_verify.cpp new file mode 100644 index 000000000..4814b7aa8 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_verify.cpp @@ -0,0 +1,145 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief File for verifing app input into api functions. + * @author Ryan Pavlik <ryan.pavlik@collabora.com> + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + * @ingroup oxr_api + */ + +#include <stdio.h> + +#include "xrt/xrt_compiler.h" +#include "util/u_debug.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" +#include "oxr_api_verify.h" + + +/* + * + * Path verification. + * + */ + +bool +contains_zero(const char* path, uint32_t size) +{ + for (uint32_t i = 0; i < size; i++) { + if (path[i] == '\0') { + return true; + } + } + + return false; +} + +XrResult +oxr_verify_fixed_size_single_level_path(struct oxr_logger* log, + const char* path, + uint32_t size, + const char* name) +{ + if (size == 0) { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "(%s) internal runtime error", name); + } + + if (path[0] == '\0') { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "(%s) can not be empty", name); + } + + if (!contains_zero(path, size)) { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "(%s) must include zero termination '\\0'.", + name); + } + + //! @todo verify more! + + return XR_SUCCESS; +} + + +/* + * + * Other verification. + * + */ + +XrResult +oxr_verify_XrSessionCreateInfo(struct oxr_logger* log, + const XrSessionCreateInfo* createInfo) +{ + if (createInfo->type != XR_TYPE_SESSION_CREATE_INFO) { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "createInfo->type"); + } + + if (createInfo->next == NULL) { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "createInfo->next"); + } + + XrStructureType* next_type = (XrStructureType*)createInfo->next; +#ifdef XR_USE_PLATFORM_XLIB + if (*next_type == XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR) { + return oxr_verify_XrGraphicsBindingOpenGLXlibKHR( + log, (XrGraphicsBindingOpenGLXlibKHR*)createInfo->next); + } else +#endif +#ifdef XR_USE_GRAPHICS_API_VULKAN + if (*next_type == XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR) { + return oxr_verify_XrGraphicsBindingVulkanKHR( + log, (XrGraphicsBindingVulkanKHR*)createInfo->next); + } else +#endif + { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "createInfo->next->type"); + } + + return XR_SUCCESS; +} + +#ifdef XR_USE_PLATFORM_XLIB +XrResult +oxr_verify_XrGraphicsBindingOpenGLXlibKHR( + struct oxr_logger* log, const XrGraphicsBindingOpenGLXlibKHR* next) +{ + if (next->type != XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR) { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "createInfo->next->type"); + } + + if (next->next != NULL) { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "createInfo->next->next"); + } + + return XR_SUCCESS; +} +#endif + +#ifdef XR_USE_GRAPHICS_API_VULKAN +XrResult +oxr_verify_XrGraphicsBindingVulkanKHR(struct oxr_logger* log, + const XrGraphicsBindingVulkanKHR* next) +{ + if (next->type != XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR) { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "createInfo->next->type"); + } + + if (next->next != NULL) { + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, + "createInfo->next->next"); + } + + return XR_SUCCESS; +} +#endif diff --git a/src/xrt/state_trackers/oxr/oxr_vulkan.c b/src/xrt/state_trackers/oxr/oxr_vulkan.c new file mode 100644 index 000000000..1f5f36228 --- /dev/null +++ b/src/xrt/state_trackers/oxr/oxr_vulkan.c @@ -0,0 +1,129 @@ +// Copyright 2018-2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Holds Vulkan related functions. + * @author Jakob Bornecrantz <jakob@collabora.com> + * @ingroup oxr_main + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "xrt/xrt_gfx_vk.h" + +#include "oxr_objects.h" +#include "oxr_logger.h" +#include "oxr_two_call.h" + + +#define GET_PROC(name) PFN_##name name = (PFN_##name)getProc(vkInstance, #name) + +XrResult +oxr_vk_get_instance_exts(struct oxr_logger *log, + struct oxr_system *sys, + uint32_t namesCapacityInput, + uint32_t *namesCountOutput, + char *namesString) +{ + size_t length = strlen(xrt_gfx_vk_instance_extensions) + 1; + + OXR_TWO_CALL_HELPER(log, namesCapacityInput, namesCountOutput, + namesString, length, + xrt_gfx_vk_instance_extensions); +} + +XrResult +oxr_vk_get_device_exts(struct oxr_logger *log, + struct oxr_system *sys, + uint32_t namesCapacityInput, + uint32_t *namesCountOutput, + char *namesString) +{ + size_t length = strlen(xrt_gfx_vk_device_extensions) + 1; + + OXR_TWO_CALL_HELPER(log, namesCapacityInput, namesCountOutput, + namesString, length, xrt_gfx_vk_device_extensions); +} + +XrResult +oxr_vk_get_requirements(struct oxr_logger *log, + struct oxr_system *sys, + XrGraphicsRequirementsVulkanKHR *graphicsRequirements) +{ + struct xrt_api_requirements ver; + + xrt_gfx_vk_get_versions(&ver); + graphicsRequirements->minApiVersionSupported = + XR_MAKE_VERSION(ver.min_major, ver.min_minor, ver.min_patch); + graphicsRequirements->maxApiVersionSupported = + XR_MAKE_VERSION(ver.max_major, ver.max_minor, ver.max_patch); + + return XR_SUCCESS; +} + +XrResult +oxr_vk_get_physical_device(struct oxr_logger *log, + struct oxr_instance *inst, + struct oxr_system *sys, + VkInstance vkInstance, + PFN_vkGetInstanceProcAddr getProc, + VkPhysicalDevice *vkPhysicalDevice) +{ + GET_PROC(vkEnumeratePhysicalDevices); + GET_PROC(vkGetPhysicalDeviceProperties); + VkResult vk_ret; + uint32_t count; + + vk_ret = vkEnumeratePhysicalDevices(vkInstance, &count, NULL); + if (vk_ret != VK_SUCCESS) { + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, + " vkEnumeratePhysicalDevices returned %u", + vk_ret); + } + if (count == 0) { + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, + " vkEnumeratePhysicalDevices returned zero " + "VkPhysicalDevices"); + } + + VkPhysicalDevice *phys = calloc(count, sizeof(VkPhysicalDevice)); + vk_ret = vkEnumeratePhysicalDevices(vkInstance, &count, phys); + if (vk_ret != VK_SUCCESS) { + free(phys); + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, + " vkEnumeratePhysicalDevices returned %u", + vk_ret); + } + if (count == 0) { + free(phys); + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, + " vkEnumeratePhysicalDevices returned zero " + "VkPhysicalDevices"); + } + + if (count > 1) { + OXR_WARN_ONCE(log, + "super intelligent device selection algorithm " + "can't handle more then one VkPhysicalDevice, " + "picking the first discrete gpu in the list."); + } + + // 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 < count; i++) { + VkPhysicalDeviceProperties pdp; + vkGetPhysicalDeviceProperties(phys[i], &pdp); + if (pdp.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { + gpu_index = i; + } + } + + *vkPhysicalDevice = phys[gpu_index]; + + free(phys); + + return XR_SUCCESS; +} diff --git a/src/xrt/targets/CMakeLists.txt b/src/xrt/targets/CMakeLists.txt new file mode 100644 index 000000000..2db892278 --- /dev/null +++ b/src/xrt/targets/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2019, Collabora, Ltd. +# SPDX-License-Identifier: BSL-1.0 + +###### +# This is where we collect all of the pieces from the different parts of +# the source tree and build a complete driver or integration part. + +add_subdirectory(openxr) diff --git a/src/xrt/targets/openxr/CMakeLists.txt b/src/xrt/targets/openxr/CMakeLists.txt new file mode 100644 index 000000000..d6b046034 --- /dev/null +++ b/src/xrt/targets/openxr/CMakeLists.txt @@ -0,0 +1,98 @@ +# Copyright 2019, Collabora, Ltd. +# SPDX-License-Identifier: BSL-1.0 + +###### +# Create a loadable OpenXR driver. + +# set(RUNTIME_BARE_PREFIX xrt) +# set(RUNTIME_PREFIX ${RUNTIME_BARE_PREFIX}_) + +set(RUNTIME_BARE_SUFFIX monado) +set(RUNTIME_SUFFIX _${RUNTIME_BARE_SUFFIX}) + +set(RUNTIME_TARGET ${RUNTIME_PREFIX}openxr${RUNTIME_SUFFIX} CACHE INTERNAL "" FORCE) + +set(XR_API_MAJOR "0") + + +# $LIBPATH is a generator expression that is evaluated after configure_file, so we have to use file(GENERATE) instead + +### +# Generate runtime manifest with absolute path to runtime intended for development without installing +file( + GENERATE + OUTPUT "${CMAKE_BINARY_DIR}/${RUNTIME_TARGET}-dev.json" + CONTENT +"{ + \"file_format_version\": \"1.0.0\", + \"runtime\": { + \"library_path\": \"$<TARGET_SONAME_FILE:${RUNTIME_TARGET}>\" + } +} +") + +### +# Generate runtime manifest with relative path to runtime intendend for installed release build +# (assumes the runtime library is in the loader's search path) +file( + GENERATE + OUTPUT "${CMAKE_BINARY_DIR}/${RUNTIME_TARGET}.json" + CONTENT +"{ + \"file_format_version\": \"1.0.0\", + \"runtime\": { + \"library_path\": \"$<TARGET_SONAME_FILE_NAME:${RUNTIME_TARGET}>\" + } +} +") + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../../include + ${CMAKE_CURRENT_SOURCE_DIR}/../../drivers + ) + +set(SOURCE_FILES + target.c + ) + + +# Siiiiiiiigh, there is no target_link_directories +# or a way to add directories to a target. +link_directories(${OPENHMD_LIBRARY_DIRS}) + +# depends on above generated files +add_library(${RUNTIME_TARGET} SHARED + ${MANIFEST_DEV_PATH} + ${MANIFEST_PATH} + ${SOURCE_FILES} + $<TARGET_OBJECTS:aux_util> + $<TARGET_OBJECTS:aux_math> + $<TARGET_OBJECTS:comp> + $<TARGET_OBJECTS:drv_ohmd> + $<TARGET_OBJECTS:st_oxr> + ) + +target_link_libraries(${RUNTIME_TARGET} + ${OPENHMD_LIBRARIES} + ${Vulkan_LIBRARIES} + ${XCB_LIBRARIES} + ) + +target_compile_definitions(${RUNTIME_TARGET} PRIVATE XRT_HAVE_OHMD) + +if(TARGET drv_hdk) + target_sources(${RUNTIME_TARGET} PRIVATE $<TARGET_OBJECTS:drv_hdk>) + target_link_libraries(${RUNTIME_TARGET} ${HIDAPI_LIBRARIES}) + target_compile_definitions(${RUNTIME_TARGET} PRIVATE XRT_HAVE_HDK) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + include(GNUInstallDirs) + install(TARGETS ${RUNTIME_TARGET} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(FILES "${CMAKE_BINARY_DIR}/${RUNTIME_TARGET}.json" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/openxr/${XR_API_MAJOR}/") +elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + # TODO: install target on windows +endif() diff --git a/src/xrt/targets/openxr/libopenxr.version b/src/xrt/targets/openxr/libopenxr.version new file mode 100644 index 000000000..1581ef8d3 --- /dev/null +++ b/src/xrt/targets/openxr/libopenxr.version @@ -0,0 +1,4 @@ +OPENXR { + global: xrNegotiateLoaderRuntimeInterface; # Only one exported symbol. + local: *; # Hide everything else. +}; diff --git a/src/xrt/targets/openxr/target.c b/src/xrt/targets/openxr/target.c new file mode 100644 index 000000000..9bdd1613c --- /dev/null +++ b/src/xrt/targets/openxr/target.c @@ -0,0 +1,102 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief The thing that binds all of the OpenXR driver together. + * @author Jakob Bornecrantz <jakob@collabora.com> + */ + +#include "xrt/xrt_prober.h" + +#include <stdlib.h> + +#ifdef XRT_HAVE_OHMD +#include "ohmd/oh_interface.h" +#endif + +#ifdef XRT_HAVE_HDK +#include "hdk/hdk_interface.h" +#endif + + +typedef struct xrt_prober *(*prober_creator)(); + + +static const prober_creator DRIVERS[] = { +#ifdef XRT_HAVE_HDK + // Returns NULL if none found, so OK to go first. + hdk_create_prober, +#endif + +#ifdef XRT_HAVE_OHMD + oh_create_prober, +#endif + +}; + +#define NUM_PROBERS (ARRAY_SIZE(DRIVERS)) + +/*! + * An xrt_prober that contains other xrt_probers. + */ +struct xrt_meta_prober +{ + struct xrt_prober base; + struct xrt_prober *probers[NUM_PROBERS]; +}; + + +static inline struct xrt_meta_prober * +xrt_meta_prober(struct xrt_prober *p) +{ + return (struct xrt_meta_prober *)p; +} + +static void +xrt_meta_prober_destroy(struct xrt_prober *p) +{ + struct xrt_meta_prober *mp = xrt_meta_prober(p); + for (size_t i = 0; i < NUM_PROBERS; i++) { + if (mp->probers[i]) { + mp->probers[i]->destroy(mp->probers[i]); + mp->probers[i] = NULL; + } + } + + free(p); +} + +static struct xrt_device * +xrt_meta_prober_autoprobe(struct xrt_prober *p) +{ + struct xrt_meta_prober *mp = xrt_meta_prober(p); + for (size_t i = 0; i < NUM_PROBERS; i++) { + if (mp->probers[i]) { + struct xrt_device *ret = + mp->probers[i]->lelo_dallas_autoprobe( + mp->probers[i]); + if (ret) { + return ret; + } + } + } + + /* Couldn't find any prober that works. */ + return NULL; +} + +struct xrt_prober * +xrt_create_prober() +{ + struct xrt_meta_prober *p = + (struct xrt_meta_prober *)calloc(1, sizeof(struct xrt_meta_prober)); + + for (size_t i = 0; i < NUM_PROBERS; i++) { + p->probers[i] = DRIVERS[i](); + } + + p->base.lelo_dallas_autoprobe = xrt_meta_prober_autoprobe; + p->base.destroy = xrt_meta_prober_destroy; + + return &p->base; +} -- GitLab