diff --git a/.appveyor.yml b/.appveyor.yml index 46256306c..f9bae8e25 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,8 +1,8 @@ -# Copyright (c) 2017-2021 The Khronos Group Inc. +# Copyright (c) 2017-2023 The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 -version: 1.0.26.{build} +version: 1.0.27.{build} image: Visual Studio 2017 diff --git a/.azure-pipelines/nuget/NugetTemplate/OpenXR.Loader.nuspec b/.azure-pipelines/nuget/NugetTemplate/OpenXR.Loader.nuspec index ab9fa9f54..da1bd0cd9 100644 --- a/.azure-pipelines/nuget/NugetTemplate/OpenXR.Loader.nuspec +++ b/.azure-pipelines/nuget/NugetTemplate/OpenXR.Loader.nuspec @@ -1,7 +1,7 @@ diff --git a/.azure-pipelines/openxr-sdk-source.yml b/.azure-pipelines/openxr-sdk-source.yml index e5a222420..c3c44541f 100644 --- a/.azure-pipelines/openxr-sdk-source.yml +++ b/.azure-pipelines/openxr-sdk-source.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022, The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 # Main azure-pipelines configuration for the OpenXR-SDK-Sources repo. @@ -21,7 +21,7 @@ stages: - job: loader_docs pool: vmImage: "ubuntu-latest" - container: khronosgroup/docker-images:openxr-base.202110 + container: khronosgroup/docker-images:openxr.20230209.1 steps: - script: make loader workingDirectory: specification @@ -34,7 +34,7 @@ stages: - job: archive pool: vmImage: "ubuntu-latest" - container: khronosgroup/docker-images:openxr-base.202110 + container: khronosgroup/docker-images:openxr.20230209.1 steps: - script: make loader workingDirectory: specification @@ -62,7 +62,7 @@ stages: presentationBackend: wayland pool: vmImage: "ubuntu-latest" - container: khronosgroup/docker-images:openxr-sdk.202110 + container: khronosgroup/docker-images:openxr-sdk.20230209 steps: - task: DownloadPipelineArtifact@2 displayName: Download archived OpenXR-SDK diff --git a/.azure-pipelines/openxr-sdk.yml b/.azure-pipelines/openxr-sdk.yml index 32315413a..df9ba2194 100644 --- a/.azure-pipelines/openxr-sdk.yml +++ b/.azure-pipelines/openxr-sdk.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022, The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 # Main azure-pipelines configuration for the OpenXR-SDK repo. diff --git a/.azure-pipelines/shared/build_jobs.yml b/.azure-pipelines/shared/build_jobs.yml index cfcfbc443..ea5e977f3 100644 --- a/.azure-pipelines/shared/build_jobs.yml +++ b/.azure-pipelines/shared/build_jobs.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022, The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 parameters: @@ -26,7 +26,7 @@ jobs: presentationBackend: wayland pool: vmImage: "ubuntu-latest" - container: khronosgroup/docker-images:openxr-sdk.202110 + container: khronosgroup/docker-images:openxr-sdk.20230209 steps: # First build as debug - template: build_linux.yml diff --git a/.azure-pipelines/shared/build_linux.yml b/.azure-pipelines/shared/build_linux.yml index 92bec215c..498547664 100644 --- a/.azure-pipelines/shared/build_linux.yml +++ b/.azure-pipelines/shared/build_linux.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022, The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 parameters: diff --git a/.azure-pipelines/shared/build_mingw.yml b/.azure-pipelines/shared/build_mingw.yml index 4f3a8e91f..13c41b172 100644 --- a/.azure-pipelines/shared/build_mingw.yml +++ b/.azure-pipelines/shared/build_mingw.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022, The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 parameters: diff --git a/.azure-pipelines/shared/build_msvc.yml b/.azure-pipelines/shared/build_msvc.yml index b236fdc92..667c8b30d 100644 --- a/.azure-pipelines/shared/build_msvc.yml +++ b/.azure-pipelines/shared/build_msvc.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022, The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 parameters: diff --git a/.azure-pipelines/shared/check_clang_format.yml b/.azure-pipelines/shared/check_clang_format.yml index ce073a316..c0574751d 100644 --- a/.azure-pipelines/shared/check_clang_format.yml +++ b/.azure-pipelines/shared/check_clang_format.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022, The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 jobs: @@ -6,7 +6,7 @@ jobs: displayName: "clang-format" pool: vmImage: "ubuntu-latest" - container: khronosgroup/docker-images:openxr-sdk.202110 + container: khronosgroup/docker-images:openxr-sdk.20230209 steps: - script: ./runClangFormat.sh displayName: Run clang-format diff --git a/.azure-pipelines/shared/check_file_format.yml b/.azure-pipelines/shared/check_file_format.yml index 909cc6fb5..f634aac27 100644 --- a/.azure-pipelines/shared/check_file_format.yml +++ b/.azure-pipelines/shared/check_file_format.yml @@ -1,11 +1,11 @@ -# Copyright (c) 2020-2022, The Khronos Group Inc. +# Copyright (c) 2020-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 jobs: - job: check_file_format displayName: 'Check file formatting' pool: vmImage: 'ubuntu-latest' - container: khronosgroup/docker-images:openxr-sdk.202110 + container: khronosgroup/docker-images:openxr-sdk.20230209 steps: - script: ./file_format.sh displayName: File formatting checks (file_format.sh) diff --git a/.azure-pipelines/shared/codespell.yml b/.azure-pipelines/shared/codespell.yml index 4d9300cbc..df0a3c996 100644 --- a/.azure-pipelines/shared/codespell.yml +++ b/.azure-pipelines/shared/codespell.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022, The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 jobs: @@ -6,7 +6,7 @@ jobs: displayName: "codespell" pool: vmImage: "ubuntu-latest" - container: khronosgroup/docker-images:openxr-sdk.202110 + container: khronosgroup/docker-images:openxr-sdk.20230209 steps: - script: ./checkCodespell displayName: Run Codespell script diff --git a/.editorconfig b/.editorconfig index aa669ccdf..0220ac21a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index e872fdbb5..5519b09d8 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,4 +1,4 @@ -# Copyright 2021-2022, The Khronos Group Inc. Inc. +# Copyright 2021-2023, The Khronos Group Inc. Inc. # # SPDX-License-Identifier: CC-BY-4.0 @@ -40,3 +40,24 @@ bd1f05a6f5da8662c6969996177063a5a98bf0ea # OpenXR-CTS 1224c0ba88b6f000a5f00f56c0dbb8265a6c6350 + + +## 1.0.27 - Bulk-apply PrettyRegistryXML + +# Khronos GitLab (commit also includes adding an extension) +ff2037bc6aa951610f4e21d133056d3f547d2374 + +# Khronos GitLab (finishing formatting) +4bb0766ec6d7101b17b0bc02ba04c86c4159bd16 + +# OpenXR-Docs +09b6b4bae7d691e1406ee6951e5ab8ed4e620ff3 + +# OpenXR-SDK-Source +2c1b77dcdc6ace701e4b08477e5fae5312a866b4 + +# OpenXR-CTS +e774b36cfc7bfc721e97de6c8435fcb14866e6fa + +# OpenXR-SDK +db11d03216666f2b574da46a39c4b565dbe90124 diff --git a/.gitattributes b/.gitattributes index aa0a3221e..892b854b9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 diff --git a/.github/scripts/install_vulkan.ps1 b/.github/scripts/install_vulkan.ps1 index b960de2c4..1f1c3d710 100644 --- a/.github/scripts/install_vulkan.ps1 +++ b/.github/scripts/install_vulkan.ps1 @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022 The Khronos Group Inc. +# Copyright (c) 2019-2023 The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 $ErrorActionPreference = 'Stop' diff --git a/.github/scripts/organize_windows_artifacts.py b/.github/scripts/organize_windows_artifacts.py index 3aa5df44f..f40536eff 100644 --- a/.github/scripts/organize_windows_artifacts.py +++ b/.github/scripts/organize_windows_artifacts.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2019-2022 The Khronos Group Inc. +# Copyright (c) 2019-2023 The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 from pathlib import Path diff --git a/.github/workflows/check_clang_format_and_codespell.yml b/.github/workflows/check_clang_format_and_codespell.yml index 6caa6a278..b9f22d644 100644 --- a/.github/workflows/check_clang_format_and_codespell.yml +++ b/.github/workflows/check_clang_format_and_codespell.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022, The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 name: Check code formatting and spelling @@ -10,7 +10,7 @@ jobs: clang-format: runs-on: ubuntu-latest container: - image: khronosgroup/docker-images:openxr-sdk.202110 + image: khronosgroup/docker-images:openxr-sdk.20230209 steps: - uses: actions/checkout@v3 - run: ./runClangFormat.sh diff --git a/.gitignore b/.gitignore index 23bcc2f17..03c1a0d79 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,13 @@ -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 /build/ build*/ CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +*/CMakeFiles *.orig .* *~ @@ -12,6 +15,9 @@ CMakeLists.txt.user *.tar.gz *.log pregen/ +generated-includes +cmake_install.cmake +cmake_uninstall.cmake # Marker file for a snapshot build SNAPSHOT @@ -35,6 +41,8 @@ out/build/ # VS misc *.sln *.pyproj +*.vcxproj +*.vcxproj.filters CMakeSettings.json CppProperties.json diff --git a/.proclamation.json.license b/.proclamation.json.license index 4ade1f4c6..3b833d2da 100644 --- a/.proclamation.json.license +++ b/.proclamation.json.license @@ -1,4 +1,4 @@ Copyright (c) 2020 Collabora, Ltd. and the Proclamation contributors -Copyright (c) 2020-2022, The Khronos Group Inc. +Copyright (c) 2020-2023, The Khronos Group Inc. SPDX-License-Identifier: CC0-1.0 diff --git a/.reuse/dep5 b/.reuse/dep5 index 6b9975ce8..c4426f94d 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -4,9 +4,13 @@ Upstream-Contact: Ryan Pavlik Source: https://khronos.org/registry/OpenXR/ Files: changes/* -Copyright: 2019-2022, The Khronos Group Inc. +Copyright: 2019-2023, The Khronos Group Inc. License: CC-BY-4.0 +Files: specification/config/copyright-spec.adoc +Copyright: 2014-2023 The Khronos Group Inc +License: LicenseRef-KhronosSpecCopyright-WithNormativeWording-v10 + Files: src/tests/hello_xr/android_resources/vulkan/mipmap-xxhdpi/ic_helloxr_launcher.png src/tests/hello_xr/android_resources/vulkan/mipmap-mdpi/ic_helloxr_launcher.png src/tests/hello_xr/android_resources/vulkan/mipmap-xhdpi/ic_helloxr_launcher.png @@ -17,13 +21,18 @@ Files: src/tests/hello_xr/android_resources/vulkan/mipmap-xxhdpi/ic_helloxr_laun src/tests/hello_xr/android_resources/opengles/mipmap-xhdpi/ic_helloxr_launcher.png src/tests/hello_xr/android_resources/opengles/mipmap-hdpi/ic_helloxr_launcher.png src/tests/hello_xr/android_resources/opengles/mipmap-xxxhdpi/ic_helloxr_launcher.png -Copyright: Copyright (c) 2020-2022, The Khronos Group Inc. +Copyright: Copyright (c) 2020-2023, The Khronos Group Inc. Copyright (c) 2020, Google License: Apache-2.0 Comment: Based on a Material Icons asset ("emoji-people") with added text in "Miriam Libre" Bold, converted to path, and manually simplified. Rasterized with Android Studio. +Files: src/external/catch2/* +Copyright: Copyright (c) 2022 Two Blue Cubes Ltd. +License: BSL-1.0 +Comment: Unmodified, vendored copy of Catch2 3.1.1 + Files: src/external/jsoncpp/* Copyright: 2007-2010 Baptiste Lepilleur and The JsonCpp Authors License: MIT OR LicenseRef-jsoncpp-public-domain @@ -33,7 +42,7 @@ Files: src/external/jnipp/* Copyright: 2016-2020, Mitchell Dowd 2020, Collabora, Ltd. License: MIT -Comment: Ryan Pavlik at Collabora's fork +Comment: Unmodified, vendored copy of commit e6c415837c5a487809fdbb2f71f1080d454eb99a Files: external/python/jinja2/* external/python/Jinja2-2.10.3.dist-info/* @@ -74,6 +83,6 @@ Comment: Generated .png versions of an icon, created in Android Studio based on a Material Icons asset. Files: specification/scripts/vuidCounts.py -Copyright: 2022 The Khronos Group Inc. +Copyright: 2022-2023, The Khronos Group Inc. License: Apache-2.0 Comment: File automatically rewritten by VUID assignment. diff --git a/BUILDING.md b/BUILDING.md index 140d6e108..c3a61e6e4 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -1,7 +1,7 @@ # How to Build and Run @@ -10,7 +10,7 @@ SPDX-License-Identifier: CC-BY-4.0 ### Python v3.6+ may be required -**If you are building from most repostories:** (specifically, the +**If you are building from most repositories:** (specifically, the OpenXR-SDK-Source repository, the OpenXR-CTS repository, or the internal Khronos GitLab OpenXR repository) Certain source files are generated at build time from the `xr.xml` file, utilizing Python scripts. The scripts make use of the Python diff --git a/CHANGELOG.SDK.md b/CHANGELOG.SDK.md index 565c87adc..6f31c2ffd 100644 --- a/CHANGELOG.SDK.md +++ b/CHANGELOG.SDK.md @@ -1,7 +1,7 @@ # Changelog for OpenXR-SDK-Source and OpenXR-SDK Repo @@ -19,6 +19,185 @@ along with any public pull requests that have been accepted. In this repository in particular, since it is primarily software, pull requests may be integrated as they are accepted even between periodic updates. +## OpenXR SDK 1.0.27 (2023-03-21) + +This release contains a large list of improvements, including interaction +profile definitions in machine-readable format in the XML, consistent tool-based +formatting of the XML, a new `list_json` tool to ease updates to +[OpenXR-Inventory][], and a wide variety of new vendor and multi-vendor +extensions, in addition to a collection of smaller improvements. + +[OpenXR-Inventory]: https://github.com/KhronosGroup/OpenXR-Inventory + +- Registry + - Add interaction profile definitions to `xr.xml` + ([internal MR 2485](https://gitlab.khronos.org/openxr/openxr/merge_requests/2485)) + - Chore: Format the full XML API registry with + [PrettyRegistryXML](https://github.com/rpavlik/PrettyRegistryXml), making some + small changes by hand to clean up. + ([internal MR 2540](https://gitlab.khronos.org/openxr/openxr/merge_requests/2540), + [internal MR 2329](https://gitlab.khronos.org/openxr/openxr/merge_requests/2329), + [OpenXR-SDK-Source PR 373](https://github.com/KhronosGroup/OpenXR-SDK-Source/pull/373), + [OpenXR-Docs PR 14](https://github.com/KhronosGroup/OpenXR-Docs/pull/14), + [OpenXR-CTS PR 50](https://github.com/KhronosGroup/OpenXR-CTS/pull/50), + [OpenXR-SDK PR 12](https://github.com/KhronosGroup/OpenXR-SDK/pull/12)) + - Document how to generate a standalone header file for an extension. + ([internal MR 2627](https://gitlab.khronos.org/openxr/openxr/merge_requests/2627)) + - Extension reservation: Register author ID and reserve vendor extensions for + Logitech. + ([internal MR 2504](https://gitlab.khronos.org/openxr/openxr/merge_requests/2504)) + - Extension reservation: Reserve an extension number for a multi-vendor + extension. + ([internal MR 2520](https://gitlab.khronos.org/openxr/openxr/merge_requests/2520)) + - Extension reservation: Reserve an extension for `XR_EXT_hand_tracking_usage` + ([internal MR 2550](https://gitlab.khronos.org/openxr/openxr/merge_requests/2550)) + - Extension reservation: Reserve extension id 430 for `XR_EXT_plane_detection` + ([internal MR 2565](https://gitlab.khronos.org/openxr/openxr/merge_requests/2565)) + - Extension reservation: Reserve vendor extensions for Monado. + ([internal MR 2613](https://gitlab.khronos.org/openxr/openxr/merge_requests/2613)) + - Extension reservation: Reserve vendor extensions for ACER. + ([OpenXR-Docs PR 142](https://github.com/KhronosGroup/OpenXR-Docs/pull/142)) + - Extension reservation: Reserve a vendor extension for OPPO. + ([OpenXR-Docs PR 145](https://github.com/KhronosGroup/OpenXR-Docs/pull/145)) + - New vendor extension: `XR_FB_composition_layer_depth_test` + ([internal MR 2208](https://gitlab.khronos.org/openxr/openxr/merge_requests/2208), + [internal issue 1657](https://gitlab.khronos.org/openxr/openxr/issues/1657)) + - New vendor extension: `XR_META_foveation_eye_tracked` + ([internal MR 2239](https://gitlab.khronos.org/openxr/openxr/merge_requests/2239), + [internal MR 2273](https://gitlab.khronos.org/openxr/openxr/merge_requests/2273), + [internal MR 2332](https://gitlab.khronos.org/openxr/openxr/merge_requests/2332)) + - New vendor extension: `XR_QCOM_tracking_optimization_settings` + ([internal MR 2261](https://gitlab.khronos.org/openxr/openxr/merge_requests/2261), + [internal issue 1703](https://gitlab.khronos.org/openxr/openxr/issues/1703)) + - New vendor extension: `XR_META_local_dimming` + ([internal MR 2267](https://gitlab.khronos.org/openxr/openxr/merge_requests/2267), + [internal MR 2595](https://gitlab.khronos.org/openxr/openxr/merge_requests/2595)) + - New vendor extension: `XR_FB_spatial_entity_sharing` + ([internal MR 2274](https://gitlab.khronos.org/openxr/openxr/merge_requests/2274)) + - New vendor extension: `XR_FB_scene_capture` + ([internal MR 2286](https://gitlab.khronos.org/openxr/openxr/merge_requests/2286)) + - New vendor extension: `XR_FB_spatial_entity_storage_batch` + ([internal MR 2312](https://gitlab.khronos.org/openxr/openxr/merge_requests/2312)) + - New vendor extension: `XR_FB_haptic_amplitude_envelope` + ([internal MR 2326](https://gitlab.khronos.org/openxr/openxr/merge_requests/2326)) + - New vendor extension: `XR_FB_touch_controller_pro` + ([internal MR 2327](https://gitlab.khronos.org/openxr/openxr/merge_requests/2327), + [internal issue 1916](https://gitlab.khronos.org/openxr/openxr/issues/1916)) + - New vendor extension: `XR_FB_haptic_pcm` + ([internal MR 2329](https://gitlab.khronos.org/openxr/openxr/merge_requests/2329)) + - New vendor extension: `FB_face_tracking` + ([internal MR 2334](https://gitlab.khronos.org/openxr/openxr/merge_requests/2334), + [internal MR 2539](https://gitlab.khronos.org/openxr/openxr/merge_requests/2539)) + - New vendor extension: `XR_FB_eye_tracking_social` + ([internal MR 2336](https://gitlab.khronos.org/openxr/openxr/merge_requests/2336), + [internal MR 2576](https://gitlab.khronos.org/openxr/openxr/merge_requests/2576)) + - New vendor extension: `XR_FB_body_tracking` + ([internal MR 2339](https://gitlab.khronos.org/openxr/openxr/merge_requests/2339), + [internal MR 2575](https://gitlab.khronos.org/openxr/openxr/merge_requests/2575)) + - New vendor extension: `XR_OCULUS_external_camera` + ([internal MR 2397](https://gitlab.khronos.org/openxr/openxr/merge_requests/2397), + [internal MR 2344](https://gitlab.khronos.org/openxr/openxr/merge_requests/2344)) + - New vendor extension: `XR_FB_spatial_entity_user` + ([internal MR 2407](https://gitlab.khronos.org/openxr/openxr/merge_requests/2407)) + - New vendor extension: `XR_FB_touch_controller_proximity` + ([internal MR 2412](https://gitlab.khronos.org/openxr/openxr/merge_requests/2412)) + - New vendor extension: `XR_ML_global_dimmer` + ([internal MR 2461](https://gitlab.khronos.org/openxr/openxr/merge_requests/2461)) + - New vendor extension: `XR_ML_frame_end_info` + ([internal MR 2462](https://gitlab.khronos.org/openxr/openxr/merge_requests/2462), + [internal MR 2536](https://gitlab.khronos.org/openxr/openxr/merge_requests/2536)) + - New vendor extension: `XR_ML_compat` + ([internal MR 2473](https://gitlab.khronos.org/openxr/openxr/merge_requests/2473)) + - New vendor extension: `XR_EXT_local_floor` + ([internal MR 2503](https://gitlab.khronos.org/openxr/openxr/merge_requests/2503), + [internal issue 746](https://gitlab.khronos.org/openxr/openxr/issues/746), + [internal issue 1606](https://gitlab.khronos.org/openxr/openxr/issues/1606), + [OpenXR-Docs issue 103](https://github.com/KhronosGroup/OpenXR-Docs/issues/103)) + - New vendor extension: `XR_BD_controller_interaction` + ([internal MR 2527](https://gitlab.khronos.org/openxr/openxr/merge_requests/2527)) + - New vendor extension: `XR_MNDX_force_feedback_curl` + ([OpenXR-Docs PR 136](https://github.com/KhronosGroup/OpenXR-Docs/pull/136)) + - Register author ID for Matthieu Bucchianeri. + ([OpenXR-Docs PR 143](https://github.com/KhronosGroup/OpenXR-Docs/pull/143)) + - Rename tag name to a short one for ByteDance. + ([internal MR 2502](https://gitlab.khronos.org/openxr/openxr/merge_requests/2502)) + - Schema: Add initial tests for Schematron rules. + ([internal MR 2512](https://gitlab.khronos.org/openxr/openxr/merge_requests/2512)) + - Schema: Add author ID schematron checks and change duplicate name/number report + to an assert + ([internal MR 2514](https://gitlab.khronos.org/openxr/openxr/merge_requests/2514)) + - Schema: Fix Relax-NG checks of naming convention, and add naming convention + checks to Schematron. + ([internal MR 2538](https://gitlab.khronos.org/openxr/openxr/merge_requests/2538)) + - Schematron: Update extension naming rule to allow for vendor tags to be + followed by an X for experimental and a version number + ([internal MR 2518](https://gitlab.khronos.org/openxr/openxr/merge_requests/2518)) + - scripts: Let `deprecated` override `provisional` when choosing extension table + of contents section. + ([internal MR 2547](https://gitlab.khronos.org/openxr/openxr/merge_requests/2547)) + - scripts: Fix leftover exclusion of `extensions/meta` from `checkMarkup` now + that it no longer generated files. + ([internal MR 2560](https://gitlab.khronos.org/openxr/openxr/merge_requests/2560)) +- SDK + - Experimental Extension Naming: Allow vendor tags to be followed by an "X" for + experimental and an optional version number (e.g. XR_EXTX2_hand_tracking). + Update source generator vendor checks accordingly + ([internal MR 2518](https://gitlab.khronos.org/openxr/openxr/merge_requests/2518)) + - Fix typo in API Dump generation script + ([internal MR 2608](https://gitlab.khronos.org/openxr/openxr/merge_requests/2608)) + - Loader: Fix dynamic build on MinGW. + ([OpenXR-SDK-Source PR 362](https://github.com/KhronosGroup/OpenXR-SDK-Source/pull/362), + [OpenXR-SDK-Source issue 367](https://github.com/KhronosGroup/OpenXR-SDK-Source/issues/367)) + - Loader and layers: In debug builds, log when non-empty environment variables + are being ignored due to executing with elevated privilege. + ([OpenXR-SDK-Source PR 336](https://github.com/KhronosGroup/OpenXR-SDK-Source/pull/336)) + - Loader doc: Minor cleanups to API layer section. + ([internal MR 2581](https://gitlab.khronos.org/openxr/openxr/merge_requests/2581)) + - Loader doc: Fix incorrect markup/dead links. + ([internal MR 2598](https://gitlab.khronos.org/openxr/openxr/merge_requests/2598)) + - Remove third-party dependencies in `external/include/utils`. + ([internal MR 2528](https://gitlab.khronos.org/openxr/openxr/merge_requests/2528)) + - Update all XrStructureType initialization to use standard OpenXR style. + ([internal MR 2557](https://gitlab.khronos.org/openxr/openxr/merge_requests/2557)) + - Update URLs with branch names in manpages. + ([internal MR 2648](https://gitlab.khronos.org/openxr/openxr/merge_requests/2648)) + - Validation layer: Fix function signature for xrNegotiateLoaderApiLayerInterface + in core validation api layer + ([internal MR 2607](https://gitlab.khronos.org/openxr/openxr/merge_requests/2607), + [OpenXR-SDK-Source issue 378](https://github.com/KhronosGroup/OpenXR-SDK-Source/issues/378), + [internal issue 1929](https://gitlab.khronos.org/openxr/openxr/issues/1929)) + - clang-format: Add clang-format-15 as acceptable clang formats + ([OpenXR-SDK-Source PR 359](https://github.com/KhronosGroup/OpenXR-SDK-Source/pull/359)) + - doc: Add VS 2022 version code to BUILDING.md + ([OpenXR-SDK-Source PR 381](https://github.com/KhronosGroup/OpenXR-SDK-Source/pull/381)) + - headers: Remove spurious space in preprocessor conditional, that was causing + `defined` to be treated as an operator. + ([internal MR 2491](https://gitlab.khronos.org/openxr/openxr/merge_requests/2491)) + - hello_xr: Correct domain in Android package identifier. + ([internal MR 2513](https://gitlab.khronos.org/openxr/openxr/merge_requests/2513)) + - hello_xr: Update Vulkan plugin to use the newer `VK_EXT_debug_utils` extension, + and provide names for most Vulkan objects used by the app to aid in debugging. + (Utility code shared with CTS.) + ([internal MR 2524](https://gitlab.khronos.org/openxr/openxr/merge_requests/2524), + [internal MR 2579](https://gitlab.khronos.org/openxr/openxr/merge_requests/2579), + [internal MR 2637](https://gitlab.khronos.org/openxr/openxr/merge_requests/2637)) + - hello_xr: Zero initialize XrSwapchainImage* structs + ([internal MR 2551](https://gitlab.khronos.org/openxr/openxr/merge_requests/2551)) + - hello_xr: Export built-in NativeActivity + ([OpenXR-SDK-Source PR 358](https://github.com/KhronosGroup/OpenXR-SDK-Source/pull/358)) + - hello_xr: Use correct lost event count + ([OpenXR-SDK-Source PR 359](https://github.com/KhronosGroup/OpenXR-SDK-Source/pull/359)) + - loader: Prefer cstdio and cstdlib for c++ files + ([OpenXR-SDK-Source PR 357](https://github.com/KhronosGroup/OpenXR-SDK-Source/pull/357)) + - loader,api_layers: Fix finding wayland-client.h on linux + ([OpenXR-SDK-Source PR 346](https://github.com/KhronosGroup/OpenXR-SDK-Source/pull/346)) + - sdk-source: Add `list_json`, a small app to print json similar to the schema + used by [OpenXR-Inventory](https://github.com/KhronosGroup/OpenXR-Inventory). + ([internal MR 2541](https://gitlab.khronos.org/openxr/openxr/merge_requests/2541), + [internal MR 2658](https://gitlab.khronos.org/openxr/openxr/merge_requests/2658)) + - xr_linear.h: Add some extra linear algebra functions + ([internal MR 2532](https://gitlab.khronos.org/openxr/openxr/merge_requests/2532)) + ## OpenXR SDK 1.0.26 (2022-11-18) This release contains new reflection headers, fixes and improvements to the diff --git a/CMakeLists.txt b/CMakeLists.txt index ad48f3762..44255b71d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 286ff6282..3742f93d2 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,6 +1,6 @@ diff --git a/COPYING.adoc b/COPYING.adoc index 3a31362ac..473e7fdc5 100644 --- a/COPYING.adoc +++ b/COPYING.adoc @@ -1,6 +1,6 @@ = COPYING.adoc for the Khronos Group OpenXR projects -// Copyright (c) 2020-2022, The Khronos Group Inc. +// Copyright (c) 2020-2023, The Khronos Group Inc. // // SPDX-License-Identifier: CC-BY-4.0 diff --git a/LICENSES/LicenseRef-KhronosSpecCopyright-WithNormativeWording-v10.txt b/LICENSES/LicenseRef-KhronosSpecCopyright-WithNormativeWording-v10.txt new file mode 100644 index 000000000..c0154fe30 --- /dev/null +++ b/LICENSES/LicenseRef-KhronosSpecCopyright-WithNormativeWording-v10.txt @@ -0,0 +1,53 @@ +Copyright (c) 2017-2023, The Khronos Group Inc. + +This Specification is protected by copyright laws and contains material +proprietary to Khronos. +Except as described by these terms, it or any components may not be +reproduced, republished, distributed, transmitted, displayed, broadcast or +otherwise exploited in any manner without the express prior written +permission of Khronos. + +Khronos grants a conditional copyright license to use and reproduce the +unmodified Specification for any purpose, without fee or royalty, EXCEPT no +licenses to any patent, trademark or other intellectual property rights are +granted under these terms. + +Khronos makes no, and expressly disclaims any, representations or +warranties, express or implied, regarding this Specification, including, +without limitation: merchantability, fitness for a particular purpose, +non-infringement of any intellectual property, correctness, accuracy, +completeness, timeliness, and reliability. +Under no circumstances will Khronos, or any of its Promoters, Contributors +or Members, or their respective partners, officers, directors, employees, +agents or representatives be liable for any damages, whether direct, +indirect, special or consequential damages for lost revenues, lost profits, +or otherwise, arising from or in connection with these materials. + +The Khronos Intellectual Property Rights Policy defines the terms 'Scope', +'Compliant Portion', and 'Necessary Patent Claims'. + +Some parts of this Specification are purely informative and so are EXCLUDED +from the Scope of this Specification. +The <> section of +the <> defines how these parts of the Specification are +identified. + +Where this Specification uses technical terminology, defined in the +<> or otherwise, that refer to enabling technologies +that are not expressly set forth in this Specification, those enabling +technologies are EXCLUDED from the Scope of this Specification. +For clarity, enabling technologies not disclosed with particularity in this +Specification (e.g. semiconductor manufacturing technology, hardware +architecture, processor architecture or microarchitecture, memory +architecture, compiler technology, object oriented technology, basic +operating system technology, compression technology, algorithms, and so on) +are NOT to be considered expressly set forth; only those application program +interfaces and data structures disclosed with particularity are included in +the Scope of this Specification. + +For purposes of the Khronos Intellectual Property Rights Policy as it +relates to the definition of Necessary Patent Claims, all recommended or +optional features, behaviors and functionality set forth in this +Specification, if implemented, are considered to be included as Compliant +Portions. + diff --git a/LICENSES/LicenseRef-KhronosSpecCopyright.txt b/LICENSES/LicenseRef-KhronosSpecCopyright.txt deleted file mode 100644 index 1ab074538..000000000 --- a/LICENSES/LicenseRef-KhronosSpecCopyright.txt +++ /dev/null @@ -1,83 +0,0 @@ -Copyright 2014-2022, The Khronos Group Inc. - -This Specification is protected by copyright laws and contains material -proprietary to Khronos. Except as described by these terms, it or any -components may not be reproduced, republished, distributed, transmitted, -displayed, broadcast or otherwise exploited in any manner without the -express prior written permission of Khronos. -Khronos grants a conditional copyright license to use and reproduce the -unmodified Specification for any purpose, without fee or royalty, EXCEPT no -licenses to any patent, trademark or other intellectual property rights are -granted under these terms. - -Khronos makes no, and expressly disclaims any, representations or -warranties, express or implied, regarding this Specification, including, -without limitation: merchantability, fitness for a particular purpose, -non-infringement of any intellectual property, correctness, accuracy, -completeness, timeliness, and reliability. -Under no circumstances will Khronos, or any of its Promoters, Contributors -or Members, or their respective partners, officers, directors, employees, -agents or representatives be liable for any damages, whether direct, -indirect, special or consequential damages for lost revenues, lost profits, -or otherwise, arising from or in connection with these materials. - -This Specification has been created under the Khronos Intellectual Property -Rights Policy, which is Attachment A of the Khronos Group Membership -Agreement available at https://www.khronos.org/files/member_agreement.pdf, and which -defines the terms 'Scope', 'Compliant Portion', and 'Necessary Patent Claims'. -Parties desiring to implement the Specification and make use of Khronos trademarks -in relation to that implementation, and receive reciprocal patent license protection -under the Khronos Intellectual Property Rights Policy must become Adopters and -confirm the implementation as conformant under the process defined by Khronos for -this Specification; see https://www.khronos.org/adopters. - -This Specification contains substantially unmodified functionality from, and is a -successor to, Khronos specifications including OpenGL, OpenGL ES and OpenCL. - -Some parts of this Specification are purely informative and so are EXCLUDED from -the Scope of this Specification. The <> section of the -<> defines how these parts of the Specification are identified. - -Where this Specification uses <>, defined in the <> or otherwise, that refer to -enabling technologies that are not expressly set forth in this -Specification, those enabling technologies are EXCLUDED from the Scope of -this Specification. -For clarity, enabling technologies not disclosed with particularity in this -Specification (e.g. semiconductor manufacturing technology, hardware -architecture, processor architecture or microarchitecture, memory -architecture, compiler technology, object oriented technology, basic -operating system technology, compression technology, algorithms, and so on) -are NOT to be considered expressly set forth; only those application program -interfaces and data structures disclosed with particularity are included in -the Scope of this Specification. - -For purposes of the Khronos Intellectual Property Rights Policy as it relates -to the definition of Necessary Patent Claims, all recommended or optional -features, behaviors and functionality set forth in this Specification, if -implemented, are considered to be included as Compliant Portions. - -Where this Specification includes <>, only the specifically -identified sections of those external documents are INCLUDED in the Scope of -this Specification. If not created by Khronos, those external documents may -contain contributions from non-members of Khronos not covered by the Khronos -Intellectual Property Rights Policy. - -ifndef::ratified_core_spec[] -This document contains extensions which are not ratified by Khronos, and as -such is not a ratified Specification, though it contains text from (and is a -superset of) the ratified Vulkan Specification. The ratified versions of the -Vulkan Specification can be found at -https://www.khronos.org/registry/vulkan/specs/1.2/html/vkspec.html (core -only) and -https://www.khronos.org/registry/vulkan/specs/1.2-khr-extensions/html/vkspec.html -(core with KHR extensions). -endif::ratified_core_spec[] - -Vulkan and Khronos are registered trademarks of The Khronos Group Inc. -ASTC is a trademark of ARM Holdings PLC; OpenCL is a trademark of Apple -Inc.; and OpenGL and OpenGL ES are registered trademarks of Hewlett Packard -Enterprise, all used under license by Khronos. All other product names, -trademarks, and/or company names are used solely for identification and -belong to their respective owners. diff --git a/README.md b/README.md index 8b87f0530..a09af6a8c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # OpenXR™ Software Development Kit (SDK) Sources Project diff --git a/changes/registry/README.md b/changes/registry/README.md index 8d98e0e55..58f646d7e 100644 --- a/changes/registry/README.md +++ b/changes/registry/README.md @@ -18,23 +18,23 @@ following as templates. For adding/enabling a vendor/multi-vendor extension: -> Add `XR_MYVENDOR_myextension` vendor extension. +> New vendor extension: `XR_MYVENDOR_myextension` - Add "provisional" before "vendor" if required. - If this is an EXT multi-vendor extension, change "vendor" to "multi-vendor". For adding/enabling a KHR or KHX extension: -> Add ratified `XR_KHR_myextension` Khronos extension. +> New ratified Khronos extension: `XR_KHR_myextension` - Add "provisional" before "Khronos" if it is a KHX extension. - Note that these all require the review period and board ratification! For reserving one or more extensions: -> Reserve a vendor extension for VendorName. +> Extension reservation: Reserve an extension for VendorName. -- Pluralize if reserving multiple extensions -- May pre-pend "Register author ID and" if applicable. +- Pluralize "an extension" if reserving multiple extensions +- May pre-pend "Register author ID and" if applicable (after the colon). - You may optionally provide information about your plans for those extensions, but this is not required, just permitted. diff --git a/changes/sdk/pr.336.gh.OpenXR-SDK-Source.md b/changes/sdk/pr.336.gh.OpenXR-SDK-Source.md deleted file mode 100644 index 29214eb16..000000000 --- a/changes/sdk/pr.336.gh.OpenXR-SDK-Source.md +++ /dev/null @@ -1 +0,0 @@ -Loader and layers: In debug builds, log when non-empty environment variables are being ignored due to executing with elevated privilege. diff --git a/changes/sdk/pr.346.gh.OpenXR-SDK-Source.md b/changes/sdk/pr.346.gh.OpenXR-SDK-Source.md deleted file mode 100644 index d2b0b6f3c..000000000 --- a/changes/sdk/pr.346.gh.OpenXR-SDK-Source.md +++ /dev/null @@ -1 +0,0 @@ -loader,api_layers: Fix finding wayland-client.h on linux diff --git a/changes/sdk/pr.357.gh.OpenXR-SDK-Source.md b/changes/sdk/pr.357.gh.OpenXR-SDK-Source.md deleted file mode 100644 index dfa371005..000000000 --- a/changes/sdk/pr.357.gh.OpenXR-SDK-Source.md +++ /dev/null @@ -1 +0,0 @@ -loader: Prefer cstdio and cstdlib for c++ files diff --git a/changes/sdk/pr.358.gh.OpenXR-SDK-Source.md b/changes/sdk/pr.358.gh.OpenXR-SDK-Source.md deleted file mode 100644 index ff7de5225..000000000 --- a/changes/sdk/pr.358.gh.OpenXR-SDK-Source.md +++ /dev/null @@ -1 +0,0 @@ -hello_xr: Export built-in NativeActivity diff --git a/changes/sdk/pr.359.gh.OpenXR-SDK-Source.md b/changes/sdk/pr.359.gh.OpenXR-SDK-Source.md deleted file mode 100644 index 3a7e3a384..000000000 --- a/changes/sdk/pr.359.gh.OpenXR-SDK-Source.md +++ /dev/null @@ -1,2 +0,0 @@ -clang-format: Add clang-format-15 as acceptable clang formats -hello_xr: Use correct lost event count diff --git a/changes/sdk/pr.362.gh.OpenXR-SDK-Source.md b/changes/sdk/pr.362.gh.OpenXR-SDK-Source.md deleted file mode 100644 index 36d28e9a3..000000000 --- a/changes/sdk/pr.362.gh.OpenXR-SDK-Source.md +++ /dev/null @@ -1 +0,0 @@ -Loader: Fix dynamic build on MinGW. diff --git a/changes/sdk/pr.381.gh.OpenXR-SDK-Source.md b/changes/sdk/pr.381.gh.OpenXR-SDK-Source.md deleted file mode 100644 index 03a6e9ae8..000000000 --- a/changes/sdk/pr.381.gh.OpenXR-SDK-Source.md +++ /dev/null @@ -1 +0,0 @@ -doc: Add VS 2022 version code to BUILDING.md diff --git a/checkCodespell b/checkCodespell index ed827def2..e5afb893d 100755 --- a/checkCodespell +++ b/checkCodespell @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2019-2022, The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # diff --git a/external/include/CMakeLists.txt b/external/include/CMakeLists.txt index 7c4748399..dd0a905be 100644 --- a/external/include/CMakeLists.txt +++ b/external/include/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 @@ -15,12 +15,5 @@ foreach(FN ${INCLUDE_DIR}/GL/glext.h ${INCLUDE_DIR}/GL/wglext.h) endif() endforeach() -set( UTILS_HEADERS - ${INCLUDE_DIR}/utils/algebra.h - ${INCLUDE_DIR}/utils/sysinfo.h - ${INCLUDE_DIR}/utils/nanoseconds.h - ${INCLUDE_DIR}/utils/threading.h ) -source_group( utils FILES ${UTILS_HEADERS} ) source_group( GL FILES ${GL_HEADERS} ) -add_library( include INTERFACE ${UTILS_HEADERS} ${GL_HEADERS}) set_property( TARGET include PROPERTY FOLDER external/include ) diff --git a/external/include/utils/algebra.h b/external/include/utils/algebra.h deleted file mode 100644 index eb0035ae4..000000000 --- a/external/include/utils/algebra.h +++ /dev/null @@ -1,971 +0,0 @@ -/* -================================================================================================ - -Description : Vector, matrix and quaternion math. -Author : J.M.P. van Waveren -Date : 12/10/2016 -Language : C99 -Format : Real tabs with the tab size equal to 4 spaces. -Copyright : Copyright (c) 2016 Oculus VR, LLC. All Rights reserved. - - -LICENSE -======= - -Copyright (c) 2016 Oculus VR, LLC. - -SPDX-License-Identifier: Apache-2.0 - -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. - -DESCRIPTION -=========== - -All matrices are column-major. - -Set one of the following defines to 1 before including this header file to -construct an appropriate projection matrix for a particular graphics API. - -#define GRAPHICS_API_OPENGL 0 -#define GRAPHICS_API_OPENGL_ES 0 -#define GRAPHICS_API_VULKAN 0 -#define GRAPHICS_API_D3D 0 -#define GRAPHICS_API_METAL 0 - - -INTERFACE -========= - -ksVector2i -ksVector3i -ksVector4i -ksVector2f -ksVector3f -ksVector4f -ksQuatf -ksMatrix2x2f -ksMatrix2x3f -ksMatrix2x4f -ksMatrix3x2f -ksMatrix3x3f -ksMatrix3x4f -ksMatrix4x2f -ksMatrix4x3f -ksMatrix4x4f - -static inline void ksVector3f_Set( ksVector3f * v, const float value ); -static inline void ksVector3f_Add( ksVector3f * result, const ksVector3f * a, const ksVector3f * b ); -static inline void ksVector3f_Sub( ksVector3f * result, const ksVector3f * a, const ksVector3f * b ); -static inline void ksVector3f_Min( ksVector3f * result, const ksVector3f * a, const ksVector3f * b ); -static inline void ksVector3f_Max( ksVector3f * result, const ksVector3f * a, const ksVector3f * b ); -static inline void ksVector3f_Decay( ksVector3f * result, const ksVector3f * a, const float value ); -static inline void ksVector3f_Lerp( ksVector3f * result, const ksVector3f * a, const ksVector3f * b, const float fraction ); -static inline void ksVector3f_Normalize( ksVector3f * v ); -static inline float ksVector3f_Length( const ksVector3f * v ); - -static inline void ksQuatf_Lerp( ksQuatf * result, const ksQuatf * a, const ksQuatf * b, const float fraction ); - -static inline void ksMatrix3x3f_CreateTransposeFromMatrix4x4f( ksMatrix3x3f * result, const ksMatrix4x4f * src ); -static inline void ksMatrix3x4f_CreateFromMatrix4x4f( ksMatrix3x4f * result, const ksMatrix4x4f * src ); - -static inline void ksMatrix4x4f_CreateIdentity( ksMatrix4x4f * result ); -static inline void ksMatrix4x4f_CreateTranslation( ksMatrix4x4f * result, const float x, const float y, const float z ); -static inline void ksMatrix4x4f_CreateRotation( ksMatrix4x4f * result, const float degreesX, const float degreesY, const float degreesZ ); -static inline void ksMatrix4x4f_CreateScale( ksMatrix4x4f * result, const float x, const float y, const float z ); -static inline void ksMatrix4x4f_CreateTranslationRotationScale( ksMatrix4x4f * result, const ksVector3f * translation, const ksQuatf * rotation, const ksVector3f * scale ); -static inline void ksMatrix4x4f_CreateProjection( ksMatrix4x4f * result, const float tanAngleLeft, const float tanAngleRight, - const float tanAngleUp, float const tanAngleDown, const float nearZ, const float farZ ); -static inline void ksMatrix4x4f_CreateProjectionFov( ksMatrix4x4f * result, const float fovDegreesLeft, const float fovDegreesRight, - const float fovDegreeUp, const float fovDegreesDown, const float nearZ, const float farZ ); -static inline void ksMatrix4x4f_CreateFromQuaternion( ksMatrix3x4f * result, const ksQuatf * src ); -static inline void ksMatrix4x4f_CreateOffsetScaleForBounds( ksMatrix4x4f * result, const ksMatrix4x4f * matrix, const ksVector3f * mins, const ksVector3f * maxs ); - -static inline bool ksMatrix4x4f_IsAffine( const ksMatrix4x4f * matrix, const float epsilon ); -static inline bool ksMatrix4x4f_IsOrthogonal( const ksMatrix4x4f * matrix, const float epsilon ); -static inline bool ksMatrix4x4f_IsOrthonormal( const ksMatrix4x4f * matrix, const float epsilon ); -static inline bool ksMatrix4x4f_IsHomogeneous( const ksMatrix4x4f * matrix, const float epsilon ); - -static inline void ksMatrix4x4f_GetTranslation( ksVector3f * result, const ksMatrix4x4f * src ); -static inline void ksMatrix4x4f_GetRotation( ksQuatf * result, const ksMatrix4x4f * src ); -static inline void ksMatrix4x4f_GetScale( ksVector3f * result, const ksMatrix4x4f * src ); - -static inline void ksMatrix4x4f_Multiply( ksMatrix4x4f * result, const ksMatrix4x4f * a, const ksMatrix4x4f * b ); -static inline void ksMatrix4x4f_Transpose( ksMatrix4x4f * result, const ksMatrix4x4f * src ); -static inline void ksMatrix4x4f_Invert( ksMatrix4x4f * result, const ksMatrix4x4f * src ); -static inline void ksMatrix4x4f_InvertHomogeneous( ksMatrix4x4f * result, const ksMatrix4x4f * src ); - -static inline void ksMatrix4x4f_TransformVector3f( ksVector3f * result, const ksMatrix4x4f * m, const ksVector3f * v ); -static inline void ksMatrix4x4f_TransformVector4f( ksVector4f * result, const ksMatrix4x4f * m, const ksVector4f * v ); - -static inline void ksMatrix4x4f_TransformBounds( ksVector3f * resultMins, ksVector3f * resultMaxs, const ksMatrix4x4f * matrix, const ksVector3f * mins, const ksVector3f * maxs ); -static inline bool ksMatrix4x4f_CullBounds( const ksMatrix4x4f * mvp, const ksVector3f * mins, const ksVector3f * maxs ); - -================================================================================================ -*/ - -#if !defined( KSALGEBRA_H ) -#define KSALGEBRA_H - -#include -#include - -#define MATH_PI 3.14159265358979323846f - -#define DEFAULT_NEAR_Z 0.015625f // exact floating point representation -#define INFINITE_FAR_Z 0.0f - -// 2D integer vector -typedef struct -{ - int x; - int y; -} ksVector2i; - -// 3D integer vector -typedef struct -{ - int x; - int y; - int z; -} ksVector3i; - -// 4D integer vector -typedef struct -{ - int x; - int y; - int z; - int w; -} ksVector4i; - -// 2D float vector -typedef struct -{ - float x; - float y; -} ksVector2f; - -// 3D float vector -typedef struct -{ - float x; - float y; - float z; -} ksVector3f; - -// 4D float vector -typedef struct -{ - float x; - float y; - float z; - float w; -} ksVector4f; - -// Quaternion -typedef struct -{ - float x; - float y; - float z; - float w; -} ksQuatf; - -// Column-major 2x2 matrix -typedef struct -{ - float m[2][2]; -} ksMatrix2x2f; - -// Column-major 2x3 matrix -typedef struct -{ - float m[2][3]; -} ksMatrix2x3f; - -// Column-major 2x4 matrix -typedef struct -{ - float m[2][4]; -} ksMatrix2x4f; - -// Column-major 3x2 matrix -typedef struct -{ - float m[3][2]; -} ksMatrix3x2f; - -// Column-major 3x3 matrix -typedef struct -{ - float m[3][3]; -} ksMatrix3x3f; - -// Column-major 3x4 matrix -typedef struct -{ - float m[3][4]; -} ksMatrix3x4f; - -// Column-major 4x2 matrix -typedef struct -{ - float m[4][2]; -} ksMatrix4x2f; - -// Column-major 4x3 matrix -typedef struct -{ - float m[4][3]; -} ksMatrix4x3f; - -// Column-major 4x4 matrix -typedef struct -{ - float m[4][4]; -} ksMatrix4x4f; - -static const ksVector4f ksColorRed = { 1.0f, 0.0f, 0.0f, 1.0f }; -static const ksVector4f ksColorGreen = { 0.0f, 1.0f, 0.0f, 1.0f }; -static const ksVector4f ksColorBlue = { 0.0f, 0.0f, 1.0f, 1.0f }; -static const ksVector4f ksColorYellow = { 1.0f, 1.0f, 0.0f, 1.0f }; -static const ksVector4f ksColorPurple = { 1.0f, 0.0f, 1.0f, 1.0f }; -static const ksVector4f ksColorCyan = { 0.0f, 1.0f, 1.0f, 1.0f }; -static const ksVector4f ksColorLightGrey = { 0.7f, 0.7f, 0.7f, 1.0f }; -static const ksVector4f ksColorDarkGrey = { 0.3f, 0.3f, 0.3f, 1.0f }; - -static inline float ksRcpSqrt( const float x ) -{ - const float SMALLEST_NON_DENORMAL = 1.1754943508222875e-038f; // ( 1U << 23 ) - const float rcp = ( x >= SMALLEST_NON_DENORMAL ) ? 1.0f / sqrtf( x ) : 1.0f; - return rcp; -} - -static inline void ksVector3f_Set( ksVector3f * v, const float value ) -{ - v->x = value; - v->y = value; - v->z = value; -} - -static inline void ksVector3f_Add( ksVector3f * result, const ksVector3f * a, const ksVector3f * b ) -{ - result->x = a->x + b->x; - result->y = a->y + b->y; - result->z = a->z + b->z; -} - -static inline void ksVector3f_Sub( ksVector3f * result, const ksVector3f * a, const ksVector3f * b ) -{ - result->x = a->x - b->x; - result->y = a->y - b->y; - result->z = a->z - b->z; -} - -static inline void ksVector3f_Min( ksVector3f * result, const ksVector3f * a, const ksVector3f * b ) -{ - result->x = ( a->x < b->x ) ? a->x : b->x; - result->y = ( a->y < b->y ) ? a->y : b->y; - result->z = ( a->z < b->z ) ? a->z : b->z; -} - -static inline void ksVector3f_Max( ksVector3f * result, const ksVector3f * a, const ksVector3f * b ) -{ - result->x = ( a->x > b->x ) ? a->x : b->x; - result->y = ( a->y > b->y ) ? a->y : b->y; - result->z = ( a->z > b->z ) ? a->z : b->z; -} - -static inline void ksVector3f_Decay( ksVector3f * result, const ksVector3f * a, const float value ) -{ - result->x = ( fabsf( a->x ) > value ) ? ( ( a->x > 0.0f ) ? ( a->x - value ) : ( a->x + value ) ) : 0.0f; - result->y = ( fabsf( a->y ) > value ) ? ( ( a->y > 0.0f ) ? ( a->y - value ) : ( a->y + value ) ) : 0.0f; - result->z = ( fabsf( a->z ) > value ) ? ( ( a->z > 0.0f ) ? ( a->z - value ) : ( a->z + value ) ) : 0.0f; -} - -static inline void ksVector3f_Lerp( ksVector3f * result, const ksVector3f * a, const ksVector3f * b, const float fraction ) -{ - result->x = a->x + fraction * ( b->x - a->x ); - result->y = a->y + fraction * ( b->y - a->y ); - result->z = a->z + fraction * ( b->z - a->z ); -} - -static inline void ksVector3f_Normalize( ksVector3f * v ) -{ - const float lengthRcp = ksRcpSqrt( v->x * v->x + v->y * v->y + v->z * v->z ); - v->x *= lengthRcp; - v->y *= lengthRcp; - v->z *= lengthRcp; -} - -static inline float ksVector3f_Length( const ksVector3f * v ) -{ - return sqrtf( v->x * v->x + v->y * v->y + v->z * v->z ); -} - -static inline void ksQuatf_Lerp( ksQuatf * result, const ksQuatf * a, const ksQuatf * b, const float fraction ) -{ - const float s = a->x * b->x + a->y * b->y + a->z * b->z + a->w * b->w; - const float fa = 1.0f - fraction; - const float fb = ( s < 0.0f ) ? -fraction : fraction; - const float x = a->x * fa + b->x * fb; - const float y = a->y * fa + b->y * fb; - const float z = a->z * fa + b->z * fb; - const float w = a->w * fa + b->w * fb; - const float lengthRcp = ksRcpSqrt( x * x + y * y + z * z + w * w ); - result->x = x * lengthRcp; - result->y = y * lengthRcp; - result->z = z * lengthRcp; - result->w = w * lengthRcp; -} - -static inline void ksMatrix3x3f_CreateTransposeFromMatrix4x4f( ksMatrix3x3f * result, const ksMatrix4x4f * src ) -{ - result->m[0][0] = src->m[0][0]; - result->m[0][1] = src->m[1][0]; - result->m[0][2] = src->m[2][0]; - - result->m[1][0] = src->m[0][1]; - result->m[1][1] = src->m[1][1]; - result->m[1][2] = src->m[2][1]; - - result->m[2][0] = src->m[0][2]; - result->m[2][1] = src->m[1][2]; - result->m[2][2] = src->m[2][2]; -} - -static inline void ksMatrix3x4f_CreateFromMatrix4x4f( ksMatrix3x4f * result, const ksMatrix4x4f * src ) -{ - result->m[0][0] = src->m[0][0]; - result->m[0][1] = src->m[1][0]; - result->m[0][2] = src->m[2][0]; - result->m[0][3] = src->m[3][0]; - result->m[1][0] = src->m[0][1]; - result->m[1][1] = src->m[1][1]; - result->m[1][2] = src->m[2][1]; - result->m[1][3] = src->m[3][1]; - result->m[2][0] = src->m[0][2]; - result->m[2][1] = src->m[1][2]; - result->m[2][2] = src->m[2][2]; - result->m[2][3] = src->m[3][2]; -} - -// Use left-multiplication to accumulate transformations. -static inline void ksMatrix4x4f_Multiply( ksMatrix4x4f * result, const ksMatrix4x4f * a, const ksMatrix4x4f * b ) -{ - result->m[0][0] = a->m[0][0] * b->m[0][0] + a->m[1][0] * b->m[0][1] + a->m[2][0] * b->m[0][2] + a->m[3][0] * b->m[0][3]; - result->m[0][1] = a->m[0][1] * b->m[0][0] + a->m[1][1] * b->m[0][1] + a->m[2][1] * b->m[0][2] + a->m[3][1] * b->m[0][3]; - result->m[0][2] = a->m[0][2] * b->m[0][0] + a->m[1][2] * b->m[0][1] + a->m[2][2] * b->m[0][2] + a->m[3][2] * b->m[0][3]; - result->m[0][3] = a->m[0][3] * b->m[0][0] + a->m[1][3] * b->m[0][1] + a->m[2][3] * b->m[0][2] + a->m[3][3] * b->m[0][3]; - - result->m[1][0] = a->m[0][0] * b->m[1][0] + a->m[1][0] * b->m[1][1] + a->m[2][0] * b->m[1][2] + a->m[3][0] * b->m[1][3]; - result->m[1][1] = a->m[0][1] * b->m[1][0] + a->m[1][1] * b->m[1][1] + a->m[2][1] * b->m[1][2] + a->m[3][1] * b->m[1][3]; - result->m[1][2] = a->m[0][2] * b->m[1][0] + a->m[1][2] * b->m[1][1] + a->m[2][2] * b->m[1][2] + a->m[3][2] * b->m[1][3]; - result->m[1][3] = a->m[0][3] * b->m[1][0] + a->m[1][3] * b->m[1][1] + a->m[2][3] * b->m[1][2] + a->m[3][3] * b->m[1][3]; - - result->m[2][0] = a->m[0][0] * b->m[2][0] + a->m[1][0] * b->m[2][1] + a->m[2][0] * b->m[2][2] + a->m[3][0] * b->m[2][3]; - result->m[2][1] = a->m[0][1] * b->m[2][0] + a->m[1][1] * b->m[2][1] + a->m[2][1] * b->m[2][2] + a->m[3][1] * b->m[2][3]; - result->m[2][2] = a->m[0][2] * b->m[2][0] + a->m[1][2] * b->m[2][1] + a->m[2][2] * b->m[2][2] + a->m[3][2] * b->m[2][3]; - result->m[2][3] = a->m[0][3] * b->m[2][0] + a->m[1][3] * b->m[2][1] + a->m[2][3] * b->m[2][2] + a->m[3][3] * b->m[2][3]; - - result->m[3][0] = a->m[0][0] * b->m[3][0] + a->m[1][0] * b->m[3][1] + a->m[2][0] * b->m[3][2] + a->m[3][0] * b->m[3][3]; - result->m[3][1] = a->m[0][1] * b->m[3][0] + a->m[1][1] * b->m[3][1] + a->m[2][1] * b->m[3][2] + a->m[3][1] * b->m[3][3]; - result->m[3][2] = a->m[0][2] * b->m[3][0] + a->m[1][2] * b->m[3][1] + a->m[2][2] * b->m[3][2] + a->m[3][2] * b->m[3][3]; - result->m[3][3] = a->m[0][3] * b->m[3][0] + a->m[1][3] * b->m[3][1] + a->m[2][3] * b->m[3][2] + a->m[3][3] * b->m[3][3]; -} - -// Creates the transpose of the given matrix. -static inline void ksMatrix4x4f_Transpose( ksMatrix4x4f * result, const ksMatrix4x4f * src ) -{ - result->m[0][0] = src->m[0][0]; - result->m[0][1] = src->m[1][0]; - result->m[0][2] = src->m[2][0]; - result->m[0][3] = src->m[3][0]; - - result->m[1][0] = src->m[0][1]; - result->m[1][1] = src->m[1][1]; - result->m[1][2] = src->m[2][1]; - result->m[1][3] = src->m[3][1]; - - result->m[2][0] = src->m[0][2]; - result->m[2][1] = src->m[1][2]; - result->m[2][2] = src->m[2][2]; - result->m[2][3] = src->m[3][2]; - - result->m[3][0] = src->m[0][3]; - result->m[3][1] = src->m[1][3]; - result->m[3][2] = src->m[2][3]; - result->m[3][3] = src->m[3][3]; -} - -// Returns a 3x3 minor of a 4x4 matrix. -static inline float ksMatrix4x4f_Minor( const ksMatrix4x4f * matrix, int r0, int r1, int r2, int c0, int c1, int c2 ) -{ - return matrix->m[r0][c0] * ( matrix->m[r1][c1] * matrix->m[r2][c2] - matrix->m[r2][c1] * matrix->m[r1][c2] ) - - matrix->m[r0][c1] * ( matrix->m[r1][c0] * matrix->m[r2][c2] - matrix->m[r2][c0] * matrix->m[r1][c2] ) + - matrix->m[r0][c2] * ( matrix->m[r1][c0] * matrix->m[r2][c1] - matrix->m[r2][c0] * matrix->m[r1][c1] ); -} - -// Calculates the inverse of a 4x4 matrix. -static inline void ksMatrix4x4f_Invert( ksMatrix4x4f * result, const ksMatrix4x4f * src ) -{ - const float rcpDet = 1.0f / ( src->m[0][0] * ksMatrix4x4f_Minor( src, 1, 2, 3, 1, 2, 3 ) - - src->m[0][1] * ksMatrix4x4f_Minor( src, 1, 2, 3, 0, 2, 3 ) + - src->m[0][2] * ksMatrix4x4f_Minor( src, 1, 2, 3, 0, 1, 3 ) - - src->m[0][3] * ksMatrix4x4f_Minor( src, 1, 2, 3, 0, 1, 2 ) ); - - result->m[0][0] = ksMatrix4x4f_Minor( src, 1, 2, 3, 1, 2, 3 ) * rcpDet; - result->m[0][1] = -ksMatrix4x4f_Minor( src, 0, 2, 3, 1, 2, 3 ) * rcpDet; - result->m[0][2] = ksMatrix4x4f_Minor( src, 0, 1, 3, 1, 2, 3 ) * rcpDet; - result->m[0][3] = -ksMatrix4x4f_Minor( src, 0, 1, 2, 1, 2, 3 ) * rcpDet; - result->m[1][0] = -ksMatrix4x4f_Minor( src, 1, 2, 3, 0, 2, 3 ) * rcpDet; - result->m[1][1] = ksMatrix4x4f_Minor( src, 0, 2, 3, 0, 2, 3 ) * rcpDet; - result->m[1][2] = -ksMatrix4x4f_Minor( src, 0, 1, 3, 0, 2, 3 ) * rcpDet; - result->m[1][3] = ksMatrix4x4f_Minor( src, 0, 1, 2, 0, 2, 3 ) * rcpDet; - result->m[2][0] = ksMatrix4x4f_Minor( src, 1, 2, 3, 0, 1, 3 ) * rcpDet; - result->m[2][1] = -ksMatrix4x4f_Minor( src, 0, 2, 3, 0, 1, 3 ) * rcpDet; - result->m[2][2] = ksMatrix4x4f_Minor( src, 0, 1, 3, 0, 1, 3 ) * rcpDet; - result->m[2][3] = -ksMatrix4x4f_Minor( src, 0, 1, 2, 0, 1, 3 ) * rcpDet; - result->m[3][0] = -ksMatrix4x4f_Minor( src, 1, 2, 3, 0, 1, 2 ) * rcpDet; - result->m[3][1] = ksMatrix4x4f_Minor( src, 0, 2, 3, 0, 1, 2 ) * rcpDet; - result->m[3][2] = -ksMatrix4x4f_Minor( src, 0, 1, 3, 0, 1, 2 ) * rcpDet; - result->m[3][3] = ksMatrix4x4f_Minor( src, 0, 1, 2, 0, 1, 2 ) * rcpDet; -} - -// Calculates the inverse of a 4x4 homogeneous matrix. -static inline void ksMatrix4x4f_InvertHomogeneous( ksMatrix4x4f * result, const ksMatrix4x4f * src ) -{ - result->m[0][0] = src->m[0][0]; - result->m[0][1] = src->m[1][0]; - result->m[0][2] = src->m[2][0]; - result->m[0][3] = 0.0f; - result->m[1][0] = src->m[0][1]; - result->m[1][1] = src->m[1][1]; - result->m[1][2] = src->m[2][1]; - result->m[1][3] = 0.0f; - result->m[2][0] = src->m[0][2]; - result->m[2][1] = src->m[1][2]; - result->m[2][2] = src->m[2][2]; - result->m[2][3] = 0.0f; - result->m[3][0] = -( src->m[0][0] * src->m[3][0] + src->m[0][1] * src->m[3][1] + src->m[0][2] * src->m[3][2] ); - result->m[3][1] = -( src->m[1][0] * src->m[3][0] + src->m[1][1] * src->m[3][1] + src->m[1][2] * src->m[3][2] ); - result->m[3][2] = -( src->m[2][0] * src->m[3][0] + src->m[2][1] * src->m[3][1] + src->m[2][2] * src->m[3][2] ); - result->m[3][3] = 1.0f; -} - -// Creates an identity matrix. -static inline void ksMatrix4x4f_CreateIdentity( ksMatrix4x4f * result ) -{ - result->m[0][0] = 1.0f; result->m[0][1] = 0.0f; result->m[0][2] = 0.0f; result->m[0][3] = 0.0f; - result->m[1][0] = 0.0f; result->m[1][1] = 1.0f; result->m[1][2] = 0.0f; result->m[1][3] = 0.0f; - result->m[2][0] = 0.0f; result->m[2][1] = 0.0f; result->m[2][2] = 1.0f; result->m[2][3] = 0.0f; - result->m[3][0] = 0.0f; result->m[3][1] = 0.0f; result->m[3][2] = 0.0f; result->m[3][3] = 1.0f; -} - -// Creates a translation matrix. -static inline void ksMatrix4x4f_CreateTranslation( ksMatrix4x4f * result, const float x, const float y, const float z ) -{ - result->m[0][0] = 1.0f; result->m[0][1] = 0.0f; result->m[0][2] = 0.0f; result->m[0][3] = 0.0f; - result->m[1][0] = 0.0f; result->m[1][1] = 1.0f; result->m[1][2] = 0.0f; result->m[1][3] = 0.0f; - result->m[2][0] = 0.0f; result->m[2][1] = 0.0f; result->m[2][2] = 1.0f; result->m[2][3] = 0.0f; - result->m[3][0] = x; result->m[3][1] = y; result->m[3][2] = z; result->m[3][3] = 1.0f; -} - -// Creates a rotation matrix. -// If -Z=forward, +Y=up, +X=right, then degreesX=pitch, degreesY=yaw, degreesZ=roll. -static inline void ksMatrix4x4f_CreateRotation( ksMatrix4x4f * result, const float degreesX, const float degreesY, const float degreesZ ) -{ - const float sinX = sinf( degreesX * ( MATH_PI / 180.0f ) ); - const float cosX = cosf( degreesX * ( MATH_PI / 180.0f ) ); - const ksMatrix4x4f rotationX = - { { - { 1, 0, 0, 0 }, - { 0, cosX, sinX, 0 }, - { 0, -sinX, cosX, 0 }, - { 0, 0, 0, 1 } - } }; - const float sinY = sinf( degreesY * ( MATH_PI / 180.0f ) ); - const float cosY = cosf( degreesY * ( MATH_PI / 180.0f ) ); - const ksMatrix4x4f rotationY = - { { - { cosY, 0, -sinY, 0 }, - { 0, 1, 0, 0 }, - { sinY, 0, cosY, 0 }, - { 0, 0, 0, 1 } - } }; - const float sinZ = sinf( degreesZ * ( MATH_PI / 180.0f ) ); - const float cosZ = cosf( degreesZ * ( MATH_PI / 180.0f ) ); - const ksMatrix4x4f rotationZ = - { { - { cosZ, sinZ, 0, 0 }, - { -sinZ, cosZ, 0, 0 }, - { 0, 0, 1, 0 }, - { 0, 0, 0, 1 } - } }; - ksMatrix4x4f rotationXY; - ksMatrix4x4f_Multiply( &rotationXY, &rotationY, &rotationX ); - ksMatrix4x4f_Multiply( result, &rotationZ, &rotationXY ); -} - -// Creates a scale matrix. -static inline void ksMatrix4x4f_CreateScale( ksMatrix4x4f * result, const float x, const float y, const float z ) -{ - result->m[0][0] = x; result->m[0][1] = 0.0f; result->m[0][2] = 0.0f; result->m[0][3] = 0.0f; - result->m[1][0] = 0.0f; result->m[1][1] = y; result->m[1][2] = 0.0f; result->m[1][3] = 0.0f; - result->m[2][0] = 0.0f; result->m[2][1] = 0.0f; result->m[2][2] = z; result->m[2][3] = 0.0f; - result->m[3][0] = 0.0f; result->m[3][1] = 0.0f; result->m[3][2] = 0.0f; result->m[3][3] = 1.0f; -} - -// Creates a matrix from a quaternion. -static inline void ksMatrix4x4f_CreateFromQuaternion( ksMatrix4x4f * result, const ksQuatf * quat ) -{ - const float x2 = quat->x + quat->x; - const float y2 = quat->y + quat->y; - const float z2 = quat->z + quat->z; - - const float xx2 = quat->x * x2; - const float yy2 = quat->y * y2; - const float zz2 = quat->z * z2; - - const float yz2 = quat->y * z2; - const float wx2 = quat->w * x2; - const float xy2 = quat->x * y2; - const float wz2 = quat->w * z2; - const float xz2 = quat->x * z2; - const float wy2 = quat->w * y2; - - result->m[0][0] = 1.0f - yy2 - zz2; - result->m[0][1] = xy2 + wz2; - result->m[0][2] = xz2 - wy2; - result->m[0][3] = 0.0f; - - result->m[1][0] = xy2 - wz2; - result->m[1][1] = 1.0f - xx2 - zz2; - result->m[1][2] = yz2 + wx2; - result->m[1][3] = 0.0f; - - result->m[2][0] = xz2 + wy2; - result->m[2][1] = yz2 - wx2; - result->m[2][2] = 1.0f - xx2 - yy2; - result->m[2][3] = 0.0f; - - result->m[3][0] = 0.0f; - result->m[3][1] = 0.0f; - result->m[3][2] = 0.0f; - result->m[3][3] = 1.0f; -} - -// Creates a combined translation(rotation(scale(object))) matrix. -static inline void ksMatrix4x4f_CreateTranslationRotationScale( ksMatrix4x4f * result, const ksVector3f * translation, const ksQuatf * rotation, const ksVector3f * scale ) -{ - ksMatrix4x4f scaleMatrix; - ksMatrix4x4f_CreateScale( &scaleMatrix, scale->x, scale->y, scale->z ); - - ksMatrix4x4f rotationMatrix; - ksMatrix4x4f_CreateFromQuaternion( &rotationMatrix, rotation ); - - ksMatrix4x4f translationMatrix; - ksMatrix4x4f_CreateTranslation( &translationMatrix, translation->x, translation->y, translation->z ); - - ksMatrix4x4f combinedMatrix; - ksMatrix4x4f_Multiply( &combinedMatrix, &rotationMatrix, &scaleMatrix ); - ksMatrix4x4f_Multiply( result, &translationMatrix, &combinedMatrix ); -} - -// Creates a projection matrix based on the specified dimensions. -// The projection matrix transforms -Z=forward, +Y=up, +X=right to the appropriate clip space for the graphics API. -// The far plane is placed at infinity if farZ <= nearZ. -// An infinite projection matrix is preferred for rasterization because, except for -// things *right* up against the near plane, it always provides better precision: -// "Tightening the Precision of Perspective Rendering" -// Paul Upchurch, Mathieu Desbrun -// Journal of Graphics Tools, Volume 16, Issue 1, 2012 -static inline void ksMatrix4x4f_CreateProjection( ksMatrix4x4f * result, const float tanAngleLeft, const float tanAngleRight, - const float tanAngleUp, float const tanAngleDown, const float nearZ, const float farZ ) -{ - const float tanAngleWidth = tanAngleRight - tanAngleLeft; - -#if GRAPHICS_API_VULKAN == 1 - // Set to tanAngleDown - tanAngleUp for a clip space with positive Y down (Vulkan). - const float tanAngleHeight = tanAngleDown - tanAngleUp; -#else - // Set to tanAngleUp - tanAngleDown for a clip space with positive Y up (OpenGL / D3D / Metal). - const float tanAngleHeight = tanAngleUp - tanAngleDown; -#endif - -#if GRAPHICS_API_OPENGL == 1 || GRAPHICS_API_OPENGL_ES == 1 - // Set to nearZ for a [-1,1] Z clip space (OpenGL / OpenGL ES). - const float offsetZ = nearZ; -#else - // Set to zero for a [0,1] Z clip space (Vulkan / D3D / Metal). - const float offsetZ = 0; -#endif - - if ( farZ <= nearZ ) - { - // place the far plane at infinity - result->m[0][0] = 2 / tanAngleWidth; - result->m[1][0] = 0; - result->m[2][0] = ( tanAngleRight + tanAngleLeft ) / tanAngleWidth; - result->m[3][0] = 0; - - result->m[0][1] = 0; - result->m[1][1] = 2 / tanAngleHeight; - result->m[2][1] = ( tanAngleUp + tanAngleDown ) / tanAngleHeight; - result->m[3][1] = 0; - - result->m[0][2] = 0; - result->m[1][2] = 0; - result->m[2][2] = -1; - result->m[3][2] = -( nearZ + offsetZ ); - - result->m[0][3] = 0; - result->m[1][3] = 0; - result->m[2][3] = -1; - result->m[3][3] = 0; - } - else - { - // normal projection - result->m[0][0] = 2 / tanAngleWidth; - result->m[1][0] = 0; - result->m[2][0] = ( tanAngleRight + tanAngleLeft ) / tanAngleWidth; - result->m[3][0] = 0; - - result->m[0][1] = 0; - result->m[1][1] = 2 / tanAngleHeight; - result->m[2][1] = ( tanAngleUp + tanAngleDown ) / tanAngleHeight; - result->m[3][1] = 0; - - result->m[0][2] = 0; - result->m[1][2] = 0; - result->m[2][2] = -( farZ + offsetZ ) / ( farZ - nearZ ); - result->m[3][2] = -( farZ * ( nearZ + offsetZ ) ) / ( farZ - nearZ ); - - result->m[0][3] = 0; - result->m[1][3] = 0; - result->m[2][3] = -1; - result->m[3][3] = 0; - } -} - -// Creates a projection matrix based on the specified FOV. -static inline void ksMatrix4x4f_CreateProjectionFov( ksMatrix4x4f * result, const float fovDegreesLeft, const float fovDegreesRight, - const float fovDegreesUp, const float fovDegreesDown, const float nearZ, const float farZ ) -{ - const float tanLeft = - tanf( fovDegreesLeft * ( MATH_PI / 180.0f ) ); - const float tanRight = tanf( fovDegreesRight * ( MATH_PI / 180.0f ) ); - - const float tanDown = - tanf( fovDegreesDown * ( MATH_PI / 180.0f ) ); - const float tanUp = tanf( fovDegreesUp * ( MATH_PI / 180.0f ) ); - - ksMatrix4x4f_CreateProjection( result, tanLeft, tanRight, tanUp, tanDown, nearZ, farZ ); -} - -// Creates a matrix that transforms the -1 to 1 cube to cover the given 'mins' and 'maxs' transformed with the given 'matrix'. -static inline void ksMatrix4x4f_CreateOffsetScaleForBounds( ksMatrix4x4f * result, const ksMatrix4x4f * matrix, const ksVector3f * mins, const ksVector3f * maxs ) -{ - const ksVector3f offset = { ( maxs->x + mins->x ) * 0.5f, ( maxs->y + mins->y ) * 0.5f, ( maxs->z + mins->z ) * 0.5f }; - const ksVector3f scale = { ( maxs->x - mins->x ) * 0.5f, ( maxs->y - mins->y ) * 0.5f, ( maxs->z - mins->z ) * 0.5f }; - - result->m[0][0] = matrix->m[0][0] * scale.x; - result->m[0][1] = matrix->m[0][1] * scale.x; - result->m[0][2] = matrix->m[0][2] * scale.x; - result->m[0][3] = matrix->m[0][3] * scale.x; - - result->m[1][0] = matrix->m[1][0] * scale.y; - result->m[1][1] = matrix->m[1][1] * scale.y; - result->m[1][2] = matrix->m[1][2] * scale.y; - result->m[1][3] = matrix->m[1][3] * scale.y; - - result->m[2][0] = matrix->m[2][0] * scale.z; - result->m[2][1] = matrix->m[2][1] * scale.z; - result->m[2][2] = matrix->m[2][2] * scale.z; - result->m[2][3] = matrix->m[2][3] * scale.z; - - result->m[3][0] = matrix->m[3][0] + matrix->m[0][0] * offset.x + matrix->m[1][0] * offset.y + matrix->m[2][0] * offset.z; - result->m[3][1] = matrix->m[3][1] + matrix->m[0][1] * offset.x + matrix->m[1][1] * offset.y + matrix->m[2][1] * offset.z; - result->m[3][2] = matrix->m[3][2] + matrix->m[0][2] * offset.x + matrix->m[1][2] * offset.y + matrix->m[2][2] * offset.z; - result->m[3][3] = matrix->m[3][3] + matrix->m[0][3] * offset.x + matrix->m[1][3] * offset.y + matrix->m[2][3] * offset.z; -} - -// Returns true if the given matrix is affine. -static inline bool ksMatrix4x4f_IsAffine( const ksMatrix4x4f * matrix, const float epsilon ) -{ - return fabsf( matrix->m[0][3] ) <= epsilon && - fabsf( matrix->m[1][3] ) <= epsilon && - fabsf( matrix->m[2][3] ) <= epsilon && - fabsf( matrix->m[3][3] - 1.0f ) <= epsilon; -} - -// Returns true if the given matrix is orthogonal. -static inline bool ksMatrix4x4f_IsOrthogonal( const ksMatrix4x4f * matrix, const float epsilon ) -{ - for ( int i = 0; i < 3; i++ ) - { - for ( int j = 0; j < 3; j++ ) - { - if ( i != j ) - { - if ( fabsf( matrix->m[i][0] * matrix->m[j][0] + matrix->m[i][1] * matrix->m[j][1] + matrix->m[i][2] * matrix->m[j][2] ) > epsilon ) - { - return false; - } - if ( fabsf( matrix->m[0][i] * matrix->m[0][j] + matrix->m[1][i] * matrix->m[1][j] + matrix->m[2][i] * matrix->m[2][j] ) > epsilon ) - { - return false; - } - } - } - } - return true; -} - -// Returns true if the given matrix is orthonormal. -static inline bool ksMatrix4x4f_IsOrthonormal( const ksMatrix4x4f * matrix, const float epsilon ) -{ - for ( int i = 0; i < 3; i++ ) - { - for ( int j = 0; j < 3; j++ ) - { - const float kd = ( i == j ) ? 1.0f : 0.0f; // Kronecker delta - if ( fabsf( kd - ( matrix->m[i][0] * matrix->m[j][0] + matrix->m[i][1] * matrix->m[j][1] + matrix->m[i][2] * matrix->m[j][2] ) ) > epsilon ) - { - return false; - } - if ( fabsf( kd - ( matrix->m[0][i] * matrix->m[0][j] + matrix->m[1][i] * matrix->m[1][j] + matrix->m[2][i] * matrix->m[2][j] ) ) > epsilon ) - { - return false; - } - } - } - return true; -} - -// Returns true if the given matrix is homogeneous. -static inline bool ksMatrix4x4f_IsHomogeneous( const ksMatrix4x4f * matrix, const float epsilon ) -{ - return ksMatrix4x4f_IsAffine( matrix, epsilon ) && ksMatrix4x4f_IsOrthonormal( matrix, epsilon ); -} - -// Get the translation from a combined translation(rotation(scale(object))) matrix. -static inline void ksMatrix4x4f_GetTranslation( ksVector3f * result, const ksMatrix4x4f * src ) -{ - assert( ksMatrix4x4f_IsAffine( src, 1e-4f ) ); - assert( ksMatrix4x4f_IsOrthogonal( src, 1e-4f ) ); - - result->x = src->m[3][0]; - result->y = src->m[3][1]; - result->z = src->m[3][2]; -} - -// Get the rotation from a combined translation(rotation(scale(object))) matrix. -static inline void ksMatrix4x4f_GetRotation( ksQuatf * result, const ksMatrix4x4f * src ) -{ - assert( ksMatrix4x4f_IsAffine( src, 1e-4f ) ); - assert( ksMatrix4x4f_IsOrthogonal( src, 1e-4f ) ); - - const float rcpScaleX = ksRcpSqrt( src->m[0][0] * src->m[0][0] + src->m[0][1] * src->m[0][1] + src->m[0][2] * src->m[0][2] ); - const float rcpScaleY = ksRcpSqrt( src->m[1][0] * src->m[1][0] + src->m[1][1] * src->m[1][1] + src->m[1][2] * src->m[1][2] ); - const float rcpScaleZ = ksRcpSqrt( src->m[2][0] * src->m[2][0] + src->m[2][1] * src->m[2][1] + src->m[2][2] * src->m[2][2] ); - const float m[9] = - { - src->m[0][0] * rcpScaleX, src->m[0][1] * rcpScaleX, src->m[0][2] * rcpScaleX, - src->m[1][0] * rcpScaleY, src->m[1][1] * rcpScaleY, src->m[1][2] * rcpScaleY, - src->m[2][0] * rcpScaleZ, src->m[2][1] * rcpScaleZ, src->m[2][2] * rcpScaleZ - }; - if ( m[0 * 3 + 0] + m[1 * 3 + 1] + m[2 * 3 + 2] > 0.0f ) - { - float t = + m[0 * 3 + 0] + m[1 * 3 + 1] + m[2 * 3 + 2] + 1.0f; - float s = ksRcpSqrt( t ) * 0.5f; - result->w = s * t; - result->z = ( m[0 * 3 + 1] - m[1 * 3 + 0] ) * s; - result->y = ( m[2 * 3 + 0] - m[0 * 3 + 2] ) * s; - result->x = ( m[1 * 3 + 2] - m[2 * 3 + 1] ) * s; - } - else if ( m[0 * 3 + 0] > m[1 * 3 + 1] && m[0 * 3 + 0] > m[2 * 3 + 2] ) - { - float t = + m[0 * 3 + 0] - m[1 * 3 + 1] - m[2 * 3 + 2] + 1.0f; - float s = ksRcpSqrt( t ) * 0.5f; - result->x = s * t; - result->y = ( m[0 * 3 + 1] + m[1 * 3 + 0] ) * s; - result->z = ( m[2 * 3 + 0] + m[0 * 3 + 2] ) * s; - result->w = ( m[1 * 3 + 2] - m[2 * 3 + 1] ) * s; - } - else if ( m[1 * 3 + 1] > m[2 * 3 + 2] ) - { - float t = - m[0 * 3 + 0] + m[1 * 3 + 1] - m[2 * 3 + 2] + 1.0f; - float s = ksRcpSqrt( t ) * 0.5f; - result->y = s * t; - result->x = ( m[0 * 3 + 1] + m[1 * 3 + 0] ) * s; - result->w = ( m[2 * 3 + 0] - m[0 * 3 + 2] ) * s; - result->z = ( m[1 * 3 + 2] + m[2 * 3 + 1] ) * s; - } - else - { - float t = - m[0 * 3 + 0] - m[1 * 3 + 1] + m[2 * 3 + 2] + 1.0f; - float s = ksRcpSqrt( t ) * 0.5f; - result->z = s * t; - result->w = ( m[0 * 3 + 1] - m[1 * 3 + 0] ) * s; - result->x = ( m[2 * 3 + 0] + m[0 * 3 + 2] ) * s; - result->y = ( m[1 * 3 + 2] + m[2 * 3 + 1] ) * s; - } -} - -// Get the scale from a combined translation(rotation(scale(object))) matrix. -static inline void ksMatrix4x4f_GetScale( ksVector3f * result, const ksMatrix4x4f * src ) -{ - assert( ksMatrix4x4f_IsAffine( src, 1e-4f ) ); - assert( ksMatrix4x4f_IsOrthogonal( src, 1e-4f ) ); - - result->x = sqrtf( src->m[0][0] * src->m[0][0] + src->m[0][1] * src->m[0][1] + src->m[0][2] * src->m[0][2] ); - result->y = sqrtf( src->m[1][0] * src->m[1][0] + src->m[1][1] * src->m[1][1] + src->m[1][2] * src->m[1][2] ); - result->z = sqrtf( src->m[2][0] * src->m[2][0] + src->m[2][1] * src->m[2][1] + src->m[2][2] * src->m[2][2] ); -} - -// Transforms a 3D vector. -static inline void ksMatrix4x4f_TransformVector3f( ksVector3f * result, const ksMatrix4x4f * m, const ksVector3f * v ) -{ - const float w = m->m[0][3] * v->x + m->m[1][3] * v->y + m->m[2][3] * v->z + m->m[3][3]; - const float rcpW = 1.0f / w; - result->x = ( m->m[0][0] * v->x + m->m[1][0] * v->y + m->m[2][0] * v->z + m->m[3][0] ) * rcpW; - result->y = ( m->m[0][1] * v->x + m->m[1][1] * v->y + m->m[2][1] * v->z + m->m[3][1] ) * rcpW; - result->z = ( m->m[0][2] * v->x + m->m[1][2] * v->y + m->m[2][2] * v->z + m->m[3][2] ) * rcpW; -} - -// Transforms a 4D vector. -static inline void ksMatrix4x4f_TransformVector4f( ksVector4f * result, const ksMatrix4x4f * m, const ksVector4f * v ) -{ - result->x = m->m[0][0] * v->x + m->m[1][0] * v->y + m->m[2][0] * v->z + m->m[3][0]; - result->y = m->m[0][1] * v->x + m->m[1][1] * v->y + m->m[2][1] * v->z + m->m[3][1]; - result->z = m->m[0][2] * v->x + m->m[1][2] * v->y + m->m[2][2] * v->z + m->m[3][2]; - result->w = m->m[0][3] * v->x + m->m[1][3] * v->y + m->m[2][3] * v->z + m->m[3][3]; -} - -// Transforms the 'mins' and 'maxs' bounds with the given 'matrix'. -static inline void ksMatrix4x4f_TransformBounds( ksVector3f * resultMins, ksVector3f * resultMaxs, const ksMatrix4x4f * matrix, const ksVector3f * mins, const ksVector3f * maxs ) -{ - assert( ksMatrix4x4f_IsAffine( matrix, 1e-4f ) ); - - const ksVector3f center = { ( mins->x + maxs->x ) * 0.5f, ( mins->y + maxs->y ) * 0.5f, ( mins->z + maxs->z ) * 0.5f }; - const ksVector3f extents = { maxs->x - center.x, maxs->y - center.y, maxs->z - center.z }; - const ksVector3f newCenter = - { - matrix->m[0][0] * center.x + matrix->m[1][0] * center.y + matrix->m[2][0] * center.z + matrix->m[3][0], - matrix->m[0][1] * center.x + matrix->m[1][1] * center.y + matrix->m[2][1] * center.z + matrix->m[3][1], - matrix->m[0][2] * center.x + matrix->m[1][2] * center.y + matrix->m[2][2] * center.z + matrix->m[3][2] - }; - const ksVector3f newExtents = - { - fabsf( extents.x * matrix->m[0][0] ) + fabsf( extents.y * matrix->m[1][0] ) + fabsf( extents.z * matrix->m[2][0] ), - fabsf( extents.x * matrix->m[0][1] ) + fabsf( extents.y * matrix->m[1][1] ) + fabsf( extents.z * matrix->m[2][1] ), - fabsf( extents.x * matrix->m[0][2] ) + fabsf( extents.y * matrix->m[1][2] ) + fabsf( extents.z * matrix->m[2][2] ) - }; - ksVector3f_Sub( resultMins, &newCenter, &newExtents ); - ksVector3f_Add( resultMaxs, &newCenter, &newExtents ); -} - -// Returns true if the 'mins' and 'maxs' bounds is completely off to one side of the projection matrix. -static inline bool ksMatrix4x4f_CullBounds( const ksMatrix4x4f * mvp, const ksVector3f * mins, const ksVector3f * maxs ) -{ - if ( maxs->x <= mins->x && maxs->y <= mins->y && maxs->z <= mins->z ) - { - return false; - } - - ksVector4f c[8]; - for ( int i = 0; i < 8; i++ ) - { - const ksVector4f corner = - { - ( i & 1 ) ? maxs->x : mins->x, - ( i & 2 ) ? maxs->y : mins->y, - ( i & 4 ) ? maxs->z : mins->z, - 1.0f - }; - ksMatrix4x4f_TransformVector4f( &c[i], mvp, &corner ); - } - - int i; - for ( i = 0; i < 8; i++ ) - { - if ( c[i].x > -c[i].w ) - { - break; - } - } - if ( i == 8 ) - { - return true; - } - for ( i = 0; i < 8; i++ ) - { - if ( c[i].x < c[i].w ) - { - break; - } - } - if ( i == 8 ) - { - return true; - } - - for ( i = 0; i < 8; i++ ) - { - if ( c[i].y > -c[i].w ) - { - break; - } - } - if ( i == 8 ) - { - return true; - } - for ( i = 0; i < 8; i++ ) - { - if ( c[i].y < c[i].w ) - { - break; - } - } - if ( i == 8 ) - { - return true; - } - for ( i = 0; i < 8; i++ ) - { - if ( c[i].z > -c[i].w ) - { - break; - } - } - if ( i == 8 ) - { - return true; - } - for ( i = 0; i < 8; i++ ) - { - if ( c[i].z < c[i].w ) - { - break; - } - } - if ( i == 8 ) - { - return true; - } - - return false; -} - -#endif // !KSALGEBRA_H diff --git a/external/include/utils/nanoseconds.h b/external/include/utils/nanoseconds.h deleted file mode 100644 index df201fb53..000000000 --- a/external/include/utils/nanoseconds.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -================================================================================================ - -Description : Time in nanoseconds. -Author : J.M.P. van Waveren -Date : 12/10/2016 -Language : C99 -Format : Real tabs with the tab size equal to 4 spaces. -Copyright : Copyright (c) 2016 Oculus VR, LLC. All Rights reserved. - - -LICENSE -======= - -Copyright (c) 2016 Oculus VR, LLC. - -SPDX-License-Identifier: Apache-2.0 - -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. - -================================================================================================ -*/ - -#if !defined( KSNANOSECONDS_H ) -#define KSNANOSECONDS_H - -#if defined( WIN32 ) || defined( _WIN32 ) || defined( WIN64 ) || defined( _WIN64 ) - #if !defined( OS_WINDOWS ) - #define OS_WINDOWS - #endif -#elif defined( __ANDROID__ ) - #if !defined( OS_ANDROID ) - #define OS_ANDROID - #endif -#elif defined( __hexagon__ ) || defined( __qdsp6__ ) - #if !defined( OS_HEXAGON ) - #define OS_HEXAGON - #endif -#elif defined( __APPLE__ ) - #if !defined( OS_APPLE ) - #define OS_APPLE - #endif - #include - #if __IPHONE_OS_VERSION_MAX_ALLOWED && !defined( OS_APPLE_IOS ) - #define OS_APPLE_IOS - #elif __MAC_OS_X_VERSION_MAX_ALLOWED && !defined( OS_APPLE_MACOS ) - #define OS_APPLE_MACOS - #endif -#elif defined( __linux__ ) - #if !defined( OS_LINUX ) - #define OS_LINUX - #endif -#else - #error "unknown platform" -#endif - -#if defined( OS_WINDOWS ) - #include -#elif defined( OS_LINUX ) - #include // for timespec - #include // for gettimeofday() -#elif defined( OS_APPLE ) - #include -#elif defined( OS_ANDROID ) - #include -#elif defined( OS_HEXAGON ) - #include -#endif - -#include - -typedef uint64_t ksNanoseconds; - -static ksNanoseconds GetTimeNanoseconds() -{ -#if defined( OS_WINDOWS ) - static ksNanoseconds ticksPerSecond = 0; - static ksNanoseconds timeBase = 0; - - if ( ticksPerSecond == 0 ) - { - LARGE_INTEGER li; - QueryPerformanceFrequency( &li ); - ticksPerSecond = (ksNanoseconds) li.QuadPart; - QueryPerformanceCounter( &li ); - timeBase = (ksNanoseconds) li.LowPart + 0xFFFFFFFFULL * li.HighPart; - } - - LARGE_INTEGER li; - QueryPerformanceCounter( &li ); - ksNanoseconds counter = (ksNanoseconds) li.LowPart + 0xFFFFFFFFULL * li.HighPart; - return ( counter - timeBase ) * 1000ULL * 1000ULL * 1000ULL / ticksPerSecond; -#elif defined( OS_ANDROID ) - static ksNanoseconds timeBase = 0; - - struct timespec ts; - clock_gettime( CLOCK_MONOTONIC, &ts ); - - if ( timeBase == 0 ) - { - timeBase = (ksNanoseconds) ts.tv_sec * 1000ULL * 1000ULL * 1000ULL + ts.tv_nsec; - } - - return (ksNanoseconds) ts.tv_sec * 1000ULL * 1000ULL * 1000ULL + ts.tv_nsec - timeBase; -#elif defined( OS_HEXAGON ) - return QURT_TIMER_TIMETICK_TO_US( qurt_timer_get_ticks() ) * 1000; -#else - static ksNanoseconds timeBase = 0; - - struct timeval tv; - gettimeofday( &tv, 0 ); - - if ( timeBase == 0 ) - { - timeBase = (ksNanoseconds) tv.tv_sec * 1000ULL * 1000ULL * 1000ULL + tv.tv_usec * 1000ULL; - } - - return (ksNanoseconds) tv.tv_sec * 1000ULL * 1000ULL * 1000ULL + tv.tv_usec * 1000ULL - timeBase; -#endif -} - -#endif // !KSNANOSECONDS_H diff --git a/external/include/utils/sysinfo.h b/external/include/utils/sysinfo.h deleted file mode 100644 index cb044be88..000000000 --- a/external/include/utils/sysinfo.h +++ /dev/null @@ -1,246 +0,0 @@ -/* -================================================================================================ - -Description : Basic system info. -Author : J.M.P. van Waveren -Date : 12/10/2016 -Language : C99 -Format : Real tabs with the tab size equal to 4 spaces. -Copyright : Copyright (c) 2016 Oculus VR, LLC. All Rights reserved. - - -LICENSE -======= - -Copyright (c) 2016 Oculus VR, LLC. - -SPDX-License-Identifier: Apache-2.0 - -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. - -================================================================================================ -*/ - -#if !defined( KSSYSINFO_H ) -#define KSSYSINFO_H - -#if defined( WIN32 ) || defined( _WIN32 ) || defined( WIN64 ) || defined( _WIN64 ) - #if !defined( OS_WINDOWS ) - #define OS_WINDOWS - #endif -#elif defined( __ANDROID__ ) - #if !defined( OS_ANDROID ) - #define OS_ANDROID - #endif -#elif defined( __hexagon__ ) || defined( __qdsp6__ ) - #if !defined( OS_HEXAGON ) - #define OS_HEXAGON - #endif -#elif defined( __APPLE__ ) - #if !defined( OS_APPLE ) - #define OS_APPLE - #endif - #include - #if __IPHONE_OS_VERSION_MAX_ALLOWED && !defined( OS_APPLE_IOS ) - #define OS_APPLE_IOS - #elif __MAC_OS_X_VERSION_MAX_ALLOWED && !defined( OS_APPLE_MACOS ) - #define OS_APPLE_MACOS - #endif -#elif defined( __linux__ ) - #if !defined( OS_LINUX ) - #define OS_LINUX - #endif -#else - #error "unknown platform" -#endif - -#if defined( OS_WINDOWS ) - #include -#elif defined( OS_APPLE ) - #include - #include -#elif defined( OS_ANDROID ) - #include // for dlopen -#endif - -#include - -static const char * GetOSVersion() -{ -#if defined( OS_WINDOWS ) - HKEY hKey = 0; - if ( RegOpenKeyA( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", &hKey ) == ERROR_SUCCESS ) - { - static char version[1024]; - DWORD version_length = sizeof( version ); - DWORD dwType = REG_SZ; - DWORD dwRet = RegQueryValueExA( hKey, "ProductName", NULL, &dwType, (LPBYTE)&version, &version_length ); - RegCloseKey( hKey ); - if ( dwRet == ERROR_SUCCESS ) - { - return version; - } - } - return "Microsoft Windows"; -#elif defined( OS_LINUX ) - static char buffer[1024]; - - FILE * os_release = fopen( "/etc/os-release", "r" ); - if ( os_release != NULL ) - { - while ( fgets( buffer, sizeof( buffer ), os_release ) ) - { - if ( strncmp( buffer, "PRETTY_NAME=", 12 ) == 0 ) - { - char * pretty_name = buffer + 12; - - // remove newline and enclosing quotes - while( pretty_name[0] == ' ' || - pretty_name[0] == '\t' || - pretty_name[0] == ':' || - pretty_name[0] == '\'' || - pretty_name[0] == '\"' ) - { - pretty_name++; - } - int last = strlen( pretty_name ) - 1; - while( last >= 0 && ( - pretty_name[last] == '\n' || - pretty_name[last] == '\'' || - pretty_name[last] == '\"' ) ) - { - pretty_name[last--] = '\0'; - } - return pretty_name; - } - } - - fclose( os_release ); - } - - return "Linux"; -#elif defined( OS_APPLE_MACOS ) - return [NSString stringWithFormat: @"Apple macOS %@", NSProcessInfo.processInfo.operatingSystemVersionString].UTF8String; -#elif defined( OS_APPLE_IOS ) - return [NSString stringWithFormat: @"Apple iOS %@", NSProcessInfo.processInfo.operatingSystemVersionString].UTF8String; -#elif defined( OS_ANDROID ) - static char version[1024]; - - #define PROP_NAME_MAX 32 - #define PROP_VALUE_MAX 92 - - char release[PROP_VALUE_MAX] = { 0 }; - char build[PROP_VALUE_MAX] = { 0 }; - - void * handle = dlopen( "libc.so", RTLD_NOLOAD ); - if ( handle != NULL ) - { - typedef int (*PFN_SYSTEM_PROP_GET)(const char *, char *); - PFN_SYSTEM_PROP_GET __my_system_property_get = (PFN_SYSTEM_PROP_GET)dlsym( handle, "__system_property_get" ); - if ( __my_system_property_get != NULL ) - { - __my_system_property_get( "ro.build.version.release", release ); - __my_system_property_get( "ro.build.version.incremental", build ); - } - } - - snprintf( version, sizeof( version ), "Android %s (%s)", release, build ); - - return version; -#endif -} - -static const char * GetCPUVersion() -{ -#if defined( OS_WINDOWS ) - HKEY hKey = 0; - if ( RegOpenKeyA( HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey ) == ERROR_SUCCESS ) - { - static char processor[1024]; - DWORD processor_length = sizeof( processor ); - DWORD dwType = REG_SZ; - DWORD dwRet = RegQueryValueExA( hKey, "ProcessorNameString", NULL, &dwType, (LPBYTE)&processor, &processor_length ); - RegCloseKey( hKey ); - if ( dwRet == ERROR_SUCCESS ) - { - return processor; - } - } - return "unknown"; -#elif defined( OS_APPLE ) - static char processor[1024]; - size_t processor_length = sizeof( processor ); - sysctlbyname( "machdep.cpu.brand_string", &processor, &processor_length, NULL, 0 ); - return processor; -#elif defined( OS_LINUX ) || defined( OS_ANDROID ) - struct - { - const char * key; - char value[1024]; - } keyValues[] = - { - { "model name", "" }, - { "Processor", "" }, - { "Hardware", "" } - }; - static char name[1024]; - - FILE * cpuinfo = fopen( "/proc/cpuinfo", "r" ); - if ( cpuinfo != NULL ) - { - char buffer[1024]; - while ( fgets( buffer, sizeof( buffer ), cpuinfo ) ) - { - for ( int i = 0; i < (int)( sizeof( keyValues ) / sizeof( keyValues[0] ) ); i++ ) - { - const size_t length = strlen( keyValues[i].key ); - if ( strncmp( buffer, keyValues[i].key, length ) == 0 ) - { - char * pretty_name = buffer + length; - - // remove newline and enclosing quotes - while( pretty_name[0] == ' ' || - pretty_name[0] == '\t' || - pretty_name[0] == ':' || - pretty_name[0] == '\'' || - pretty_name[0] == '\"' ) - { - pretty_name++; - } - int last = strlen( pretty_name ) - 1; - while( last >= 0 && ( - pretty_name[last] == '\n' || - pretty_name[last] == '\'' || - pretty_name[last] == '\"' ) ) - { - pretty_name[last--] = '\0'; - } - - strcpy( keyValues[i].value, pretty_name ); - break; - } - } - } - - fclose( cpuinfo ); - - snprintf( name, sizeof(name), "%s%s%s", keyValues[2].value, - ( keyValues[2].value[0] != '\0' ) ? " - " : "", - ( keyValues[0].value[0] != '\0' ) ? keyValues[0].value : keyValues[1].value ); - return name; - } - return "unknown"; -#endif -} - -#endif // !KSSYSINFO_H diff --git a/external/include/utils/threading.h b/external/include/utils/threading.h deleted file mode 100644 index 052a1033c..000000000 --- a/external/include/utils/threading.h +++ /dev/null @@ -1,982 +0,0 @@ -/* -================================================================================================ - -Description : Threading primitives. -Author : J.M.P. van Waveren -Date : 12/10/2016 -Language : C99 -Format : Real tabs with the tab size equal to 4 spaces. -Copyright : Copyright (c) 2016 Oculus VR, LLC. All Rights reserved. - - -LICENSE -======= - -Copyright (c) 2016 Oculus VR, LLC. - -SPDX-License-Identifier: Apache-2.0 - -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. - -================================================================================================ -*/ - -#if !defined( KSTHREADING_H ) -#define KSTHREADING_H - -#if defined( WIN32 ) || defined( _WIN32 ) || defined( WIN64 ) || defined( _WIN64 ) - #if !defined( OS_WINDOWS ) - #define OS_WINDOWS - #endif -#elif defined( __ANDROID__ ) - #if !defined( OS_ANDROID ) - #define OS_ANDROID - #endif -#elif defined( __hexagon__ ) || defined( __qdsp6__ ) - #if !defined( OS_HEXAGON ) - #define OS_HEXAGON - #endif -#elif defined( __APPLE__ ) - #if !defined( OS_APPLE ) - #define OS_APPLE - #endif - #include - #if __IPHONE_OS_VERSION_MAX_ALLOWED && !defined( OS_APPLE_IOS ) - #define OS_APPLE_IOS - #elif __MAC_OS_X_VERSION_MAX_ALLOWED && !defined( OS_APPLE_MACOS ) - #define OS_APPLE_MACOS - #endif -#elif defined( __linux__ ) - #if !defined( OS_LINUX ) - #define OS_LINUX - #endif -#else - #error "unknown platform" -#endif - -#if defined( OS_WINDOWS ) - #include -#elif defined( OS_LINUX ) - #include // for timespec - #include // for gettimeofday() - #include // for pthread_create() etc. -#elif defined( OS_APPLE ) - #include - #include -#elif defined( OS_ANDROID ) - #include - #include - #include - #include // for prctl( PR_SET_NAME ) - #include // for gettid - #include // for syscall -#elif defined( OS_HEXAGON ) - #include "qurt.h" - #include "qurt_atomic_ops.h" -#endif - -#include -#include "nanoseconds.h" - -#if !defined( UNUSED_PARM ) -#define UNUSED_PARM( x ) { (void)(x); } -#endif - -/* -================================================================================================================================ - -Atomic 32-bit unsigned integer - -================================================================================================================================ -*/ - -typedef unsigned int ksAtomicUint32; - -static ksAtomicUint32 ksAtomicUint32_Increment( ksAtomicUint32 * atomicUint32 ) -{ -#if defined( OS_WINDOWS ) - return (ksAtomicUint32) InterlockedIncrement( (LONG *)atomicUint32 ); -#elif defined( OS_HEXAGON ) - return qurt_atomic_inc_return( atomicUint32 ); -#else - return __sync_fetch_and_add( atomicUint32, 1 ); -#endif -} - -static ksAtomicUint32 ksAtomicUint32_Decrement( ksAtomicUint32 * atomicUint32 ) -{ -#if defined( OS_WINDOWS ) - return (ksAtomicUint32) InterlockedDecrement( (LONG *)atomicUint32 ); -#elif defined( OS_HEXAGON ) - return qurt_atomic_dec_return( atomicUint32 ); -#else - return __sync_fetch_and_add( atomicUint32, -1 ); -#endif -} - -/* -================================================================================================================================ - -Mutex for mutual exclusion on shared resources within a single process. - -Equivalent to a Windows Critical Section Object which allows recursive access. This mutex cannot be -used for mutual-exclusion synchronization between threads from different processes. - -ksMutex - -static void ksMutex_Create( ksMutex * mutex ); -static void ksMutex_Destroy( ksMutex * mutex ); -static bool ksMutex_Lock( ksMutex * mutex, const bool blocking ); -static void ksMutex_Unlock( ksMutex * mutex ); - -================================================================================================================================ -*/ - -typedef struct -{ -#if defined( OS_WINDOWS ) - CRITICAL_SECTION handle; -#elif defined( OS_HEXAGON ) - qurt_mutex_t mutex; -#else - pthread_mutex_t mutex; -#endif -} ksMutex; - -static void ksMutex_Create( ksMutex * mutex ) -{ -#if defined( OS_WINDOWS ) - InitializeCriticalSection( &mutex->handle ); -#elif defined( OS_HEXAGON ) - qurt_rmutex_init( &mutex->mutex ); -#else - pthread_mutexattr_t attr; - pthread_mutexattr_init( &attr ); - pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE ); - pthread_mutex_init( &mutex->mutex, &attr ); -#endif -} - -static void ksMutex_Destroy( ksMutex * mutex ) -{ -#if defined( OS_WINDOWS ) - DeleteCriticalSection( &mutex->handle ); -#elif defined( OS_HEXAGON ) - qurt_rmutex_destroy( &mutex->mutex ); -#else - pthread_mutex_destroy( &mutex->mutex ); -#endif -} - -static bool ksMutex_Lock( ksMutex * mutex, const bool blocking ) -{ -#if defined( OS_WINDOWS ) - if ( TryEnterCriticalSection( &mutex->handle ) == 0 ) - { - if ( !blocking ) - { - return false; - } - EnterCriticalSection( &mutex->handle ); - } - return true; -#elif defined( OS_HEXAGON ) - if ( qurt_rmutex_try_lock( &mutex->mutex ) != 0 ) - { - if ( !blocking ) - { - return false; - } - qurt_rmutex_lock( &mutex->mutex ); - } - return true; -#else - if ( pthread_mutex_trylock( &mutex->mutex ) == EBUSY ) - { - if ( !blocking ) - { - return false; - } - pthread_mutex_lock( &mutex->mutex ); - } - return true; -#endif -} - -static void ksMutex_Unlock( ksMutex * mutex ) -{ -#if defined( OS_WINDOWS ) - LeaveCriticalSection( &mutex->handle ); -#elif defined( OS_HEXAGON ) - qurt_rmutex_unlock( &mutex->mutex ); -#else - pthread_mutex_unlock( &mutex->mutex ); -#endif -} - -/* -================================================================================================================================ - -Signal for thread synchronization, similar to a Windows event object which only supports SetEvent. - -Windows event objects come in two types: auto-reset events and manual-reset events. A Windows event object -can be signalled by calling either SetEvent or PulseEvent. - -When a manual-reset event is signaled by calling SetEvent, it sets the event into the signaled state and -wakes up all threads waiting on the event. The manual-reset event remains in the signalled state until -the event is manually reset. When an auto-reset event is signaled by calling SetEvent and there are any -threads waiting, it wakes up only one thread and resets the event to the non-signaled state. If there are -no threads waiting for an auto-reset event, then the event remains signaled until a single waiting thread -waits on it and is released. - -When a manual-reset event is signaled by calling PulseEvent, it wakes up all waiting threads and atomically -resets the event. When an auto-reset event is signaled by calling PulseEvent, and there are any threads -waiting, it wakes up only one thread and resets the event to the non-signaled state. If there are no threads -waiting, then no threads are released and the event is set to the non-signaled state. - -A Windows event object has limited functionality compared to a POSIX condition variable. Unlike a -Windows event object, the expression waited upon by a POSIX condition variable can be arbitrarily complex. -Furthermore, there is no way to release just one waiting thread with a manual-reset Windows event object. -Similarly there is no way to release all waiting threads with an auto-reset Windows event object. -These limitations make it difficult to simulate a POSIX condition variable using Windows event objects. - -Windows Vista and later implement PCONDITION_VARIABLE, but as Douglas C. Schmidt and Irfan Pyarali point -out, it is complicated to simulate a POSIX condition variable on prior versions of Windows without causing -unfair or even incorrect behavior: - - 1. "Strategies for Implementing POSIX Condition Variables on Win32" - http://www.cs.wustl.edu/~schmidt/win32-cv-1.html - 2. "Patterns for POSIX Condition Variables on Win32" - http://www.cs.wustl.edu/~schmidt/win32-cv-2.html - -Even using SignalObjectAndWait is not safe because as per the Microsoft documentation: "Note that the 'signal' -and 'wait' are not guaranteed to be performed as an atomic operation. Threads executing on other processors -can observe the signaled state of the first object before the thread calling SignalObjectAndWait begins its -wait on the second object." - -Simulating a Windows event object using a POSIX condition variable is fairly straight forward, which -is done here. However, this implementation does not support the equivalent of PulseEvent, because -PulseEvent is unreliable. On Windows, a thread waiting on an event object can be momentarily removed -from the wait state by a kernel-mode Asynchronous Procedure Call (APC), and then returned to the wait -state after the APC is complete. If a call to PulseEvent occurs during the time when the thread has -been temporarily removed from the wait state, then the thread will not be released, because PulseEvent -releases only those threads that are in the wait state at the moment PulseEvent is called. - -ksSignal - -static void ksSignal_Create( ksSignal * signal, const bool autoReset ); -static void ksSignal_Destroy( ksSignal * signal ); -static bool ksSignal_Wait( ksSignal * signal, const ksNanoseconds timeOutNanoseconds ); -static void ksSignal_Raise( ksSignal * signal ); -static void ksSignal_Clear( ksSignal * signal ); - -================================================================================================================================ -*/ - -#define SIGNAL_TIMEOUT_INFINITE 0xFFFFFFFFFFFFFFFFULL - -typedef struct -{ -#if defined( OS_WINDOWS ) - HANDLE handle; -#elif defined( OS_HEXAGON ) - qurt_mutex_t mutex; - qurt_cond_t cond; - int waitCount; // number of threads waiting on the signal - bool autoReset; // automatically clear the signalled state when a single thread is released - bool signaled; // in the signalled state if true -#else - pthread_mutex_t mutex; - pthread_cond_t cond; - int waitCount; // number of threads waiting on the signal - bool autoReset; // automatically clear the signalled state when a single thread is released - bool signaled; // in the signalled state if true -#endif -} ksSignal; - -static void ksSignal_Create( ksSignal * signal, const bool autoReset ) -{ -#if defined( OS_WINDOWS ) - signal->handle = CreateEventA( NULL, !autoReset, FALSE, NULL ); -#elif defined( OS_HEXAGON ) - qurt_mutex_init( &signal->mutex ); - qurt_cond_init( &signal->cond ); - signal->waitCount = 0; - signal->autoReset = autoReset; - signal->signaled = false; -#else - pthread_mutex_init( &signal->mutex, NULL ); - pthread_cond_init( &signal->cond, NULL ); - signal->waitCount = 0; - signal->autoReset = autoReset; - signal->signaled = false; -#endif -} - -static void ksSignal_Destroy( ksSignal * signal ) -{ -#if defined( OS_WINDOWS ) - CloseHandle( signal->handle ); -#elif defined( OS_HEXAGON ) - qurt_cond_destroy( &signal->cond ); - qurt_mutex_destroy( &signal->mutex ); -#else - pthread_cond_destroy( &signal->cond ); - pthread_mutex_destroy( &signal->mutex ); -#endif -} - -// Waits for the object to enter the signalled state and returns true if this state is reached within the time-out period. -// If 'autoReset' is true then the first thread that reaches the signalled state within the time-out period will clear the signalled state. -// If 'timeOutNanoseconds' is SIGNAL_TIMEOUT_INFINITE then this will wait indefinitely until the signalled state is reached. -// Returns true if the thread was released because the object entered the signalled state, returns false if the time-out is reached first. -static bool ksSignal_Wait( ksSignal * signal, const ksNanoseconds timeOutNanoseconds ) -{ -#if defined( OS_WINDOWS ) - DWORD result = WaitForSingleObject( signal->handle, ( timeOutNanoseconds == SIGNAL_TIMEOUT_INFINITE ) ? INFINITE : (DWORD)( timeOutNanoseconds / ( 1000 * 1000 ) ) ); - assert( result == WAIT_OBJECT_0 || ( timeOutNanoseconds != SIGNAL_TIMEOUT_INFINITE && result == WAIT_TIMEOUT ) ); - return ( result == WAIT_OBJECT_0 ); -#elif defined( OS_HEXAGON ) - bool released = false; - qurt_mutex_lock( &signal->mutex ); - if ( signal->signaled ) - { - released = true; - } - else - { - signal->waitCount++; - if ( timeOutMicroseconds == SIGNAL_TIMEOUT_INFINITE ) - { - do - { - qurt_cond_wait( &signal->cond, &signal->mutex ); - // Re-check condition in case qurt_cond_wait spuriously woke up. - } while ( signal->signaled == false ); - } - else if ( timeOutMicroseconds > 0 ) - { - // No support for a time-out other than zero. - //assert( false ); - } - released = signal->signaled; - signal->waitCount--; - } - if ( released && signal->autoReset ) - { - signal->signaled = false; - } - qurt_mutex_unlock( &signal->mutex ); - return released; -#else - bool released = false; - pthread_mutex_lock( &signal->mutex ); - if ( signal->signaled ) - { - released = true; - } - else - { - signal->waitCount++; - if ( timeOutNanoseconds == SIGNAL_TIMEOUT_INFINITE ) - { - do - { - pthread_cond_wait( &signal->cond, &signal->mutex ); - // Must re-check condition because pthread_cond_wait may spuriously wake up. - } while ( signal->signaled == false ); - } - else if ( timeOutNanoseconds > 0 ) - { - struct timeval tp; - gettimeofday( &tp, NULL ); - struct timespec ts; - ts.tv_sec = (time_t)( tp.tv_sec + timeOutNanoseconds / ( 1000 * 1000 * 1000 ) ); - ts.tv_nsec = (long)( tp.tv_usec + ( timeOutNanoseconds % ( 1000 * 1000 * 1000 ) ) ); - do - { - if ( pthread_cond_timedwait( &signal->cond, &signal->mutex, &ts ) == ETIMEDOUT ) - { - break; - } - // Must re-check condition because pthread_cond_timedwait may spuriously wake up. - } while ( signal->signaled == false ); - } - released = signal->signaled; - signal->waitCount--; - } - if ( released && signal->autoReset ) - { - signal->signaled = false; - } - pthread_mutex_unlock( &signal->mutex ); - return released; -#endif -} - -// Enter the signalled state. -// Note that if 'autoReset' is true then this will only release a single thread. -static void ksSignal_Raise( ksSignal * signal ) -{ -#if defined( OS_WINDOWS ) - SetEvent( signal->handle ); -#elif defined( OS_HEXAGON ) - qurt_mutex_lock( &signal->mutex ); - signal->signaled = true; - if ( signal->waitCount > 0 ) - { - qurt_cond_broadcast( &signal->cond ); - } - qurt_mutex_unlock( &signal->mutex ); -#else - pthread_mutex_lock( &signal->mutex ); - signal->signaled = true; - if ( signal->waitCount > 0 ) - { - pthread_cond_broadcast( &signal->cond ); - } - pthread_mutex_unlock( &signal->mutex ); -#endif -} - -// Clear the signalled state. -// Should not be needed for auto-reset signals (autoReset == true). -static void ksSignal_Clear( ksSignal * signal ) -{ -#if defined( OS_WINDOWS ) - ResetEvent( signal->handle ); -#elif defined( OS_HEXAGON ) - qurt_mutex_lock( &signal->mutex ); - signal->signaled = false; - qurt_mutex_unlock( &signal->mutex ); -#else - pthread_mutex_lock( &signal->mutex ); - signal->signaled = false; - pthread_mutex_unlock( &signal->mutex ); -#endif -} - -/* -================================================================================================================================ - -Worker thread. - -When the thread is first created, it will be in a suspended state. The thread function will be -called as soon as the thread is signalled. If the thread is not signalled again, then the thread -will return to a suspended state as soon as the thread function returns. The thread function will -be called again by signalling the thread again. The thread function will be called again right -away, when the thread is signalled during the execution of the thread function. Signalling the -thread more than once during the execution of the thread function does not cause the thread -function to be called multiple times. The thread can be joined to wait for the thread function -to return. - -This worker thread will function as a normal thread by immediately signalling the thread after creation. -Once the thread function returns, the thread can be destroyed. Destroying the thread always waits -for the thread function to return first. - -ksThread - -static bool ksThread_Create( ksThread * thread, const char * threadName, ksThreadFunction threadFunction, void * threadData ); -static void ksThread_Destroy( ksThread * thread ); -static void ksThread_Signal( ksThread * thread ); -static void ksThread_Join( ksThread * thread ); -static void ksThread_Submit( ksThread * thread, ksThreadFunction threadFunction, void * threadData ); - -// These must be called from the thread itself. -static void ksThread_SetName( const char * name ); -static void ksThread_SetAffinity( int mask ); -static void ksThread_SetRealTimePriority( int priority ); - -================================================================================================================================ -*/ - -typedef void (*ksThreadFunction)( void * data ); - -#if defined( OS_WINDOWS ) -#define THREAD_HANDLE HANDLE -#define THREAD_RETURN_TYPE int -#define THREAD_RETURN_VALUE 0 -#elif defined( OS_HEXAGON ) -#define THREAD_HANDLE qurt_thread_t -#define THREAD_RETURN_TYPE void -#define THREAD_RETURN_VALUE -#else -#define THREAD_HANDLE pthread_t -#define THREAD_RETURN_TYPE void * -#define THREAD_RETURN_VALUE 0 -#endif - -#define THREAD_AFFINITY_BIG_CORES -1 - -typedef struct -{ - char threadName[128]; - ksThreadFunction threadFunction; - void * threadData; - - void * stack; - THREAD_HANDLE handle; - ksSignal workIsDone; - ksSignal workIsAvailable; - ksMutex workMutex; - volatile bool terminate; -} ksThread; - -// Note that on Android AttachCurrentThread will reset the thread name. -static void ksThread_SetName( const char * name ) -{ - (void)name; -#if defined( OS_WINDOWS ) && !defined(__MINGW32__) - static const unsigned int MS_VC_EXCEPTION = 0x406D1388; - -#pragma pack( push, 8 ) - typedef struct - { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user address space). - DWORD dwThreadID; // Thread ID (-1 = caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. - } THREADNAME_INFO; -#pragma pack( pop ) - - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = name; - info.dwThreadID = (DWORD)( -1 ); - info.dwFlags = 0; - __try - { - RaiseException( MS_VC_EXCEPTION, 0, sizeof( info ) / sizeof( ULONG_PTR ), (const ULONG_PTR *)&info ); - } - __except( GetExceptionCode() == MS_VC_EXCEPTION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH ) - { - info.dwFlags = 0; - } -#elif defined( OS_LINUX ) - pthread_setname_np( pthread_self(), name ); -#elif defined( OS_APPLE ) - pthread_setname_np( name ); -#elif defined( OS_ANDROID ) - prctl( PR_SET_NAME, (long)name, 0, 0, 0 ); -#endif -} - -static void ksThread_SetAffinity( int mask ) -{ -#if defined( OS_WINDOWS ) - if ( mask == THREAD_AFFINITY_BIG_CORES ) - { - return; - } - HANDLE thread = GetCurrentThread(); - if ( !SetThreadAffinityMask( thread, mask ) ) - { - char buffer[1024]; - DWORD error = GetLastError(); - FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), buffer, sizeof( buffer ), NULL ); - printf( "Failed to set thread %p affinity: %s(%lu)\n", thread, buffer, error ); - } - else - { - printf( "Thread %p affinity set to 0x%02X\n", thread, mask ); - } -#elif defined( OS_LINUX ) - if ( mask == THREAD_AFFINITY_BIG_CORES ) - { - return; - } - cpu_set_t set; - memset( &set, 0, sizeof( cpu_set_t ) ); - for ( int bit = 0; bit < 32; bit++ ) - { - if ( ( mask & ( 1 << bit ) ) != 0 ) - { - set.__bits[bit / sizeof( set.__bits[0] )] |= 1 << ( bit & ( sizeof( set.__bits[0] ) - 1 ) ); - } - } - const int result = pthread_setaffinity_np( pthread_self(), sizeof( cpu_set_t ), &set ); - if ( result != 0 ) - { - printf( "Failed to set thread %d affinity.\n", (unsigned int)pthread_self() ); - } - else - { - printf( "Thread %d affinity set to 0x%02X\n", (unsigned int)pthread_self(), mask ); - } -#elif defined( OS_APPLE ) - // macOS and iOS do not export interfaces that identify processors or control thread placement. - UNUSED_PARM( mask ); -#elif defined( OS_ANDROID ) - // Optionally use the faster cores of a heterogeneous CPU. - if ( mask == THREAD_AFFINITY_BIG_CORES ) - { - mask = 0; - unsigned int bestFrequency = 0; - for ( int i = 0; i < 16; i++ ) - { - unsigned int maxFrequency = 0; - const char * files[] = - { - "scaling_available_frequencies", // not available on all devices - "scaling_max_freq", // no user read permission on all devices - "cpuinfo_max_freq", // could be set lower than the actual max, but better than nothing - }; - for ( unsigned int j = 0; j < ( sizeof(files) / sizeof(files[0]) ); j++ ) - { - char fileName[1024]; - sprintf( fileName, "/sys/devices/system/cpu/cpu%d/cpufreq/%s", i, files[j] ); - FILE * fp = fopen( fileName, "r" ); - if ( fp == NULL ) - { - continue; - } - char buffer[1024]; - if ( fgets( buffer, sizeof( buffer ), fp ) == NULL ) - { - fclose( fp ); - continue; - } - for ( int index = 0; buffer[index] != '\0'; ) - { - const unsigned int frequency = atoi( buffer + index ); - maxFrequency = ( frequency > maxFrequency ) ? frequency : maxFrequency; - while ( isspace( buffer[index] ) ) { index++; } - while ( isdigit( buffer[index] ) ) { index++; } - } - fclose( fp ); - break; - } - if ( maxFrequency == 0 ) - { - break; - } - - if ( maxFrequency == bestFrequency ) - { - mask |= ( 1 << i ); - } - else if ( maxFrequency > bestFrequency ) - { - mask = ( 1 << i ); - bestFrequency = maxFrequency; - } - } - - if ( mask == 0 ) - { - return; - } - } - - // Set the thread affinity. - pid_t pid = gettid(); - int syscallres = syscall( __NR_sched_setaffinity, pid, sizeof( mask ), &mask ); - if ( syscallres ) - { - int err = errno; - printf( " Error sched_setaffinity(%d): thread=(%d) mask=0x%X err=%s(%d)\n", __NR_sched_setaffinity, pid, mask, strerror( err ), err ); - } - else - { - printf( " Thread %d affinity 0x%02X\n", pid, mask ); - } -#else - UNUSED_PARM( mask ); -#endif -} - -static void ksThread_SetRealTimePriority( int priority ) -{ -#if defined( OS_WINDOWS ) - UNUSED_PARM( priority ); - HANDLE process = GetCurrentProcess(); - if( !SetPriorityClass( process, REALTIME_PRIORITY_CLASS ) ) - { - char buffer[1024]; - DWORD error = GetLastError(); - FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), buffer, sizeof( buffer ), NULL ); - printf( "Failed to set process %p priority class: %s(%lu)\n", process, buffer, error ); - } - else - { - printf( "Process %p priority class set to real-time.\n", process ); - } - HANDLE thread = GetCurrentThread(); - if ( !SetThreadPriority( thread, THREAD_PRIORITY_TIME_CRITICAL ) ) - { - char buffer[1024]; - DWORD error = GetLastError(); - FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), buffer, sizeof( buffer ), NULL ); - printf( "Failed to set thread %p priority: %s(%lu)\n", thread, buffer, error ); - } - else - { - printf( "Thread %p priority set to critical.\n", thread ); - } -#elif defined( OS_LINUX ) || defined( OS_APPLE ) - struct sched_param sp; - memset( &sp, 0, sizeof( struct sched_param ) ); - sp.sched_priority = priority; - if ( pthread_setschedparam( pthread_self(), SCHED_FIFO, &sp ) == -1 ) - { - printf( "Failed to change thread %llu priority.\n", (unsigned long long)pthread_self() ); - } - else - { - printf( "Thread %llu set to SCHED_FIFO, priority=%d\n", (unsigned long long)pthread_self(), priority ); - } -#elif defined( OS_ANDROID ) - struct sched_attr - { - uint32_t size; - uint32_t sched_policy; - uint64_t sched_flags; - int32_t sched_nice; - uint32_t sched_priority; - uint64_t sched_runtime; - uint64_t sched_deadline; - uint64_t sched_period; - } attr; - - memset( &attr, 0, sizeof( attr ) ); - attr.size = sizeof( attr ); - attr.sched_policy = SCHED_FIFO; - attr.sched_flags = SCHED_FLAG_RESET_ON_FORK; - attr.sched_nice = 0; // (SCHED_OTHER, SCHED_BATCH) - attr.sched_priority = priority; // (SCHED_FIFO, SCHED_RR) - attr.sched_runtime = 0; // (SCHED_DEADLINE) - attr.sched_deadline = 0; // (SCHED_DEADLINE) - attr.sched_period = 0; // (SCHED_DEADLINE) - - unsigned int flags = 0; - - pid_t pid = gettid(); - int syscallres = syscall( __NR_sched_setattr, pid, &attr, flags ); - if ( syscallres ) - { - int err = errno; - printf( " Error sched_setattr(%d): thread=%d err=%s(%d)\n", __NR_sched_setattr, pid, strerror( err ), err ); - } - else - { - printf( " Thread %d set to SCHED_FIFO, priority=%d\n", pid, priority ); - } -#else - UNUSED_PARM( priority ); -#endif -} - -static THREAD_RETURN_TYPE ThreadFunctionInternal( void * data ) -{ - ksThread * thread = (ksThread *)data; - - ksThread_SetName( thread->threadName ); - - for ( ; ; ) - { - ksMutex_Lock( &thread->workMutex, true ); - if ( ksSignal_Wait( &thread->workIsAvailable, 0 ) ) - { - ksMutex_Unlock( &thread->workMutex ); - } - else - { - ksSignal_Raise( &thread->workIsDone ); - ksMutex_Unlock( &thread->workMutex ); - ksSignal_Wait( &thread->workIsAvailable, SIGNAL_TIMEOUT_INFINITE ); - } - if ( thread->terminate ) - { - ksSignal_Raise( &thread->workIsDone ); - break; - } - thread->threadFunction( thread->threadData ); - } - return THREAD_RETURN_VALUE; -} - -static bool ksThread_Create( ksThread * thread, const char * threadName, ksThreadFunction threadFunction, void * threadData ) -{ -#if defined( OS_WINDOWS ) - strncpy_s( thread->threadName, sizeof( thread->threadName ), threadName, sizeof( thread->threadName ) ); -#else - strncpy( thread->threadName, threadName, sizeof( thread->threadName ) ); -#endif - thread->threadName[sizeof( thread->threadName ) - 1] = '\0'; - thread->threadFunction = threadFunction; - thread->threadData = threadData; - thread->stack = NULL; - ksSignal_Create( &thread->workIsDone, false ); - ksSignal_Create( &thread->workIsAvailable, true ); - ksMutex_Create( &thread->workMutex ); - thread->terminate = false; - -#if defined( OS_WINDOWS ) - const int stackSize = 512 * 1024; - DWORD threadID; - thread->handle = CreateThread( NULL, stackSize, (LPTHREAD_START_ROUTINE)ThreadFunctionInternal, thread, STACK_SIZE_PARAM_IS_A_RESERVATION, &threadID ); - if ( thread->handle == 0 ) - { - return false; - } -#elif defined( OS_HEXAGON ) - const int stackSize = 16 * 1024; - thread->stack = malloc( stackSize + 128 ); - void * aligned = (void *)( ( (size_t)thread->stack + 127 ) & ~127 ); - qurt_thread_attr_t attr; - qurt_thread_attr_init( &attr ); - qurt_thread_attr_set_name( &attr, (char *)threadName ); - qurt_thread_attr_set_stack_addr( &attr, aligned ); - qurt_thread_attr_set_stack_size( &attr, stackSize ); - qurt_thread_attr_set_priority( &attr, qurt_thread_get_priority( qurt_thread_get_id() ) ); - int ret = qurt_thread_create( &thread->handle, &attr, ThreadFunctionInternal, (void *)thread ); - if ( ret != 0 ) - { - return false; - } -#else - const int stackSize = 512 * 1024; - pthread_attr_t attr; - pthread_attr_init( &attr ); - pthread_attr_setstacksize( &attr, stackSize ); - int ret = pthread_create( &thread->handle, &attr, ThreadFunctionInternal, thread ); - if ( ret != 0 ) - { - return false; - } - pthread_attr_destroy( &attr ); -#endif - - ksSignal_Wait( &thread->workIsDone, SIGNAL_TIMEOUT_INFINITE ); - return true; -} - -static void ksThread_Destroy( ksThread * thread ) -{ - ksMutex_Lock( &thread->workMutex, true ); - ksSignal_Clear( &thread->workIsDone ); - thread->terminate = true; - ksSignal_Raise( &thread->workIsAvailable ); - ksMutex_Unlock( &thread->workMutex ); - ksSignal_Wait( &thread->workIsDone, SIGNAL_TIMEOUT_INFINITE ); - ksMutex_Destroy( &thread->workMutex ); - ksSignal_Destroy( &thread->workIsDone ); - ksSignal_Destroy( &thread->workIsAvailable ); -#if defined( OS_WINDOWS ) - WaitForSingleObject( thread->handle, INFINITE ); - CloseHandle( thread->handle ); -#elif defined( OS_HEXAGON ) - int status = 0; - qurt_thread_join( thread->handle, &status ); - free( thread->stack ); -#else - pthread_join( thread->handle, NULL ); -#endif -} - -static void ksThread_Signal( ksThread * thread ) -{ - ksMutex_Lock( &thread->workMutex, true ); - ksSignal_Clear( &thread->workIsDone ); - ksSignal_Raise( &thread->workIsAvailable ); - ksMutex_Unlock( &thread->workMutex ); -} - -static void ksThread_Join( ksThread * thread ) -{ - ksSignal_Wait( &thread->workIsDone, SIGNAL_TIMEOUT_INFINITE ); -} - -static void ksThread_Submit( ksThread * thread, ksThreadFunction threadFunction, void * threadData ) -{ - ksThread_Join( thread ); - thread->threadFunction = threadFunction; - thread->threadData = threadData; - ksThread_Signal( thread ); -} - -/* -================================================================================================================================ - -Worker thread pool. - -ksThreadPool - -static bool ksThreadPool_Create( ksThreadPool * pool, const int numWorkers ); -static void ksThreadPool_Destroy( ksThreadPool * pool ); -static void ksThreadPool_Submit( ksThreadPool * pool, ksThreadFunction threadFunction, void * threadData ); -static void ksThreadPool_Join( ksThreadPool * pool ); - -================================================================================================================================ -*/ - -#define MAX_WORKERS 8 - -typedef struct -{ - ksThread threads[MAX_WORKERS]; - int threadCount; -} ksThreadPool; - -static void PoolThreadStartFuntion( void * data ) -{ - UNUSED_PARM( data ); - - ksThread_SetAffinity( THREAD_AFFINITY_BIG_CORES ); - ksThread_SetRealTimePriority( 1 ); -} - -static void ksThreadPool_Create( ksThreadPool * pool, const int numWorkers ) -{ - pool->threadCount = ( numWorkers <= MAX_WORKERS ) ? numWorkers : MAX_WORKERS; -#if defined( OS_HEXAGON ) - qurt_sysenv_max_hthreads_t num_threads; - if ( qurt_sysenv_get_max_hw_threads( &num_threads ) == QURT_EOK ) - { - pool->threadCount = num_threads.max_hthreads; - } -#endif - - for ( int i = 0; i < pool->threadCount; i++ ) - { - ksThread_Create( &pool->threads[i], "worker", PoolThreadStartFuntion, NULL ); - ksThread_Signal( &pool->threads[i] ); - ksThread_Join( &pool->threads[i] ); - } -} - -static void ksThreadPool_Destroy( ksThreadPool * pool ) -{ - for ( int i = 0; i < pool->threadCount; i++ ) - { - ksThread_Destroy( &pool->threads[i] ); - } -} - -static void ksThreadPool_Submit( ksThreadPool * pool, ksThreadFunction threadFunction, void * threadData ) -{ - for ( int i = 0; i < pool->threadCount; i++ ) - { - ksThread_Submit( &pool->threads[i], threadFunction, threadData ); - } -} - -static void ksThreadPool_Join( ksThreadPool * pool ) -{ - for ( int i = 0; i < pool->threadCount; i++ ) - { - ksThread_Join( &pool->threads[i] ); - } -} - -#endif // !KSTHREADING_H diff --git a/github/sdk/.github/pull_request_template.md b/github/sdk/.github/pull_request_template.md new file mode 100644 index 000000000..2c1c1a32a --- /dev/null +++ b/github/sdk/.github/pull_request_template.md @@ -0,0 +1,6 @@ + +This is a derived repository, please open a corresponding pull request at [OpenXR-SDK-Source](https://github.com/KhronosGroup/OpenXR-SDK-Source) diff --git a/github/sdk/README.md b/github/sdk/README.md index 907a9c9be..c3cd2289b 100644 --- a/github/sdk/README.md +++ b/github/sdk/README.md @@ -1,7 +1,7 @@ # OpenXR™ Software Development Kit (SDK) Project diff --git a/include/generated_header_list.txt.license b/include/generated_header_list.txt.license index bbd5892c6..f19e71604 100644 --- a/include/generated_header_list.txt.license +++ b/include/generated_header_list.txt.license @@ -1,4 +1,4 @@ -Copyright (c) 2017-2022, The Khronos Group Inc. +Copyright (c) 2017-2023, The Khronos Group Inc. SPDX-License-Identifier: Apache-2.0 diff --git a/include/openxr/CMakeLists.txt b/include/openxr/CMakeLists.txt index db054a93b..b1718f60e 100644 --- a/include/openxr/CMakeLists.txt +++ b/include/openxr/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # diff --git a/include/openxr/openxr_platform_defines.h b/include/openxr/openxr_platform_defines.h index 31fa05a0c..9573c101e 100644 --- a/include/openxr/openxr_platform_defines.h +++ b/include/openxr/openxr_platform_defines.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 2017-2022, The Khronos Group Inc. +** Copyright (c) 2017-2023, The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -65,7 +65,7 @@ typedef unsigned __int64 uint64_t; #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__)) +#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 diff --git a/maintainer-scripts/archive-sdk.sh b/maintainer-scripts/archive-sdk.sh index ce9b573e3..82fdda4f1 100755 --- a/maintainer-scripts/archive-sdk.sh +++ b/maintainer-scripts/archive-sdk.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2019-2022, The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -53,6 +53,8 @@ makeSubset "$TARNAME" $(getSDKFilenames) cd sdk # Add the SDK-specific README add_to_tar "$TARNAME" README.md + # Add the pull request template + add_to_tar "$TARNAME" .github/pull_request_template.md ) # Read the list of headers we should generate, and generate them. diff --git a/maintainer-scripts/common.sh b/maintainer-scripts/common.sh index 3d20f12b5..6dac4c02b 100644 --- a/maintainer-scripts/common.sh +++ b/maintainer-scripts/common.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2019-2022, The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -220,7 +220,6 @@ getSDKFilenames() { .github/scripts \ .github/workflows/android.yml \ .github/workflows/check_clang_format_and_codespell.yml \ - .github/workflows/gradle-wrapper-validation.yml \ .github/workflows/msvc-build-preset.yml \ .github/workflows/windows-matrix.yml \ specification/registry/*.xml \ diff --git a/openxr-codespell.exclude b/openxr-codespell.exclude index cb3d8015d..3e3e3645a 100644 --- a/openxr-codespell.exclude +++ b/openxr-codespell.exclude @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: CC-BY-4.0 # Lines that should be excluded from codespell - trailing newline required! diff --git a/runClangFormat.sh b/runClangFormat.sh index c96b96c96..49eb9e65b 100755 --- a/runClangFormat.sh +++ b/runClangFormat.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # diff --git a/specification/.gitignore b/specification/.gitignore index 57426bb06..5b5772843 100644 --- a/specification/.gitignore +++ b/specification/.gitignore @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 @@ -16,4 +16,4 @@ registry/regenerated.rnc # Schematron-related files registry/schxslt-cli.jar registry/cli-*.jar -registry/report.srvl +registry/**/*.srvl diff --git a/specification/Makefile b/specification/Makefile index 70c5235cf..16320e882 100644 --- a/specification/Makefile +++ b/specification/Makefile @@ -1,4 +1,4 @@ -# Copyright 2013-2022 The Khronos Group Inc. +# Copyright 2013-2023 The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 @@ -32,7 +32,7 @@ ifneq (,$(strip $(VERY_STRICT))) ASCIIDOC := $(ASCIIDOC) --failure-level WARN endif -SPECREVISION = 1.0.26 +SPECREVISION = 1.0.27 REVISION_COMPONENTS = $(subst ., ,$(SPECREVISION)) MAJORMINORVER = $(word 1,$(REVISION_COMPONENTS)).$(word 2,$(REVISION_COMPONENTS)) @@ -56,7 +56,9 @@ SPECTOOLS := $(SCRIPTS)/spec_tools XRAPI := $(GENDIR)/apimap.py METADIR := $(GENDIR)/meta -VK_REF_PAGE_ROOT := https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html +VK_REF_PAGE_ROOT := https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html + +MAKE_RELATIVE = $(patsubst $(CURDIR)/%,%,$(1)) # Gets built automatically ASCIIDOCTOR_TARGETS := @@ -376,7 +378,7 @@ BACKEND_ARGS=--backend html5 # AsciiDoctor rule - customized by the places where these are described $(ASCIIDOCTOR_TARGETS): - $(ECHO) "[asciidoctor] $(SPECSRC) -> $@" + $(ECHO) "[asciidoctor] $(SPECSRC) -> $(call MAKE_RELATIVE,$@)" $(QUIET)$(MKDIR) "$(@D)" $(QUIET)if [ $$(uname -s | cut -c 1-6) == "CYGWIN" ]; then \ OUTSPEC_DOS=$$(cygpath -w $@) ;\ @@ -423,12 +425,12 @@ HTML_SPEC_RELATIVE ?= ../../$(SPEC_FILENAME_STEM).html # isrefpage is for refpage-specific content # html_spec_relative is where to find the full specification ADOCREFOPTS = -a stylesheet=khronos.css \ - -a stylesdir=$(CURDIR)/config \ - -a refprefix='refpage.' \ - -a isrefpage \ - -a html_spec_relative='$(HTML_SPEC_RELATIVE)' \ - -a imagesdir=$(CURDIR)/sources \ - -a vkRefPageRoot='$(VK_REF_PAGE_ROOT)' + -a stylesdir=$(CURDIR)/config \ + -a refprefix='refpage.' \ + -a isrefpage \ + -a html_spec_relative='$(HTML_SPEC_RELATIVE)' \ + -a imagesdir=$(CURDIR)/sources \ + -a vkRefPageRoot='$(VK_REF_PAGE_ROOT)' # Pure makefile lowercase function, generated by a script. make_lower = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$(1))))))))))))))))))))))))))) @@ -477,14 +479,11 @@ $(REFPATH)/apispec.txt: $(SPECFILES) $(EXTENSION_SOURCES) $(GENREF) $(SCRIPTS)/r # command output logging in the individual refpage actions below. SUBMAKEOPTIONS = --no-print-directory manhtmlpages: $(REFPATH)/apispec.txt $(GENDEPENDS) - $(QUIET) echo "manhtmlpages: building HTML refpages with these options:" - $(QUIET) echo $(ASCIIDOC) -b html5 $(ADOCOPTS) $(ADOCHTMLOPTS) \ - $(ADOCREFOPTS) -d manpage -o REFPAGE.html REFPAGE.txt $(QUIET)$(MAKE) $(SUBMAKEOPTIONS) -e buildmanpages # Build the individual refpages, then the symbolic links from aliases buildmanpages: $(MANHTML) $(MANHTMLDIR)/openxr.html - $(MAKE) $(SUBMAKEOPTIONS) -e manaliases + $(QUIET)$(MAKE) $(SUBMAKEOPTIONS) -e manaliases # This target does not at present, since OpenXR does not alias refpage # content yet. @@ -494,7 +493,7 @@ manaliases: $(XRAPI) # 'doctype-manpage' allows use of the "book" style but still enable the # refpage-only portions. $(MANHTMLDIR)/openxr.html: $(REFPATH)/apispec.txt $(MANDEPS) - $(ECHO) "[asciidoctor] $< -> $@" + $(ECHO) "[asciidoctor] $(call MAKE_RELATIVE,$<) -> $(call MAKE_RELATIVE,$@)" $(QUIET)$(MKDIR) "$(@D)" $(QUIET)$(ASCIIDOC) -b html5 $(ADOCOPTS) $(ADOCREFOPTS) -a doctype-manpage -d book -o $@ $< @@ -503,8 +502,8 @@ $(MANHTMLDIR)/openxr.html: $(REFPATH)/apispec.txt $(MANDEPS) # 'cross-file-links' causes the *link: macros to link to other refpages, # instead of internal anchors. $(MANHTML): $(MANHTMLDIR)/%.html: $(REFPATH)/%.txt $(MANDEPS) - $(VERYQUIET)echo "Building $@ from $< using default options" - $(VERYQUIET)$(MKDIR) "$(MANHTMLDIR)" + $(ECHO) "[asciidoctor] $(call MAKE_RELATIVE,$<) -> $(call MAKE_RELATIVE,$@)" + $(QUIET)$(MKDIR) "$(@D)" $(VERYQUIET)$(ASCIIDOC) -b html5 $(ADOCOPTS) $(ADOCHTMLOPTS) $(ADOCREFOPTS) \ -a cross-file-links -d manpage -o $@ $< @@ -559,6 +558,20 @@ check-spec-links: .PHONY: check-spec-links +# Look for files whose Khronos copyright has not been updated to the +# current year. +# Ignore this line in the Makefile, and also ignore the compare-base. +DATE_YEAR = $(shell date +%Y) +CHECK_DATES = git grep -l -e 'Copyright.*The Khronos' --and --not \( -e 'Copyright.*$(DATE_YEAR).*The Khronos' --or -e 'grep' \) | grep -v "compare-base/openxr" +check-copyright-dates: + $(QUIET)if test `$(CHECK_DATES) | wc -l` != 0 ; then \ + echo "Files with out-of-date Khronos copyrights (must be updated to $(DATE_YEAR)):" ; \ + $(CHECK_DATES) ; \ + exit 1 ; \ + fi + +.PHONY: check-copyright-dates + ################################################ # Reflow all specification source text @@ -585,7 +598,7 @@ all: ################################################ # Meta builds for releases. Also copies into approximately the right layout for the OpenXR-Registry repo. -REGISTRYOUTDIR = $(OUTDIR)/../registry-release/specs/$(MAJORMINORVER)$(RELEASE_SPECS_SUFFIX) +REGISTRYOUTDIR = $(GENDIR)/out/registry-release/specs/$(MAJORMINORVER)$(RELEASE_SPECS_SUFFIX) $(REGISTRYOUTDIR): $(QUIET)$(MKDIR) "$@" diff --git a/specification/README.md b/specification/README.md index f5193af5c..45948c3b2 100644 --- a/specification/README.md +++ b/specification/README.md @@ -1,7 +1,7 @@ # Building the OpenXR Specification @@ -134,6 +134,17 @@ make styleguide * Remove intermediate files only * `clean_dirt` +## Generate standalone headers + +When an extension is in progress it is often useful to have +a standalone header that can be used in combination with the +official OpenXR header files. The following command can be +used to generate these. + +```bash +python3 scripts/genxr.py -registry registry/xr.xml -standaloneExtension XR_KHR_sample_extension standalone_header +``` + ## Installing the Prerequisite Tools This section describes the software components used by the OpenXR spec diff --git a/specification/loader/api_layer.adoc b/specification/loader/api_layer.adoc index 95c97ed39..d81e19355 100644 --- a/specification/loader/api_layer.adoc +++ b/specification/loader/api_layer.adoc @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // // SPDX-License-Identifier: CC-BY-4.0 @@ -396,9 +396,9 @@ The loader accesses these using the Android AssetManager classes. On Windows, Linux and Android, the loader uses manifest files to discover API layers. -The loader doesn't load the API layer libraries (e.g. DLL or .so -files) for each of the enabled API layers except during `xrCreateInstance` -when it sets up the call chain. +The loader doesn't load the API layer libraries (e.g. DLL or .so files) for +each of the enabled API layers except during `xrCreateInstance` when it sets +up the call chain. This is to reduce the likelihood of loading a malicious API layer into memory. Instead, details are read from the manifest file, which are then provided @@ -470,11 +470,11 @@ The only requirement is that the filename extension is ".json". | "api_layer" | *Required* for Implicit / Explicit | The identifier used to group a single API layer's information together. - | xrEnumerateApiLayerProperties + | `xrEnumerateApiLayerProperties` | "name" | *Required* for Implicit / Explicit | The string used to uniquely identify this API layer to applications. - | xrEnumerateApiLayerProperties + | `xrEnumerateApiLayerProperties` | "library_path" | *Required* for Implicit / Explicit | The "library_path" specifies either a filename, a relative pathname, @@ -487,32 +487,32 @@ The only requirement is that the filename extension is ".json". are no rules about the name of the API layer shared library files other than it should end with the appropriate suffix (".DLL" on Windows, and ".so" on Linux). - | N/A + | N/A | "api_version" | *Required* for Implicit / Explicit | The major.minor (but not patch) version number of the OpenXR API that the shared library file for the library was built against. For example: 1.0. - | xrEnumerateApiLayerProperties + | `xrEnumerateApiLayerProperties` | "implementation_version" | *Required* for Implicit / Explicit | The version of the API layer implemented. If the API layer itself has any major changes, this number should change so the loader and/or application can identify it properly. - | xrEnumerateApiLayerProperties + | `xrEnumerateApiLayerProperties` | "description" | *Required* for Implicit / Explicit - | A high-level description of the API layer and it's intended use. - | xrEnumerateApiLayerProperties + | A high-level description of the API layer and its intended use. + | `xrEnumerateApiLayerProperties` | "functions" | Optional for Implicit / Explicit | This section can be used to identify a different function name for the loader to use in place of standard API layer interface functions. The "functions" node is required if the API layer is using an alternative name for `xrNegotiateLoaderApiLayerInterface`. - | xrGet*ProcAddr (except for `xrNegotiateLoaderApiLayerInterface` + | `xrGetInstanceProcAddr` (except for `xrNegotiateLoaderApiLayerInterface` which must be queried using the OS/platform-specific - GetProcAddress)s. + `GetProcAddress`). | "instance_extensions" | Optional for Implicit / Explicit | Contains the list of instance extension names supported by this @@ -521,12 +521,12 @@ The only requirement is that the filename extension is ".json". API layer, otherwise the node is optional. Each element of the array must have the nodes "name" and "extension_version" which correspond to `XrExtensionProperties` "extensionName" and "extensionVersion" respectively. - | xrEnumerateInstanceExtensionProperties + | `xrEnumerateInstanceExtensionProperties` | "enable_environment" | Optional for Implicit | Indicates an environment variable used to enable the implicit API layer. If provided in the JSON file, this environment variable (which should vary - with each "version" of the API layer) must be set in the environment or else + with each "version" of the API layer) must be set in the environment or else the implicit API layer is not loaded. This is for application environments (e.g. Steam) which want to enable an API layer(s) only for applications that they launch, and allows for applications run outside of that @@ -536,9 +536,9 @@ The only requirement is that the filename extension is ".json". | *Required* for Implicit | Indicates an environment variable used to disable the implicit API layer. Required to allow users or applications to disable implicit layers that are - not desired or that cause problems for the application. The user/application - can set this environment variable (before calling OpenXR functions) to - "blacklist" the API layer. + not desired or that cause problems for the application. The user/application + can set this environment variable (before calling OpenXR functions) to skip + loading this API layer. This environment variable should vary with each "version" of the API layer. If both the "enable_environment" and "disable_environment" variables are set, the @@ -601,12 +601,12 @@ XrResult xrNegotiateLoaderApiLayerInterface( XrNegotiateApiLayerRequest *apiLayerRequest); ---- * pname:loaderInfo must: be a valid pointer to a constant - slink:XrNegotiateLoaderInfo structure. + sname:XrNegotiateLoaderInfo structure. * pname:layerName must: be NULL or a valid C-style NULL-terminated string listing the name of an API layer which the loader is attempting to negotiate with. * pname:layerRequest must be a valid pointer to a - slink:XrNegotiateApiLayerRequest structure. + sname:XrNegotiateApiLayerRequest structure. This function should be directly exported by an API layer so that using "GetProcAddress" on Windows or "dlsym" on Linux, should return a valid @@ -733,8 +733,8 @@ struct XrNegotiateApiLayerRequest { ==== Loader/API Layer Negotiation Process ==== Once the loader has obtained a valid address to the API layer's -flink:xrNegotiateLoaderApiLayerInterface function, the loader will create a -variable of type slink:XrNegotiateLoaderInfo and initialize it in the +fname:xrNegotiateLoaderApiLayerInterface function, the loader will create a +variable of type sname:XrNegotiateLoaderInfo and initialize it in the following ways: 1. Set the structure "structType" to @@ -755,7 +755,7 @@ following ways: loader (the current version at the time of loader compilation). The loader also creates and initializes a variable of type -slink:XrNegotiateApiLayerRequest to allow the API layer to properly respond +sname:XrNegotiateApiLayerRequest to allow the API layer to properly respond to the request. The structure will be initialized by the loader in the following way: @@ -769,7 +769,7 @@ The structure will be initialized by the loader in the following way: The loader will leave the remaining fields uninitialized to allow each API layer to fill in the appropriate information for itself. The loader will then individually call each API layer's -flink:xrNegotiateLoaderApiLayerInterface function and each API layer then +fname:xrNegotiateLoaderApiLayerInterface function and each API layer then must: : * Determine if it can support the loader's request: @@ -907,9 +907,9 @@ XrResult xrCreateApiLayerInstance( const struct XrApiLayerCreateInfo *layerInfo, XrInstance *instance); ---- - * pname:info is a pointer to the slink:XrInstanceCreateInfo information - passed into the standard flink:xrCreateInstance command. - * pname:layerInfo is a pointer to an slink:XrApiLayerCreateInfo structure + * pname:info is a pointer to the sname:XrInstanceCreateInfo information + passed into the standard fname:xrCreateInstance command. + * pname:layerInfo is a pointer to an sname:XrApiLayerCreateInfo structure that contains special information required by a API layer during its create instance process. This is generated by the loader. @@ -940,7 +940,7 @@ struct XrApiLayerCreateInfo { * pname:settings_file_location is the location of any API layer settings file that can be used. This is currently unused. - * pname:nextInfo is a pointer to the slink:XrApiLayerNextInfo structure + * pname:nextInfo is a pointer to the sname:XrApiLayerNextInfo structure which contains information to work with the next API layer in the chain. The sname:XrApiLayerNextInfo structure is also defined in @@ -988,7 +988,7 @@ struct XrApiLayerNextInfo { During the `xrCreateInstance` call, the following happens: . The call enters the loader's trampoline function `xrCreateInstance` -. The loader will generate an instance of the slink:XrApiLayerCreateInfo +. The loader will generate an instance of the sname:XrApiLayerCreateInfo structure . The loader will go through each API layer in reverse order (i.e. starting with the layer closest to the runtime and ending with the API layer closest to @@ -1015,19 +1015,19 @@ During the `xrCreateInstance` call, the following happens: . The loader will then update the `XrApiLayerCreateInfo.nextInfo` to point to the last created `XrApiLayerNextInfo` since this is the first API layer in the call-chain. -. The loader calls the first API layer's flink:xrCreateApiLayerInstance command - passing in the pointer to the created slink:XrApiLayerCreateInfo -. The API layer receives the information in its flink:xrCreateApiLayerInstance command. -. The API layer copies the slink:XrApiLayerCreateInfo structure into it's own structure. -. The API layer then updates it's version of the slink:XrApiLayerCreateInfo structure - setting pname:nextInfo to point to the slink:XrApiLayerNextInfo for the +. The loader calls the first API layer's fname:xrCreateApiLayerInstance command + passing in the pointer to the created sname:XrApiLayerCreateInfo +. The API layer receives the information in its fname:xrCreateApiLayerInstance command. +. The API layer copies the sname:XrApiLayerCreateInfo structure into it's own structure. +. The API layer then updates it's version of the sname:XrApiLayerCreateInfo structure + setting pname:nextInfo to point to the sname:XrApiLayerNextInfo for the next API layer (i.e. `XrApiLayerCreateInfo->nextInfo = XrApiLayerCreateInfo->nextInfo->next;`). . The API layer may validate that it is getting the correct next information by checking that the pname:layerName matches. . The API layer then uses the information out of its sname:XrApiLayerNextInfo to call down the call-chain to the next fname:xrCreateApiLayerInstance, using a - pointer to its slink:XrApiLayerCreateInfo structure instead of the one + pointer to its sname:XrApiLayerCreateInfo structure instead of the one that was passed in during its fname:xrCreateApiLayerInstance command. .. If the call passes, this API layer may choose to setup its own dispatch table to the next API layer's commands using the returned `XrInstance`, the next diff --git a/specification/loader/appendicies.adoc b/specification/loader/appendicies.adoc index 983eb7175..8016a6acc 100644 --- a/specification/loader/appendicies.adoc +++ b/specification/loader/appendicies.adoc @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // // SPDX-License-Identifier: CC-BY-4.0 diff --git a/specification/loader/application.adoc b/specification/loader/application.adoc index 88a3e1f88..89d7e6356 100644 --- a/specification/loader/application.adoc +++ b/specification/loader/application.adoc @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // // SPDX-License-Identifier: CC-BY-4.0 diff --git a/specification/loader/debug.adoc b/specification/loader/debug.adoc index e0abf1fcc..eb4cfa237 100644 --- a/specification/loader/debug.adoc +++ b/specification/loader/debug.adoc @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // // SPDX-License-Identifier: CC-BY-4.0 diff --git a/specification/loader/design.adoc b/specification/loader/design.adoc index 7511af96e..1ae080252 100644 --- a/specification/loader/design.adoc +++ b/specification/loader/design.adoc @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // // SPDX-License-Identifier: CC-BY-4.0 @@ -573,7 +573,7 @@ void GeneratedXrPopulateDispatchTable( XrInstance instance, PFN_xrGetInstanceProcAddr get_inst_proc_addr); ---- - * pname:table is a pointer to the slink:XrGeneratedDispatchTable to + * pname:table is a pointer to the sname:XrGeneratedDispatchTable to populate. * pname:instance is the instance required by pname:get_inst_proc_addr. *NOTE*: This may have a value of `XR_NULL_HANDLE`, but many of the @@ -590,7 +590,7 @@ void GeneratedXrPopulateDispatchTable( ==== xr_generated_dispatch_table.c ==== This file is paired with the above `xr_generated_dispatch_table.h` header -and only implements the flink:GeneratedXrPopulateDispatchTable function used +and only implements the fname:GeneratedXrPopulateDispatchTable function used to populate the elements of a dispatch table. @@ -712,7 +712,7 @@ const char *LoaderPlatformLibraryOpenError( ---- * pname:path must: be a constant string containing the absolute path to the library file that the loader previously attempted to load using - flink:LoaderPlatformLibraryOpen. + fname:LoaderPlatformLibraryOpen. The returned C-style character string contains any available platform-specific error code that may have occurred. @@ -730,7 +730,7 @@ void LoaderPlatformLibraryClose( LoaderPlatformLibraryHandle library) ---- * pname:library must: be valid `LoaderPlatformLibraryHandle` opened using - flink:LoaderPlatformLibraryOpen + fname:LoaderPlatformLibraryOpen .Querying Content In a Platform-Specific Library File @@ -747,8 +747,8 @@ void *LoaderPlatformLibraryGetProcAddr const std::string &name) ---- * pname:library must: be valid `LoaderPlatformLibraryHandle` opened using - flink:LoaderPlatformLibraryOpen, but not yet closed using - flink:LoaderPlatformLibraryClose. + fname:LoaderPlatformLibraryOpen, but not yet closed using + fname:LoaderPlatformLibraryClose. * pname:name must: contain the name of the library supplied function who's function pointer is desired. @@ -769,7 +769,7 @@ const char *LoaderPlatformLibraryGetProcAddrError( ---- * pname:path must: be a constant string containing the name of the entry point that was attempted to be queried during the previous - flink:LoaderPlatformLibraryGetProcAddr call. + fname:LoaderPlatformLibraryGetProcAddr call. The returned C-style character string contains any available platform-specific error code that may have occurred. @@ -837,7 +837,7 @@ char *PlatformUtilsGetSecureEnv( If the platform supports secure environment variable reading, the appropriate method will be used. -Otherwise, it will fall back to the standard flink:PlatformUtilsGetEnv call. +Otherwise, it will fall back to the standard fname:PlatformUtilsGetEnv call. [[active-runtime-file-management]] ==== Active Runtime File Management ==== diff --git a/specification/loader/images/app_dispatch_table_call_chain.svg.license b/specification/loader/images/app_dispatch_table_call_chain.svg.license index ad3390ac1..2631837b0 100644 --- a/specification/loader/images/app_dispatch_table_call_chain.svg.license +++ b/specification/loader/images/app_dispatch_table_call_chain.svg.license @@ -1,3 +1,3 @@ -Copyright (c) 2017-2022, The Khronos Group Inc. +Copyright (c) 2017-2023, The Khronos Group Inc. SPDX-License-Identifier: CC-BY-4.0 diff --git a/specification/loader/images/call_chain_example.svg.license b/specification/loader/images/call_chain_example.svg.license index ad3390ac1..2631837b0 100644 --- a/specification/loader/images/call_chain_example.svg.license +++ b/specification/loader/images/call_chain_example.svg.license @@ -1,3 +1,3 @@ -Copyright (c) 2017-2022, The Khronos Group Inc. +Copyright (c) 2017-2023, The Khronos Group Inc. SPDX-License-Identifier: CC-BY-4.0 diff --git a/specification/loader/images/class_diagram.svg.license b/specification/loader/images/class_diagram.svg.license index ad3390ac1..2631837b0 100644 --- a/specification/loader/images/class_diagram.svg.license +++ b/specification/loader/images/class_diagram.svg.license @@ -1,3 +1,3 @@ -Copyright (c) 2017-2022, The Khronos Group Inc. +Copyright (c) 2017-2023, The Khronos Group Inc. SPDX-License-Identifier: CC-BY-4.0 diff --git a/specification/loader/images/high_level_loader.svg.license b/specification/loader/images/high_level_loader.svg.license index ad3390ac1..2631837b0 100644 --- a/specification/loader/images/high_level_loader.svg.license +++ b/specification/loader/images/high_level_loader.svg.license @@ -1,3 +1,3 @@ -Copyright (c) 2017-2022, The Khronos Group Inc. +Copyright (c) 2017-2023, The Khronos Group Inc. SPDX-License-Identifier: CC-BY-4.0 diff --git a/specification/loader/images/loader_layer_order_calls.svg.license b/specification/loader/images/loader_layer_order_calls.svg.license index ad3390ac1..2631837b0 100644 --- a/specification/loader/images/loader_layer_order_calls.svg.license +++ b/specification/loader/images/loader_layer_order_calls.svg.license @@ -1,3 +1,3 @@ -Copyright (c) 2017-2022, The Khronos Group Inc. +Copyright (c) 2017-2023, The Khronos Group Inc. SPDX-License-Identifier: CC-BY-4.0 diff --git a/specification/loader/images/optional_layer_function_impl.svg.license b/specification/loader/images/optional_layer_function_impl.svg.license index ad3390ac1..2631837b0 100644 --- a/specification/loader/images/optional_layer_function_impl.svg.license +++ b/specification/loader/images/optional_layer_function_impl.svg.license @@ -1,3 +1,3 @@ -Copyright (c) 2017-2022, The Khronos Group Inc. +Copyright (c) 2017-2023, The Khronos Group Inc. SPDX-License-Identifier: CC-BY-4.0 diff --git a/specification/loader/images/standard_call_chains.svg.license b/specification/loader/images/standard_call_chains.svg.license index ad3390ac1..2631837b0 100644 --- a/specification/loader/images/standard_call_chains.svg.license +++ b/specification/loader/images/standard_call_chains.svg.license @@ -1,3 +1,3 @@ -Copyright (c) 2017-2022, The Khronos Group Inc. +Copyright (c) 2017-2023, The Khronos Group Inc. SPDX-License-Identifier: CC-BY-4.0 diff --git a/specification/loader/loader.adoc b/specification/loader/loader.adoc index 053e02441..048e9e9c4 100644 --- a/specification/loader/loader.adoc +++ b/specification/loader/loader.adoc @@ -1,10 +1,10 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright notice at https://www.khronos.org/registry/speccopyright.html // // SPDX-License-Identifier: CC-BY-4.0 = OpenXR^(R)^ Loader - Design and Operation {apititle} -Copyright (c) 2017-2022, The Khronos Group Inc. +Copyright (c) 2017-2023, The Khronos Group Inc. :data-uri: :icons: font :toc2: @@ -14,7 +14,7 @@ Copyright (c) 2017-2022, The Khronos Group Inc. :imagewidth: 800 :fullimagewidth: width="800" -Copyright (c) 2017-2022, The Khronos Group Inc. +Copyright (c) 2017-2023, The Khronos Group Inc. All Rights reserved. toc::[] diff --git a/specification/loader/overview.adoc b/specification/loader/overview.adoc index 57b9e2f18..945913b5d 100644 --- a/specification/loader/overview.adoc +++ b/specification/loader/overview.adoc @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // // SPDX-License-Identifier: CC-BY-4.0 diff --git a/specification/loader/runtime.adoc b/specification/loader/runtime.adoc index 0fbc903e3..f8aed9c5a 100644 --- a/specification/loader/runtime.adoc +++ b/specification/loader/runtime.adoc @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // // SPDX-License-Identifier: CC-BY-4.0 @@ -538,9 +538,9 @@ XrResult xrNegotiateLoaderRuntimeInterface( XrNegotiateRuntimeRequest *runtimeRequest); ---- * pname:loaderInfo must: be a valid pointer to a constant - slink:XrNegotiateLoaderInfo structure. + sname:XrNegotiateLoaderInfo structure. * pname:runtimeRequest must be a valid pointer to a - slink:XrNegotiateRuntimeRequest structure. + sname:XrNegotiateRuntimeRequest structure. This function should be directly exported by a runtime so that using "GetProcAddress" on Windows or "dlsym" on Linux, should return a valid @@ -557,7 +557,7 @@ The sname:XrNegotiateLoaderInfo struct is defined in the `src/common/loader_interfaces.h` header. It is used to pass information about the loader to a runtime during the negotiation process. -See the definition of slink:XrNegotiateLoaderInfo under the +See the definition of sname:XrNegotiateLoaderInfo under the <> section for more information. @@ -592,7 +592,7 @@ struct XrNegotiateRuntimeRequest { <> being requested by the runtime. Should not be outside of the bounds of the - slink:XrNegotiateLoaderInfo::`minInterfaceVersion` and + sname:XrNegotiateLoaderInfo::`minInterfaceVersion` and sname:XrNegotiateLoaderInfo::`maxInterfaceVersion` values (inclusive). * pname:runtimeApiVersion is the version of the OpenXR API supported by this runtime as formatted by `XR_MAKE_VERSION` defined in `openxr.h`. @@ -620,8 +620,8 @@ the application is exiting, or some period of inactivity occurs. ==== Loader/Runtime Negotiation Process ==== Once the loader has obtained a valid address to the runtime's -flink:xrNegotiateLoaderRuntimeInterface function, the loader will create a -variable of type slink:XrNegotiateLoaderInfo and initialize it in the +fname:xrNegotiateLoaderRuntimeInterface function, the loader will create a +variable of type sname:XrNegotiateLoaderInfo and initialize it in the following ways: 1. Set the structure "structType" to @@ -642,7 +642,7 @@ following ways: loader (the current version at the time of loader compilation). The loader will also create an initialize a variable of type -slink:XrNegotiateRuntimeRequest to allow the runtime to properly respond to +sname:XrNegotiateRuntimeRequest to allow the runtime to properly respond to the request. The structure will be initialized by the loader in the following way: @@ -656,7 +656,7 @@ The structure will be initialized by the loader in the following way: The loader will leave the remaining fields uninitialized to allow each runtime to fill in the appropriate information for itself. The loader will then individually call each runtime's -flink:xrNegotiateLoaderRuntimeInterface function and each runtime then must: +fname:xrNegotiateLoaderRuntimeInterface function and each runtime then must: * Determine if it can support the loader's request: ** Does the runtime support any < -Copyright (c) 2017-2022, The Khronos Group Inc. +Copyright (c) 2017-2023, The Khronos Group Inc. SPDX-License-Identifier: Apache-2.0 OR MIT @@ -19,49 +19,48 @@ layer authors. The only authoritative version of xr.xml is the one maintained in the default branch of the Khronos OpenXR GitHub project. - + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -117,6 +116,7 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + #define XR_MAKE_VERSION(major, minor, patch) \ ((((major) & 0xffffULL) << 48) | (((minor) & 0xffffULL) << 32) | ((patch) & 0xffffffffULL)) @@ -130,7 +130,7 @@ maintained in the default branch of the Khronos OpenXR GitHub project. updates them automatically by processing a line at a time. --> // OpenXR current version number. -#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 0, 26) +#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 0, 27) + +#define XR_FACE_EXPRESSSION_SET_DEFAULT_FB XR_FACE_EXPRESSION_SET_DEFAULT_FB + + + +#define XR_MAX_HAPTIC_AMPLITUDE_ENVELOPE_SAMPLES_FB 4000u + + + +#define XR_MAX_HAPTIC_PCM_BUFFER_SIZE_FB 4000 + typedef uint32_t XrBool32; typedef uint64_t XrFlags64; @@ -235,6 +247,9 @@ maintained in the default branch of the Khronos OpenXR GitHub project. typedef int64_t XrDuration; typedef uint64_t XrVersion; + + typedef uint64_t XrSpaceUserIdFB; + XR_DEFINE_ATOM(XrPath) XR_DEFINE_ATOM(XrSystemId) @@ -297,6 +312,10 @@ maintained in the default branch of the Khronos OpenXR GitHub project. typedef XrFlags64 XrSwapchainCreateFoveationFlagsFB; typedef XrFlags64 XrSwapchainStateFoveationFlagsFB; + + typedef XrFlags64 XrFoveationEyeTrackedProfileCreateFlagsMETA; + typedef XrFlags64 XrFoveationEyeTrackedStateFlagsMETA; + typedef XrFlags64 XrTriangleMeshFlagsFB; @@ -324,12 +343,21 @@ maintained in the default branch of the Khronos OpenXR GitHub project. typedef XrFlags64 XrCompositionLayerSettingsFlagsFB; + + typedef XrFlags64 XrExternalCameraStatusFlagsOCULUS; + typedef XrFlags64 XrPerformanceMetricsCounterFlagsMETA; typedef XrFlags64 XrFoveationDynamicFlagsHTC; + + typedef XrFlags64 XrFrameEndInfoFlagsML; + + + typedef XrFlags64 XrGlobalDimmerFrameEndInfoFlagsML; + XR_DEFINE_HANDLE(XrInstance) @@ -361,6 +389,18 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XR_DEFINE_HANDLE(XrPassthroughHTC) + + XR_DEFINE_HANDLE(XrFaceTrackerFB) + + + XR_DEFINE_HANDLE(XrBodyTrackerFB) + + + XR_DEFINE_HANDLE(XrEyeTrackerFB) + + + XR_DEFINE_HANDLE(XrSpaceUserFB) + @@ -424,6 +464,10 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + @@ -460,6 +504,10 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + @@ -477,6 +525,32 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1425,6 +1499,108 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrHandJointVelocityEXT* jointVelocities + + + XrStructureType type + void* next + XrBool32 supportsFaceTracking + + + XrStructureType type + const void* next + XrFaceExpressionSetFB faceExpressionSet + + + XrStructureType type + const void* next + XrTime time + + + XrBool32 isValid + XrBool32 isEyeFollowingBlendshapesValid + + + XrStructureType type + void* next + uint32_t weightCount + float* weights + uint32_t confidenceCount + float* confidences + XrFaceExpressionStatusFB status + XrTime time + + + + + XrStructureType type + void* next + XrBool32 supportsBodyTracking + + + XrStructureType type + const void* next + XrBodyJointSetFB bodyJointSet + + + int32_t joint + int32_t parentJoint + XrPosef pose + + + XrStructureType type + void* next + uint32_t jointCount + XrBodySkeletonJointFB* joints + + + XrStructureType type + const void* next + XrSpace baseSpace + XrTime time + + + XrSpaceLocationFlags locationFlags + XrPosef pose + + + XrStructureType type + void* next + XrBool32 isActive + float confidence + uint32_t jointCount + XrBodyJointLocationFB* jointLocations + uint32_t skeletonChangedCount + XrTime time + + + + + XrStructureType type + void* next + XrBool32 supportsEyeTracking + + + XrStructureType type + const void* next + + + XrStructureType type + const void* next + XrSpace baseSpace + XrTime time + + + XrBool32 isValid + XrPosef gazePose + float gazeConfidence + + + XrStructureType type + void* next + XrEyeGazeFB gaze[XR_EYE_POSITION_COUNT_FB] + XrTime time + + @@ -1943,6 +2119,24 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrFoveationDynamicFB dynamic + + + XrStructureType type + const void* next + XrFoveationEyeTrackedProfileCreateFlagsMETA flags + + + XrStructureType type + void* next + XrVector2f foveationCenter[XR_FOVEATION_CENTER_SIZE_META] + XrFoveationEyeTrackedStateFlagsMETA flags + + + XrStructureType type + void* next + XrBool32 supportsFoveationEyeTracked + + int16_t x @@ -2130,6 +2324,37 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrSpaceStorageLocationFB location + + + XrStructureType type + const void* next + uint32_t spaceCount + XrSpace* spaces + uint32_t userCount + XrSpaceUserFB* users + + + XrStructureType type + const void* next + XrAsyncRequestIdFB requestId + XrResult result + + + + + XrStructureType type + const void* next + uint32_t spaceCount + XrSpace* spaces + XrSpaceStorageLocationFB location + + + XrStructureType type + const void* next + XrAsyncRequestIdFB requestId + XrResult result + + XrStructureType type @@ -2178,6 +2403,20 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrVector2f* vertices + + + XrStructureType type + const void* next + uint32_t requestByteCount + const char* request + + + XrStructureType type + const void* next + XrAsyncRequestIdFB requestId + XrResult result + + XrStructureType type @@ -2339,6 +2578,13 @@ maintained in the default branch of the Khronos OpenXR GitHub project. float rightHandIntensity + + + XrStructureType type + const void* next + XrLocalDimmingModeMETA localDimmingMode + + XR_DEFINE_HANDLE(XrSpatialAnchorStoreConnectionMSFT) @@ -2474,6 +2720,14 @@ maintained in the default branch of the Khronos OpenXR GitHub project. uint8_t data[XR_UUID_SIZE_EXT] + + + XrStructureType type + const void* next + float dimmerValue + XrGlobalDimmerFrameEndInfoFlagsML flags + + XrStructureType type @@ -2484,6 +2738,9 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + XrStructureType type @@ -2491,6 +2748,30 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrCompositionLayerSettingsFlagsFB layerFlags + + + XrTime lastChangeTime + XrFovf fov + float virtualNearPlaneDistance + float virtualFarPlaneDistance + XrExtent2Di imageSensorPixelResolution + + + + XrTime lastChangeTime + XrExternalCameraStatusFlagsOCULUS cameraStatusFlags + XrExternalCameraAttachedToDeviceOCULUS attachedToDevice + XrPosef relativePose + + + + XrStructureType type + const void* next + char name[XR_MAX_EXTERNAL_CAMERA_NAME_SIZE_OCULUS] + XrExternalCameraIntrinsicsOCULUS intrinsics + XrExternalCameraExtrinsicsOCULUS extrinsics + + XrStructureType type @@ -2551,6 +2832,84 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrActionSet actionSet uint32_t priorityOverride + + + + XrStructureType type + const void* next + XrBool32 depthMask + XrCompareOpFB compareOp + + + + XrStructureType type + const void* next + MLCoordinateFrameUID cfuid + XrPosef poseInCoordinateSpace + + + + + + XrStructureType type + const void* next + float focusDistance + XrFrameEndInfoFlagsML flags + + + + + XrStructureType type + const void* next + XrDuration duration + uint32_t amplitudeCount + const float* amplitudes + + + + + XrStructureType type + const void* next + uint32_t bufferSize + const float* buffer + float sampleRate + XrBool32 append + uint32_t* samplesConsumed + + + XrStructureType type + void* next + float sampleRate + + + + + + + XrStructureType type + const void* next + XrSpaceUserIdFB userId + + + + + XrStructureType type + void* next + XrBool32 supportsForceFeedbackCurl + + + + XrStructureType type + const void* next + uint32_t locationCount + XrForceFeedbackCurlApplyLocationMNDX* locations + + + + XrForceFeedbackCurlLocationMNDX location + float value + + @@ -2830,6 +3189,170 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3041,6 +3564,14 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + + + + @@ -3051,6 +3582,7 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + @@ -3110,12 +3642,19 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + + + @@ -3236,6 +3775,22 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + + + + + + + + + + + + @@ -3270,6 +3825,50 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3892,6 +4491,65 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrHandJointLocationsEXT* locations + + + XrResult xrCreateFaceTrackerFB + XrSession session + const XrFaceTrackerCreateInfoFB* createInfo + XrFaceTrackerFB* faceTracker + + + XrResult xrDestroyFaceTrackerFB + XrFaceTrackerFB faceTracker + + + XrResult xrGetFaceExpressionWeightsFB + XrFaceTrackerFB faceTracker + const XrFaceExpressionInfoFB* expressionInfo + XrFaceExpressionWeightsFB* expressionWeights + + + + + XrResult xrCreateBodyTrackerFB + XrSession session + const XrBodyTrackerCreateInfoFB* createInfo + XrBodyTrackerFB* bodyTracker + + + XrResult xrDestroyBodyTrackerFB + XrBodyTrackerFB bodyTracker + + + XrResult xrLocateBodyJointsFB + XrBodyTrackerFB bodyTracker + const XrBodyJointsLocateInfoFB* locateInfo + XrBodyJointLocationsFB* locations + + + XrResult xrGetBodySkeletonFB + XrBodyTrackerFB bodyTracker + XrBodySkeletonFB* skeleton + + + + + XrResult xrCreateEyeTrackerFB + XrSession session + const XrEyeTrackerCreateInfoFB* createInfo + XrEyeTrackerFB* eyeTracker + + + XrResult xrDestroyEyeTrackerFB + XrEyeTrackerFB eyeTracker + + + XrResult xrGetEyeGazesFB + XrEyeTrackerFB eyeTracker + const XrEyeGazesInfoFB* gazeInfo + XrEyeGazesFB* eyeGazes + + XrResult xrCreateHandMeshSpaceMSFT @@ -4079,6 +4737,13 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrFoveationProfileFB profile + + + XrResult xrGetFoveationEyeTrackedStateMETA + XrSession session + XrFoveationEyeTrackedStateMETA* foveationState + + XrResult xrGetHandMeshFB @@ -4314,6 +4979,22 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrAsyncRequestIdFB* requestId + + + XrResult xrSaveSpaceListFB + XrSession session + const XrSpaceListSaveInfoFB* info + XrAsyncRequestIdFB* requestId + + + + + XrResult xrShareSpacesFB + XrSession session + const XrSpaceShareInfoFB* info + XrAsyncRequestIdFB* requestId + + XrResult xrGetSpaceContainerFB @@ -4354,6 +5035,14 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrRoomLayoutFB* roomLayoutOutput + + + XrResult xrRequestSceneCaptureFB + XrSession session + const XrSceneCaptureRequestInfoFB* info + XrAsyncRequestIdFB* requestId + + XrResult xrPassthroughLayerSetKeyboardHandsIntensityFB @@ -4486,6 +5175,15 @@ maintained in the default branch of the Khronos OpenXR GitHub project. float offset + + + XrResult xrEnumerateExternalCamerasOCULUS + XrSession session + uint32_t cameraCapacityInput + uint32_t* cameraCountOutput + XrExternalCameraOCULUS* cameras + + XrResult xrEnumeratePerformanceMetricsCounterPathsMETA @@ -4521,8 +5219,538 @@ maintained in the default branch of the Khronos OpenXR GitHub project. const XrFoveationApplyInfoHTC* applyInfo + + + + XrResult xrCreateSpaceFromCoordinateFrameUIDML + XrSession session + const XrCoordinateSpaceCreateInfoML *createInfo + XrSpace* space + + + + + XrResult xrGetDeviceSampleRateFB + XrSession session + const XrHapticActionInfo* hapticActionInfo + XrDevicePcmSampleRateGetInfoFB* deviceSampleRate + + + + + XrResult xrSetTrackingOptimizationSettingsHintQCOM + XrSession session + XrTrackingOptimizationSettingsDomainQCOM domain + XrTrackingOptimizationSettingsHintQCOM hint + + + + + XrResult xrCreateSpaceUserFB + XrSession session + const XrSpaceUserCreateInfoFB* info + XrSpaceUserFB* user + + + XrResult xrGetSpaceUserIdFB + XrSpaceUserFB user + XrSpaceUserIdFB* userId + + + XrResult xrDestroySpaceUserFB + XrSpaceUserFB user + + + + + XrResult xrApplyForceFeedbackCurlMNDX + XrHandTrackerEXT handTracker + const XrForceFeedbackCurlApplyLocationsMNDX* locations + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/api_layers/README_api_dump.md b/src/api_layers/README_api_dump.md index 352ca25db..94afb024c 100644 --- a/src/api_layers/README_api_dump.md +++ b/src/api_layers/README_api_dump.md @@ -1,7 +1,7 @@ # The API Dump API Layer diff --git a/src/api_layers/README_core_validation.md b/src/api_layers/README_core_validation.md index b7369fcd8..accce9c09 100644 --- a/src/api_layers/README_core_validation.md +++ b/src/api_layers/README_core_validation.md @@ -1,7 +1,7 @@ # The Core Validation API Layer diff --git a/src/api_layers/XrApiLayer_api_dump.def b/src/api_layers/XrApiLayer_api_dump.def index ddda7d443..821d477de 100644 --- a/src/api_layers/XrApiLayer_api_dump.def +++ b/src/api_layers/XrApiLayer_api_dump.def @@ -1,7 +1,7 @@ ;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; -; Copyright (c) 2017-2022, The Khronos Group Inc. +; Copyright (c) 2017-2023, The Khronos Group Inc. ; Copyright (c) 2017-2019 Valve Corporation ; Copyright (c) 2017-2019 LunarG, Inc. ; diff --git a/src/api_layers/XrApiLayer_core_validation.def b/src/api_layers/XrApiLayer_core_validation.def index 47f6c3d12..927962465 100644 --- a/src/api_layers/XrApiLayer_core_validation.def +++ b/src/api_layers/XrApiLayer_core_validation.def @@ -1,7 +1,7 @@ ;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; -; Copyright (c) 2017-2022, The Khronos Group Inc. +; Copyright (c) 2017-2023, The Khronos Group Inc. ; Copyright (c) 2017-2019 Valve Corporation ; Copyright (c) 2017-2019 LunarG, Inc. ; diff --git a/src/api_layers/api_dump.cpp b/src/api_layers/api_dump.cpp index e19e38879..da87d307c 100644 --- a/src/api_layers/api_dump.cpp +++ b/src/api_layers/api_dump.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/api_layers/api_layer_platform_defines.h b/src/api_layers/api_layer_platform_defines.h index a204ff1e3..a49ffc5c4 100644 --- a/src/api_layers/api_layer_platform_defines.h +++ b/src/api_layers/api_layer_platform_defines.h @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2022, The Khronos Group Inc. +// Copyright (c) 2018-2023, The Khronos Group Inc. // Copyright (c) 2018-2019 Valve Corporation // Copyright (c) 2018-2019 LunarG, Inc. // diff --git a/src/api_layers/core_validation.cpp b/src/api_layers/core_validation.cpp index 57015ffa0..98e010c0d 100644 --- a/src/api_layers/core_validation.cpp +++ b/src/api_layers/core_validation.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -266,8 +266,7 @@ void CoreValidLogMessage(GenValidUsageXrInstanceInfo *instance_info, const std:: }); // Setup our callback data once - XrDebugUtilsMessengerCallbackDataEXT callback_data = {}; - callback_data.type = XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT; + XrDebugUtilsMessengerCallbackDataEXT callback_data = {XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; callback_data.messageId = message_id.c_str(); callback_data.functionName = command_name.c_str(); callback_data.message = message.c_str(); @@ -842,8 +841,9 @@ extern "C" { // 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. -LAYER_EXPORT XrResult xrNegotiateLoaderApiLayerInterface(const XrNegotiateLoaderInfo *loaderInfo, const char * /*apiLayerName*/, - XrNegotiateApiLayerRequest *apiLayerRequest) { +LAYER_EXPORT XrResult XRAPI_CALL xrNegotiateLoaderApiLayerInterface(const XrNegotiateLoaderInfo *loaderInfo, + const char * /*apiLayerName*/, + XrNegotiateApiLayerRequest *apiLayerRequest) { if (nullptr == loaderInfo || nullptr == apiLayerRequest || loaderInfo->structType != XR_LOADER_INTERFACE_STRUCT_LOADER_INFO || loaderInfo->structVersion != XR_LOADER_INFO_STRUCT_VERSION || loaderInfo->structSize != sizeof(XrNegotiateLoaderInfo) || apiLayerRequest->structType != XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST || diff --git a/src/api_layers/core_validation_html_anchor.png.license b/src/api_layers/core_validation_html_anchor.png.license index 47cb30822..d71980778 100644 --- a/src/api_layers/core_validation_html_anchor.png.license +++ b/src/api_layers/core_validation_html_anchor.png.license @@ -1,4 +1,4 @@ Copyright (c) 2017, The Khronos Group Inc. -Copyright (c) 2021-2022, The Khronos Group Inc. +Copyright (c) 2021-2023, The Khronos Group Inc. SPDX-License-Identifier: CC-BY-4.0 diff --git a/src/api_layers/core_validation_message.svg.license b/src/api_layers/core_validation_message.svg.license index 4f6ba3a2c..b086cfbad 100644 --- a/src/api_layers/core_validation_message.svg.license +++ b/src/api_layers/core_validation_message.svg.license @@ -1,4 +1,4 @@ Copyright (c) 2017, LunarG, Inc. -Copyright (c) 2021-2022, The Khronos Group Inc. +Copyright (c) 2021-2023, The Khronos Group Inc. SPDX-License-Identifier: CC-BY-4.0 diff --git a/src/api_layers/validation_utils.h b/src/api_layers/validation_utils.h index 48cd55999..7d4a0e99d 100644 --- a/src/api_layers/validation_utils.h +++ b/src/api_layers/validation_utils.h @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2022, The Khronos Group Inc. +// Copyright (c) 2018-2023, The Khronos Group Inc. // Copyright (c) 2018-2019 Valve Corporation // Copyright (c) 2018-2019 LunarG, Inc. // Copyright (c) 2019, Collabora, Ltd. diff --git a/src/cmake/presentation.cmake b/src/cmake/presentation.cmake index f54cf293b..50c41803a 100644 --- a/src/cmake/presentation.cmake +++ b/src/cmake/presentation.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 diff --git a/src/common/extra_algorithms.h b/src/common/extra_algorithms.h index 64af4d08f..eec429e12 100644 --- a/src/common/extra_algorithms.h +++ b/src/common/extra_algorithms.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // Copyright (c) 2019 Collabora, Ltd. diff --git a/src/common/gfxwrapper_opengl.c b/src/common/gfxwrapper_opengl.c index 45912db5f..73daccc33 100644 --- a/src/common/gfxwrapper_opengl.c +++ b/src/common/gfxwrapper_opengl.c @@ -15,26 +15,7 @@ System level functionality ================================================================================================================================ */ -static void *AllocAlignedMemory(size_t size, size_t alignment) { - alignment = (alignment < sizeof(void *)) ? sizeof(void *) : alignment; -#if defined(OS_WINDOWS) - return _aligned_malloc(size, alignment); -#elif defined(OS_APPLE) - void *ptr = NULL; - return (posix_memalign(&ptr, alignment, size) == 0) ? ptr : NULL; -#else - return memalign(alignment, size); -#endif -} - -static void FreeAlignedMemory(void *ptr) { -#if defined(OS_WINDOWS) - _aligned_free(ptr); -#else - free(ptr); -#endif -} - +#if defined(OS_ANDROID) static void Print(const char *format, ...) { #if defined(OS_WINDOWS) char buffer[4096]; @@ -68,6 +49,7 @@ static void Print(const char *format, ...) { __android_log_print(ANDROID_LOG_VERBOSE, "atw", "%s", buffer); #endif } +#endif // defined(OS_ANDROID) static void Error(const char *format, ...) { #if defined(OS_WINDOWS) @@ -145,125 +127,14 @@ static void Error(const char *format, ...) { /* ================================================================================================================================ -Frame logging. - -Each thread that calls ksFrameLog_Open will open its own log. -A frame log is always opened for a specified number of frames, and will -automatically close after the specified number of frames have been recorded. -The CPU and GPU times for the recorded frames will be listed at the end of the log. - -ksFrameLog - -static void ksFrameLog_Open( const char * fileName, const int frameCount ); -static void ksFrameLog_Write( const char * fileName, const int lineNumber, const char * function ); -static void ksFrameLog_BeginFrame(); -static void ksFrameLog_EndFrame( const ksNanoseconds cpuTimeNanoseconds, const ksNanoseconds gpuTimeNanoseconds, const int -gpuTimeFramesDelayed ); - -================================================================================================================================ -*/ - -typedef struct { - FILE *fp; - ksNanoseconds *frameCpuTimes; - ksNanoseconds *frameGpuTimes; - int frameCount; - int frame; -} ksFrameLog; - -__thread ksFrameLog *threadFrameLog; - -static ksFrameLog *ksFrameLog_Get() { - ksFrameLog *l = threadFrameLog; - if (l == NULL) { - l = (ksFrameLog *)malloc(sizeof(ksFrameLog)); - memset(l, 0, sizeof(ksFrameLog)); - threadFrameLog = l; - } - return l; -} - -static void ksFrameLog_Open(const char *fileName, const int frameCount) { - ksFrameLog *l = ksFrameLog_Get(); - if (l != NULL && l->fp == NULL) { - l->fp = fopen(fileName, "wb"); - if (l->fp == NULL) { - Print("Failed to open %s\n", fileName); - } else { - Print("Opened frame log %s for %d frames.\n", fileName, frameCount); - l->frameCpuTimes = (ksNanoseconds *)malloc(frameCount * sizeof(l->frameCpuTimes[0])); - l->frameGpuTimes = (ksNanoseconds *)malloc(frameCount * sizeof(l->frameGpuTimes[0])); - memset(l->frameCpuTimes, 0, frameCount * sizeof(l->frameCpuTimes[0])); - memset(l->frameGpuTimes, 0, frameCount * sizeof(l->frameGpuTimes[0])); - l->frameCount = frameCount; - l->frame = 0; - } - } -} - -static void ksFrameLog_Write(const char *fileName, const int lineNumber, const char *function) { - ksFrameLog *l = ksFrameLog_Get(); - if (l != NULL && l->fp != NULL) { - if (l->frame < l->frameCount) { - fprintf(l->fp, "%s(%d): %s\r\n", fileName, lineNumber, function); - } - } -} - -static void ksFrameLog_BeginFrame() { - ksFrameLog *l = ksFrameLog_Get(); - if (l != NULL && l->fp != NULL) { - if (l->frame < l->frameCount) { -#if !defined(NDEBUG) - fprintf(l->fp, "================ BEGIN FRAME %d ================\r\n", l->frame); -#endif - } - } -} - -static void ksFrameLog_EndFrame(const ksNanoseconds cpuTimeNanoseconds, const ksNanoseconds gpuTimeNanoseconds, - const int gpuTimeFramesDelayed) { - ksFrameLog *l = ksFrameLog_Get(); - if (l != NULL && l->fp != NULL) { - if (l->frame < l->frameCount) { - l->frameCpuTimes[l->frame] = cpuTimeNanoseconds; -#if !defined(NDEBUG) - fprintf(l->fp, "================ END FRAME %d ================\r\n", l->frame); -#endif - } - if (l->frame >= gpuTimeFramesDelayed && l->frame < l->frameCount + gpuTimeFramesDelayed) { - l->frameGpuTimes[l->frame - gpuTimeFramesDelayed] = gpuTimeNanoseconds; - } - - l->frame++; - - if (l->frame >= l->frameCount + gpuTimeFramesDelayed) { - for (int i = 0; i < l->frameCount; i++) { - fprintf(l->fp, "frame %d: CPU = %1.1f ms, GPU = %1.1f ms\r\n", i, l->frameCpuTimes[i] * 1e-6f, - l->frameGpuTimes[i] * 1e-6f); - } - - Print("Closing frame log file (%d frames).\n", l->frameCount); - fclose(l->fp); - free(l->frameCpuTimes); - free(l->frameGpuTimes); - memset(l, 0, sizeof(ksFrameLog)); - } - } -} - -/* -================================================================================================================================ - OpenGL error checking. ================================================================================================================================ */ #if !defined(NDEBUG) -#define GL(func) \ - func; \ - ksFrameLog_Write(__FILE__, __LINE__, #func); \ +#define GL(func) \ + func; \ GlCheckErrors(#func); #else #define GL(func) func; @@ -271,7 +142,6 @@ OpenGL error checking. #if !defined(NDEBUG) #define EGL(func) \ - ksFrameLog_Write(__FILE__, __LINE__, #func); \ if (func == EGL_FALSE) { \ Error(#func " failed: %s", EglErrorString(eglGetError())); \ } @@ -321,6 +191,7 @@ static const char *EglErrorString(const EGLint error) { } #endif +#if !defined(NDEBUG) static const char *GlErrorString(GLenum error) { switch (error) { case GL_NO_ERROR: @@ -346,31 +217,6 @@ static const char *GlErrorString(GLenum error) { } } -static const char *GlFramebufferStatusString(GLenum status) { - switch (status) { - case GL_FRAMEBUFFER_UNDEFINED: - return "GL_FRAMEBUFFER_UNDEFINED"; - case GL_FRAMEBUFFER_UNSUPPORTED: - return "GL_FRAMEBUFFER_UNSUPPORTED"; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: - return "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; -#if !defined(OS_ANDROID) && !defined(OS_APPLE_IOS) - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - return "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - return "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; - case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: - return "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS"; -#endif - default: - return "unknown"; - } -} - static void GlCheckErrors(const char *function) { for (int i = 0; i < 10; i++) { const GLenum error = glGetError(); @@ -380,6 +226,7 @@ static void GlCheckErrors(const char *function) { Error("GL error: %s: %s", function, GlErrorString(error)); } } +#endif // !defined(NDEBUG) /* ================================================================================================================================ @@ -1509,10 +1356,12 @@ static bool ksGpuContext_CreateForSurface(ksGpuContext *context, const ksGpuDevi NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes] autorelease]; if (pixelFormat == nil) { + Error("Failed : NSOpenGLPixelFormat."); return false; } context->nsContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; if (context->nsContext == nil) { + Error("Failed : NSOpenGLContext."); return false; } @@ -1643,15 +1492,18 @@ bool ksGpuContext_CreateShared(ksGpuContext *context, const ksGpuContext *other, context->nsContext = NULL; CGLPixelFormatObj pf = CGLGetPixelFormat(other->cglContext); if (CGLCreateContext(pf, other->cglContext, &context->cglContext) != kCGLNoError) { + Error("Failed : CGLCreateContext."); return false; } CGSConnectionID cid; CGSWindowID wid; CGSSurfaceID sid; if (CGLGetSurface(other->cglContext, &cid, &wid, &sid) != kCGLNoError) { + Error("Failed : CGLGetSurface."); return false; } if (CGLSetSurface(context->cglContext, cid, wid, sid) != kCGLNoError) { + Error("Failed : CGLSetSurface."); return false; } #elif defined(OS_ANDROID) || defined(OS_LINUX_WAYLAND) @@ -1777,12 +1629,6 @@ void ksGpuContext_Destroy(ksGpuContext *context) { #endif } -void ksGpuContext_WaitIdle(ksGpuContext *context) { - UNUSED_PARM(context); - - GL(glFinish()); -} - void ksGpuContext_SetCurrent(ksGpuContext *context) { #if defined(OS_WINDOWS) wglMakeCurrent(context->hDC, context->hGLRC); @@ -1838,13 +1684,6 @@ bool ksGpuContext_CheckCurrent(ksGpuContext *context) { #endif } -static void ksGpuContext_GetLimits(ksGpuContext *context, ksGpuLimits *limits) { - UNUSED_PARM(context); - - limits->maxPushConstantsSize = 512; - limits->maxSamples = glGetInteger(GL_MAX_SAMPLES); -} - /* ================================================================================================================================ @@ -1995,7 +1834,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k window->windowActive = false; window->windowExit = false; window->windowActiveState = false; - window->lastSwapTime = GetTimeNanoseconds(); const LPCSTR displayDevice = NULL; @@ -2116,48 +1954,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k return true; } -static bool ksGpuWindow_SupportedResolution(const int width, const int height) { - DEVMODE dm = {0}; - dm.dmSize = sizeof(dm); - for (int modeIndex = 0; EnumDisplaySettings(NULL, modeIndex, &dm) != 0; modeIndex++) { - if (dm.dmPelsWidth == (DWORD)width && dm.dmPelsHeight == (DWORD)height) { - return true; - } - } - return false; -} - -void ksGpuWindow_Exit(ksGpuWindow *window) { window->windowExit = true; } - -ksGpuWindowEvent ksGpuWindow_ProcessEvents(ksGpuWindow *window) { - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0) { - if (msg.message == WM_QUIT) { - window->windowExit = true; - } else { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - window->input.keyInput[KEY_SHIFT_LEFT] = GetAsyncKeyState(KEY_SHIFT_LEFT) != 0; - window->input.keyInput[KEY_CTRL_LEFT] = GetAsyncKeyState(KEY_CTRL_LEFT) != 0; - window->input.keyInput[KEY_ALT_LEFT] = GetAsyncKeyState(KEY_ALT_LEFT) != 0; - window->input.keyInput[KEY_CURSOR_UP] = GetAsyncKeyState(KEY_CURSOR_UP) != 0; - window->input.keyInput[KEY_CURSOR_DOWN] = GetAsyncKeyState(KEY_CURSOR_DOWN) != 0; - window->input.keyInput[KEY_CURSOR_LEFT] = GetAsyncKeyState(KEY_CURSOR_LEFT) != 0; - window->input.keyInput[KEY_CURSOR_RIGHT] = GetAsyncKeyState(KEY_CURSOR_RIGHT) != 0; - - if (window->windowExit) { - return KS_GPU_WINDOW_EVENT_EXIT; - } - if (window->windowActiveState != window->windowActive) { - window->windowActive = window->windowActiveState; - return (window->windowActiveState) ? KS_GPU_WINDOW_EVENT_ACTIVATED : KS_GPU_WINDOW_EVENT_DEACTIVATED; - } - return KS_GPU_WINDOW_EVENT_NONE; -} - #elif defined(OS_LINUX_XLIB) typedef enum // keysym.h @@ -2267,242 +2063,6 @@ static bool ChangeVideoMode_XF86VidMode(Display *xDisplay, int xScreen, int *cur return true; } -/* - Change video mode using the XRandR X extension version 1.1 - - This does not work using NVIDIA drivers because the NVIDIA drivers by default dynamically - configure TwinView, known as DynamicTwinView. When DynamicTwinView is enabled (the default), - the refresh rate of a mode reported through XRandR is not the actual refresh rate, but - instead is an unique number such that each MetaMode has a different value. This is to - guarantee that MetaModes can be uniquely identified by XRandR. - - To get XRandR to report accurate refresh rates, DynamicTwinView needs to be disabled, but - then NV-CONTROL clients, such as nvidia-settings, will not be able to dynamically manipulate - the X screen's MetaModes. -*/ -static bool ChangeVideoMode_XRandR_1_1(Display *xDisplay, Window xWindow, int *currentWidth, int *currentHeight, - float *currentRefreshRate, int *desiredWidth, int *desiredHeight, - float *desiredRefreshRate) { - int major_version; - int minor_version; - XRRQueryVersion(xDisplay, &major_version, &minor_version); - - XRRScreenConfiguration *screenInfo = XRRGetScreenInfo(xDisplay, xWindow); - if (screenInfo == NULL) { - Error("Cannot get screen info."); - return false; - } - - if (currentWidth != NULL && currentHeight != NULL && currentRefreshRate != NULL) { - XRRScreenConfiguration *screenInfo = XRRGetScreenInfo(xDisplay, xWindow); - - Rotation rotation; - int size_index = XRRConfigCurrentConfiguration(screenInfo, &rotation); - - int nsizes; - XRRScreenSize *sizes = XRRConfigSizes(screenInfo, &nsizes); - - *currentWidth = sizes[size_index].width; - *currentHeight = sizes[size_index].height; - *currentRefreshRate = XRRConfigCurrentRate(screenInfo); - } - - if (desiredWidth != NULL && desiredHeight != NULL && desiredRefreshRate != NULL) { - int nsizes = 0; - XRRScreenSize *sizes = XRRConfigSizes(screenInfo, &nsizes); - - int size_index = -1; - int bestSizeError = 0x7FFFFFFF; - for (int i = 0; i < nsizes; i++) { - const int dw = sizes[i].width - *desiredWidth; - const int dh = sizes[i].height - *desiredHeight; - const int error = dw * dw + dh * dh; - if (error < bestSizeError) { - bestSizeError = error; - size_index = i; - } - } - if (size_index == -1) { - Error("%dx%d resolution not available.", *desiredWidth, *desiredHeight); - XRRFreeScreenConfigInfo(screenInfo); - return false; - } - - int nrates = 0; - short *rates = XRRConfigRates(screenInfo, size_index, &nrates); - - int rate_index = -1; - float bestRateError = 1e6f; - for (int i = 0; i < nrates; i++) { - const float error = fabsf(rates[i] - *desiredRefreshRate); - if (error < bestRateError) { - bestRateError = error; - rate_index = i; - } - } - - *desiredWidth = sizes[size_index].width; - *desiredHeight = sizes[size_index].height; - *desiredRefreshRate = rates[rate_index]; - - XSelectInput(xDisplay, xWindow, StructureNotifyMask); - XRRSelectInput(xDisplay, xWindow, RRScreenChangeNotifyMask); - - Rotation rotation = 1; - int reflection = 0; - - Status status = XRRSetScreenConfigAndRate(xDisplay, screenInfo, xWindow, (SizeID)size_index, - (Rotation)(rotation | reflection), rates[rate_index], CurrentTime); - - if (status != RRSetConfigSuccess) { - Error("Failed to change resolution to %dx%d", *desiredWidth, *desiredHeight); - XRRFreeScreenConfigInfo(screenInfo); - return false; - } - - int eventbase; - int errorbase; - XRRQueryExtension(xDisplay, &eventbase, &errorbase); - - bool receivedScreenChangeNotify = false; - bool receivedConfigNotify = false; - while (1) { - XEvent event; - XNextEvent(xDisplay, (XEvent *)&event); - XRRUpdateConfiguration(&event); - if (event.type - eventbase == RRScreenChangeNotify) { - receivedScreenChangeNotify = true; - } else if (event.type == ConfigureNotify) { - receivedConfigNotify = true; - } - if (receivedScreenChangeNotify && receivedConfigNotify) { - break; - } - } - } - - XRRFreeScreenConfigInfo(screenInfo); - - return true; -} - -/* - Change video mode using the XRandR X extension version 1.2 - - The following code does not necessarily work out of the box, because on - some configurations the modes list returned by XRRGetScreenResources() - is populated with nothing other than the maximum display resolution, - even though XF86VidModeGetAllModeLines() and XRRConfigSizes() *will* - list all resolutions for the same display. - - The user can manually add new modes from the command-line using the - xrandr utility: - - xrandr --newmode - - Where is generated with a utility that implements either - the General Timing Formula (GTF) or the Coordinated Video Timing (CVT) - standard put forth by the Video Electronics Standards Association (VESA): - - gft // http://gtf.sourceforge.net/ - cvt // http://www.uruk.org/~erich/projects/cvt/ - - Alternatively, new modes can be added in code using XRRCreateMode(). - However, this requires calculating all the timing information in code - because there is no standard library that implements the GTF or CVT. -*/ -static bool ChangeVideoMode_XRandR_1_2(Display *xDisplay, Window xWindow, int *currentWidth, int *currentHeight, - float *currentRefreshRate, int *desiredWidth, int *desiredHeight, - float *desiredRefreshRate) { - int major_version; - int minor_version; - XRRQueryVersion(xDisplay, &major_version, &minor_version); - - /* - Screen - virtual screenspace which may be covered by multiple CRTCs - CRTC - display controller - Output - display/monitor connected to a CRTC - Clones - outputs that are simultaneously connected to the same CRTC - */ - - const int PRIMARY_CRTC_INDEX = 0; - const int PRIMARY_OUTPUT_INDEX = 0; - - XRRScreenResources *screenResources = XRRGetScreenResources(xDisplay, xWindow); - XRRCrtcInfo *primaryCrtcInfo = XRRGetCrtcInfo(xDisplay, screenResources, screenResources->crtcs[PRIMARY_CRTC_INDEX]); - XRROutputInfo *primaryOutputInfo = XRRGetOutputInfo(xDisplay, screenResources, primaryCrtcInfo->outputs[PRIMARY_OUTPUT_INDEX]); - - if (currentWidth != NULL && currentHeight != NULL && currentRefreshRate != NULL) { - for (int i = 0; i < screenResources->nmode; i++) { - const XRRModeInfo *modeInfo = &screenResources->modes[i]; - if (modeInfo->id == primaryCrtcInfo->mode) { - *currentWidth = modeInfo->width; - *currentHeight = modeInfo->height; - *currentRefreshRate = modeInfo->dotClock / ((float)modeInfo->hTotal * (float)modeInfo->vTotal); - break; - } - } - } - - if (desiredWidth != NULL && desiredHeight != NULL && desiredRefreshRate != NULL) { - RRMode bestMode = 0; - int bestModeWidth = 0; - int bestModeHeight = 0; - float bestModeRefreshRate = 0.0f; - int bestSizeError = 0x7FFFFFFF; - float bestRefreshRateError = 1e6f; - - for (int i = 0; i < screenResources->nmode; i++) { - const XRRModeInfo *modeInfo = &screenResources->modes[i]; - - if (modeInfo->modeFlags & RR_Interlace) { - continue; - } - - bool validOutputMode = false; - for (int j = 0; j < primaryOutputInfo->nmode; j++) { - if (modeInfo->id == primaryOutputInfo->modes[j]) { - validOutputMode = true; - break; - } - } - if (!validOutputMode) { - continue; - } - - const int modeWidth = modeInfo->width; - const int modeHeight = modeInfo->height; - const float modeRefreshRate = modeInfo->dotClock / ((float)modeInfo->hTotal * (float)modeInfo->vTotal); - - const int dw = modeWidth - *desiredWidth; - const int dh = modeHeight - *desiredHeight; - const int sizeError = dw * dw + dh * dh; - const float refreshRateError = fabsf(modeRefreshRate - *desiredRefreshRate); - if (sizeError < bestSizeError || (sizeError == bestSizeError && refreshRateError < bestRefreshRateError)) { - bestSizeError = sizeError; - bestRefreshRateError = refreshRateError; - bestMode = modeInfo->id; - bestModeWidth = modeWidth; - bestModeHeight = modeHeight; - bestModeRefreshRate = modeRefreshRate; - } - } - - XRRSetCrtcConfig(xDisplay, screenResources, primaryOutputInfo->crtc, CurrentTime, primaryCrtcInfo->x, primaryCrtcInfo->y, - bestMode, primaryCrtcInfo->rotation, primaryCrtcInfo->outputs, primaryCrtcInfo->noutput); - - *desiredWidth = bestModeWidth; - *desiredHeight = bestModeHeight; - *desiredRefreshRate = bestModeRefreshRate; - } - - XRRFreeOutputInfo(primaryOutputInfo); - XRRFreeCrtcInfo(primaryCrtcInfo); - XRRFreeScreenResources(screenResources); - - return true; -} - void ksGpuWindow_Destroy(ksGpuWindow *window) { ksGpuContext_Destroy(&window->context); ksGpuDevice_Destroy(&window->device); @@ -2551,7 +2111,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k window->windowFullscreen = fullscreen; window->windowActive = false; window->windowExit = false; - window->lastSwapTime = GetTimeNanoseconds(); const char *displayName = NULL; window->xDisplay = XOpenDisplay(displayName); @@ -2666,82 +2225,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k return true; } -static bool ksGpuWindow_SupportedResolution(const int width, const int height) { - UNUSED_PARM(width); - UNUSED_PARM(height); - - return true; -} - -void ksGpuWindow_Exit(ksGpuWindow *window) { window->windowExit = true; } - -ksGpuWindowEvent ksGpuWindow_ProcessEvents(ksGpuWindow *window) { - int count = XPending(window->xDisplay); - for (int i = 0; i < count; i++) { - XEvent event; - XNextEvent(window->xDisplay, &event); - - switch (event.type) { - case KeyPress: { - KeySym key = XLookupKeysym(&event.xkey, 0); - if (key < 256 || key == XK_Escape) { - window->input.keyInput[key & 255] = true; - } - break; - } - case KeyRelease: { - KeySym key = XLookupKeysym(&event.xkey, 0); - if (key == XK_Escape) { - exit(0); - } - break; - } - case ButtonPress: { - window->input.mouseInput[event.xbutton.button] = true; - window->input.mouseInputX[event.xbutton.button] = event.xbutton.x; - window->input.mouseInputY[event.xbutton.button] = event.xbutton.y; - } - case ButtonRelease: { - break; - } - // StructureNotifyMask - case ConfigureNotify: - case MapNotify: - case UnmapNotify: - case DestroyNotify: - // PropertyChangeMask - case PropertyNotify: - // ResizeRedirectMask - case ResizeRequest: - // EnterWindowMask | LeaveWindowMask - case EnterNotify: - case LeaveNotify: - // FocusChangeMask - case FocusIn: - case FocusOut: - // ExposureMask - case Expose: - // VisibilityChangeMask - case VisibilityNotify: - - case GenericEvent: - default: - break; - } - } - - if (window->windowExit) { - return KS_GPU_WINDOW_EVENT_EXIT; - } - - if (window->windowActive == false) { - window->windowActive = true; - return KS_GPU_WINDOW_EVENT_ACTIVATED; - } - - return KS_GPU_WINDOW_EVENT_NONE; -} - #elif defined(OS_LINUX_XCB) || defined(OS_LINUX_XCB_GLX) typedef enum // keysym.h @@ -2978,7 +2461,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k window->windowFullscreen = fullscreen; window->windowActive = false; window->windowExit = false; - window->lastSwapTime = GetTimeNanoseconds(); const char *displayName = NULL; int screen_number = 0; @@ -3129,67 +2611,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k return true; } -static bool ksGpuWindow_SupportedResolution(const int width, const int height) { - UNUSED_PARM(width); - UNUSED_PARM(height); - - return true; -} - -void ksGpuWindow_Exit(ksGpuWindow *window) { window->windowExit = true; } - -ksGpuWindowEvent ksGpuWindow_ProcessEvents(ksGpuWindow *window) { - xcb_generic_event_t *event = xcb_poll_for_event(window->connection); - if (event != NULL) { - const uint8_t event_code = (event->response_type & 0x7f); - switch (event_code) { - case XCB_CLIENT_MESSAGE: { - const xcb_client_message_event_t *client_message_event = (const xcb_client_message_event_t *)event; - if (client_message_event->data.data32[0] == window->wm_delete_window_atom) { - free(event); - return KS_GPU_WINDOW_EVENT_EXIT; - } - break; - } - case XCB_KEY_PRESS: { - xcb_key_press_event_t *key_press_event = (xcb_key_press_event_t *)event; - const xcb_keysym_t keysym = xcb_key_press_lookup_keysym(window->key_symbols, key_press_event, 0); - if (keysym < 256 || keysym == XK_Escape) { - window->input.keyInput[keysym & 255] = true; - } - break; - } - case XCB_BUTTON_PRESS: { - const xcb_button_press_event_t *button_press_event = (const xcb_button_press_event_t *)event; - const int masks[5] = {XCB_BUTTON_MASK_1, XCB_BUTTON_MASK_2, XCB_BUTTON_MASK_3, XCB_BUTTON_MASK_4, - XCB_BUTTON_MASK_5}; - for (int i = 0; i < 5; i++) { - if ((button_press_event->state & masks[i]) != 0) { - window->input.mouseInput[i] = true; - window->input.mouseInputX[i] = button_press_event->event_x; - window->input.mouseInputY[i] = button_press_event->event_y; - } - } - break; - } - default: - break; - } - free(event); - } - - if (window->windowExit) { - return KS_GPU_WINDOW_EVENT_EXIT; - } - - if (window->windowActive == false) { - window->windowActive = true; - return KS_GPU_WINDOW_EVENT_ACTIVATED; - } - - return KS_GPU_WINDOW_EVENT_NONE; -} - #elif defined(OS_LINUX_WAYLAND) #ifdef __GNUC__ @@ -3376,7 +2797,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k window->windowFullscreen = fullscreen; window->windowActive = false; window->windowExit = false; - window->lastSwapTime = GetTimeNanoseconds(); window->display = wl_display_connect(NULL); if (window->display == NULL) { @@ -3463,31 +2883,6 @@ void ksGpuWindow_Destroy(ksGpuWindow *window) { ksGpuDevice_Destroy(&window->device); } -ksGpuWindowEvent ksGpuWindow_ProcessEvents(ksGpuWindow *window) { - while (wl_display_prepare_read(window->display) != 0) wl_display_dispatch_pending(window->display); - - if (wl_display_flush(window->display) < 0 && errno != EAGAIN) { - wl_display_cancel_read(window->display); - return KS_GPU_WINDOW_EVENT_NONE; - } - - struct pollfd fds[] = { - {wl_display_get_fd(window->display), POLLIN}, - }; - if (poll(fds, 1, 0) > 0) { - wl_display_read_events(window->display); - wl_display_dispatch_pending(window->display); - } else { - wl_display_cancel_read(window->display); - } - - if (window->windowExit) { - return KS_GPU_WINDOW_EVENT_EXIT; - } - - return KS_GPU_WINDOW_EVENT_NONE; -} - /* * TODO: * This is a work around for ksKeyboardKey naming collision @@ -3676,7 +3071,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k window->windowFullscreen = fullscreen; window->windowActive = false; window->windowExit = false; - window->lastSwapTime = GetTimeNanoseconds(); // Get a list of all available displays. CGDirectDisplayID displays[32]; @@ -3806,61 +3200,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k return true; } -static bool ksGpuWindow_SupportedResolution(const int width, const int height) { - UNUSED_PARM(width); - UNUSED_PARM(height); - - return true; -} - -void ksGpuWindow_Exit(ksGpuWindow *window) { window->windowExit = true; } - -ksGpuWindowEvent ksGpuWindow_ProcessEvents(ksGpuWindow *window) { - [autoReleasePool release]; - autoReleasePool = [[NSAutoreleasePool alloc] init]; - - for (;;) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - NSEvent *event = - [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES]; - if (event == nil) { - break; - } - - if (event.type == NSKeyDown) { - unsigned short key = [event keyCode]; - if (key >= 0 && key < 256) { - window->input.keyInput[key] = true; - } - } else if (event.type == NSLeftMouseDown) { - NSPoint point = [event locationInWindow]; - window->input.mouseInput[MOUSE_LEFT] = true; - window->input.mouseInputX[MOUSE_LEFT] = point.x; - window->input.mouseInputY[MOUSE_LEFT] = point.y - 1; // change to zero-based - } else if (event.type == NSRightMouseDown) { - NSPoint point = [event locationInWindow]; - window->input.mouseInput[MOUSE_RIGHT] = true; - window->input.mouseInputX[MOUSE_RIGHT] = point.x; - window->input.mouseInputY[MOUSE_RIGHT] = point.y - 1; // change to zero-based - } -#pragma GCC diagnostic pop - - [NSApp sendEvent:event]; - } - - if (window->windowExit) { - return KS_GPU_WINDOW_EVENT_EXIT; - } - - if (window->windowActive == false) { - window->windowActive = true; - return KS_GPU_WINDOW_EVENT_ACTIVATED; - } - - return KS_GPU_WINDOW_EVENT_NONE; -} - #elif defined(OS_APPLE_IOS) typedef enum { @@ -3963,7 +3302,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k window->windowFullscreen = fullscreen; window->windowActive = false; window->windowExit = false; - window->lastSwapTime = GetTimeNanoseconds(); window->uiView = myUIView; window->uiWindow = myUIWindow; @@ -3974,28 +3312,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k return true; } -static bool ksGpuWindow_SupportedResolution(const int width, const int height) { - UNUSED_PARM(width); - UNUSED_PARM(height); - - return true; -} - -void ksGpuWindow_Exit(ksGpuWindow *window) { window->windowExit = true; } - -ksGpuWindowEvent ksGpuWindow_ProcessEvents(ksGpuWindow *window) { - if (window->windowExit) { - return KS_GPU_WINDOW_EVENT_EXIT; - } - - if (window->windowActive == false) { - window->windowActive = true; - return KS_GPU_WINDOW_EVENT_ACTIVATED; - } - - return KS_GPU_WINDOW_EVENT_NONE; -} - #elif defined(OS_ANDROID) typedef enum // https://developer.android.com/ndk/reference/group___input.html @@ -4213,7 +3529,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k window->windowFullscreen = true; window->windowActive = false; window->windowExit = false; - window->lastSwapTime = GetTimeNanoseconds(); window->app = global_app; window->nativeWindow = NULL; @@ -4247,215 +3562,4 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k return true; } -static bool ksGpuWindow_SupportedResolution(const int width, const int height) { - UNUSED_PARM(width); - UNUSED_PARM(height); - - // Assume the HWC can handle any window size. - return true; -} - -void ksGpuWindow_Exit(ksGpuWindow *window) { - // Call finish() on the activity and ksGpuWindow_ProcessEvents will handle the rest. - ANativeActivity_finish(window->app->activity); -} - -ksGpuWindowEvent ksGpuWindow_ProcessEvents(ksGpuWindow *window) { - if (window->app == NULL) { - return KS_GPU_WINDOW_EVENT_NONE; - } - - const bool windowWasActive = window->windowActive; - - for (;;) { - int events; - struct android_poll_source *source; - const int timeoutMilliseconds = (window->windowActive == false && window->app->destroyRequested == 0) ? -1 : 0; - if (ALooper_pollAll(timeoutMilliseconds, NULL, &events, (void **)&source) < 0) { - break; - } - - if (source != NULL) { - source->process(window->app, source); - } - - if (window->nativeWindow != NULL && window->context.mainSurface == window->context.tinySurface) { - Print(" ANativeWindow_setBuffersGeometry %d x %d", window->windowWidth, window->windowHeight); - ANativeWindow_setBuffersGeometry(window->nativeWindow, window->windowWidth, window->windowHeight, 0); - - const EGLint surfaceAttribs[] = {EGL_NONE}; - Print(" mainSurface = eglCreateWindowSurface( nativeWindow )"); - window->context.mainSurface = - eglCreateWindowSurface(window->context.display, window->context.config, window->nativeWindow, surfaceAttribs); - if (window->context.mainSurface == EGL_NO_SURFACE) { - Error(" eglCreateWindowSurface() failed: %s", EglErrorString(eglGetError())); - return KS_GPU_WINDOW_EVENT_EXIT; - } - Print(" eglMakeCurrent( mainSurface )"); - EGL(eglMakeCurrent(window->context.display, window->context.mainSurface, window->context.mainSurface, - window->context.context)); - - eglQuerySurface(window->context.display, window->context.mainSurface, EGL_WIDTH, &window->windowWidth); - eglQuerySurface(window->context.display, window->context.mainSurface, EGL_HEIGHT, &window->windowHeight); - } - - if (window->resumed != false && window->nativeWindow != NULL) { - window->windowActive = true; - } else { - window->windowActive = false; - } - - if (window->nativeWindow == NULL && window->context.mainSurface != window->context.tinySurface) { - Print(" eglMakeCurrent( tinySurface )"); - EGL(eglMakeCurrent(window->context.display, window->context.tinySurface, window->context.tinySurface, - window->context.context)); - Print(" eglDestroySurface( mainSurface )"); - EGL(eglDestroySurface(window->context.display, window->context.mainSurface)); - window->context.mainSurface = window->context.tinySurface; - } - } - - if (window->app->destroyRequested != 0) { - return KS_GPU_WINDOW_EVENT_EXIT; - } - if (windowWasActive != window->windowActive) { - return (window->windowActive) ? KS_GPU_WINDOW_EVENT_ACTIVATED : KS_GPU_WINDOW_EVENT_DEACTIVATED; - } - return KS_GPU_WINDOW_EVENT_NONE; -} - -#endif - -void ksGpuWindow_SwapInterval(ksGpuWindow *window, int swapInterval) { - if (swapInterval != window->windowSwapInterval) { -#if defined(OS_WINDOWS) - wglSwapIntervalEXT(swapInterval); -#elif defined(OS_LINUX_XLIB) - glXSwapIntervalEXT(window->context.xDisplay, window->xWindow, swapInterval); -#elif defined(OS_LINUX_XCB) - xcb_dri2_swap_interval(window->context.connection, window->context.glxDrawable, swapInterval); -#elif defined(OS_LINUX_XCB_GLX) - glXSwapIntervalEXT(window->context.xDisplay, window->glxWindow, swapInterval); -#elif defined(OS_APPLE_MACOS) - CGLSetParameter(window->context.cglContext, kCGLCPSwapInterval, &swapInterval); -#elif defined(OS_ANDROID) || defined(OS_LINUX_WAYLAND) - EGL(eglSwapInterval(window->context.display, swapInterval)); -#endif - window->windowSwapInterval = swapInterval; - } -} - -void ksGpuWindow_SwapBuffers(ksGpuWindow *window) { -#if defined(OS_WINDOWS) - SwapBuffers(window->context.hDC); -#elif defined(OS_LINUX_XLIB) - glXSwapBuffers(window->context.xDisplay, window->xWindow); -#elif defined(OS_LINUX_XCB) - xcb_glx_swap_buffers(window->context.connection, window->context.glxContextTag, window->glxWindow); -#elif defined(OS_LINUX_XCB_GLX) - glXSwapBuffers(window->context.xDisplay, window->glxWindow); -#elif defined(OS_APPLE_MACOS) - CGLFlushDrawable(window->context.cglContext); -#elif defined(OS_ANDROID) || defined(OS_LINUX_WAYLAND) - EGL(eglSwapBuffers(window->context.display, window->context.mainSurface)); #endif - - ksNanoseconds newTimeNanoseconds = GetTimeNanoseconds(); - - // Even with smoothing, this is not particularly accurate. - const float frameTimeNanoseconds = 1000.0f * 1000.0f * 1000.0f / window->windowRefreshRate; - const float deltaTimeNanoseconds = (float)newTimeNanoseconds - window->lastSwapTime - frameTimeNanoseconds; - if (fabsf(deltaTimeNanoseconds) < frameTimeNanoseconds * 0.75f) { - newTimeNanoseconds = (ksNanoseconds)(window->lastSwapTime + frameTimeNanoseconds + 0.025f * deltaTimeNanoseconds); - } - // const float smoothDeltaNanoseconds = (float)( newTimeNanoseconds - window->lastSwapTime ); - // Print( "frame delta = %1.3f (error = %1.3f)\n", smoothDeltaNanoseconds * 1e-6f, - // ( smoothDeltaNanoseconds - frameTimeNanoseconds ) * 1e-6f ); - window->lastSwapTime = newTimeNanoseconds; -} - -ksNanoseconds ksGpuWindow_GetNextSwapTimeNanoseconds(ksGpuWindow *window) { - const float frameTimeNanoseconds = 1000.0f * 1000.0f * 1000.0f / window->windowRefreshRate; - return window->lastSwapTime + (ksNanoseconds)(frameTimeNanoseconds); -} - -ksNanoseconds ksGpuWindow_GetFrameTimeNanoseconds(ksGpuWindow *window) { - const float frameTimeNanoseconds = 1000.0f * 1000.0f * 1000.0f / window->windowRefreshRate; - return (ksNanoseconds)(frameTimeNanoseconds); -} - -void ksGpuWindow_DelayBeforeSwap(ksGpuWindow *window, const ksNanoseconds delay) { - UNUSED_PARM(window); - UNUSED_PARM(delay); - - // FIXME: this appears to not only stall the calling context but also other contexts. - /* - #if defined( OS_WINDOWS ) - if ( wglDelayBeforeSwapNV != NULL ) - { - wglDelayBeforeSwapNV( window->hDC, delay * 1e-6f ); - } - #elif defined( OS_LINUX_XLIB ) - if ( glXDelayBeforeSwapNV != NULL ) - { - glXDelayBeforeSwapNV( window->hDC, delay * 1e-6f ); - } - #endif - */ -} - -static bool ksGpuWindowInput_ConsumeKeyboardKey(ksGpuWindowInput *input, const ksKeyboardKey key) { - if (input->keyInput[key]) { - input->keyInput[key] = false; - return true; - } - return false; -} - -static bool ksGpuWindowInput_ConsumeMouseButton(ksGpuWindowInput *input, const ksMouseButton button) { - if (input->mouseInput[button]) { - input->mouseInput[button] = false; - return true; - } - return false; -} - -static bool ksGpuWindowInput_CheckKeyboardKey(ksGpuWindowInput *input, const ksKeyboardKey key) { - return (input->keyInput[key] != false); -} - -/* -================================================================================================================================ - -GPU timer. - -================================================================================================================================ -*/ - -void ksGpuTimer_Create(ksGpuContext *context, ksGpuTimer *timer) { - UNUSED_PARM(context); - - if (glExtensions.timer_query) { - GL(glGenQueries(KS_GPU_TIMER_FRAMES_DELAYED, timer->beginQueries)); - GL(glGenQueries(KS_GPU_TIMER_FRAMES_DELAYED, timer->endQueries)); - timer->queryIndex = 0; - timer->gpuTime = 0; - } -} - -void ksGpuTimer_Destroy(ksGpuContext *context, ksGpuTimer *timer) { - UNUSED_PARM(context); - - if (glExtensions.timer_query) { - GL(glDeleteQueries(KS_GPU_TIMER_FRAMES_DELAYED, timer->beginQueries)); - GL(glDeleteQueries(KS_GPU_TIMER_FRAMES_DELAYED, timer->endQueries)); - } -} - -ksNanoseconds ksGpuTimer_GetNanoseconds(ksGpuTimer *timer) { - if (glExtensions.timer_query) { - return timer->gpuTime; - } else { - return 0; - } -} diff --git a/src/common/gfxwrapper_opengl.h b/src/common/gfxwrapper_opengl.h index 424a2ad10..1243ae832 100644 --- a/src/common/gfxwrapper_opengl.h +++ b/src/common/gfxwrapper_opengl.h @@ -167,10 +167,6 @@ Platform headers / declarations #pragma warning(disable : 4774) // 'printf' : format string expected in argument 1 is not a string literal #endif -#if defined(__clang__) -#pragma clang diagnostic ignored "-Wunused-function" -#endif // defined(__clang__) - #define OPENGL_VERSION_MAJOR 4 #define OPENGL_VERSION_MINOR 3 #define GLSL_VERSION "430" @@ -187,8 +183,6 @@ Platform headers / declarations #define GRAPHICS_API_OPENGL 1 #define OUTPUT_PATH "" -#define __thread __declspec(thread) - #elif defined(OS_LINUX) #define OPENGL_VERSION_MAJOR 4 @@ -260,8 +254,6 @@ extern int pthread_setname_np(pthread_t __target_thread, __const char *__name); extern int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset); #endif // !__USE_GNU -#pragma GCC diagnostic ignored "-Wunused-function" - #elif defined(OS_APPLE_MACOS) // Apple is still at OpenGL 4.1 @@ -276,7 +268,11 @@ extern int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu #include #include #include -#include +#include +#if defined(__OBJC__) +#import +#endif + #define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED #include #include @@ -298,9 +294,6 @@ CGLError CGLSetSurface(CGLContextObj ctx, CGSConnectionID cid, CGSWindowID wid, CGLError CGLGetSurface(CGLContextObj ctx, CGSConnectionID *cid, CGSWindowID *wid, CGSSurfaceID *sid); CGLError CGLUpdateContext(CGLContextObj ctx); -#pragma clang diagnostic ignored "-Wunused-function" -#pragma clang diagnostic ignored "-Wunused-const-variable" - #elif defined(OS_APPLE_IOS) // Assume iOS 7+ which is GLES 3.0 @@ -360,8 +353,6 @@ CGLError CGLUpdateContext(CGLContextObj ctx); #define GRAPHICS_API_OPENGL_ES 1 #define OUTPUT_PATH "/sdcard/" -#pragma GCC diagnostic ignored "-Wunused-function" - typedef struct { JavaVM *vm; // Java Virtual Machine JNIEnv *env; // Thread specific environment @@ -387,20 +378,6 @@ Common headers #include // for EBUSY, ETIMEDOUT etc. #include // for isspace, isdigit -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-function" -#endif // defined(__clang__) - -#include -#include -#include -#include - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif // defined(__clang__) - /* ================================ Common defines @@ -625,10 +602,12 @@ extern PFNGLXDELAYBEFORESWAPNVPROC glXDelayBeforeSwapNV; #elif defined(OS_APPLE_MACOS) +#ifdef GL_GLEXT_FUNCTION_POINTERS extern PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glFramebufferTextureMultiviewOVR; extern PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC glFramebufferTextureMultisampleMultiviewOVR; extern PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT; extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT; +#endif // def GL_GLEXT_FUNCTION_POINTERS #elif defined(OS_ANDROID) @@ -798,7 +777,6 @@ ksGpuSampleCount bool ksGpuContext_CreateShared( ksGpuContext * context, const ksGpuContext * other, const int queueIndex ); void ksGpuContext_Destroy( ksGpuContext * context ); -void ksGpuContext_WaitIdle( ksGpuContext * context ); void ksGpuContext_SetCurrent( ksGpuContext * context ); void ksGpuContext_UnsetCurrent( ksGpuContext * context ); bool ksGpuContext_CheckCurrent( ksGpuContext * context ); @@ -868,7 +846,11 @@ typedef struct { EGLConfig config; EGLSurface mainSurface; #elif defined(OS_APPLE_MACOS) +#if defined(__OBJC__) NSOpenGLContext *nsContext; +#else + void *nsContext; +#endif // defined(__OBJC__) CGLContextObj cglContext; #elif defined(OS_ANDROID) EGLDisplay display; @@ -890,7 +872,6 @@ typedef struct { bool ksGpuContext_CreateShared(ksGpuContext *context, const ksGpuContext *other, int queueIndex); void ksGpuContext_Destroy(ksGpuContext *context); -void ksGpuContext_WaitIdle(ksGpuContext *context); void ksGpuContext_SetCurrent(ksGpuContext *context); void ksGpuContext_UnsetCurrent(ksGpuContext *context); bool ksGpuContext_CheckCurrent(ksGpuContext *context); @@ -918,12 +899,6 @@ depthFormat, const ksGpuSampleCount sampleCount, const int width, const int height, const bool fullscreen ); void ksGpuWindow_Destroy( ksGpuWindow * window ); -void ksGpuWindow_Exit( ksGpuWindow * window ); -ksGpuWindowEvent ksGpuWindow_ProcessEvents( ksGpuWindow * window ); -void ksGpuWindow_SwapInterval( ksGpuWindow * window, const int swapInterval ); -void ksGpuWindow_SwapBuffers( ksGpuWindow * window ); -ksNanoseconds ksGpuWindow_GetNextSwapTimeNanoseconds( ksGpuWindow * window ); -ksNanoseconds ksGpuWindow_GetFrameTimeNanoseconds( ksGpuWindow * window ); ================================================================================================================================ */ @@ -956,7 +931,6 @@ typedef struct { bool windowActive; bool windowExit; ksGpuWindowInput input; - ksNanoseconds lastSwapTime; #if defined(OS_WINDOWS) HINSTANCE hInstance; @@ -1001,8 +975,13 @@ typedef struct { #elif defined(OS_APPLE_MACOS) CGDirectDisplayID display; CGDisplayModeRef desktopDisplayMode; +#if defined(__OBJC__) NSWindow *nsWindow; NSView *nsView; +#else + void *nsWindow; + void *nsView; +#endif // defined(__OBJC__) #elif defined(OS_APPLE_IOS) UIWindow *uiWindow; UIView *uiView; @@ -1021,45 +1000,6 @@ bool ksGpuWindow_Create(ksGpuWindow *window, ksDriverInstance *instance, const k ksGpuSurfaceColorFormat colorFormat, ksGpuSurfaceDepthFormat depthFormat, ksGpuSampleCount sampleCount, int width, int height, bool fullscreen); void ksGpuWindow_Destroy(ksGpuWindow *window); -void ksGpuWindow_Exit(ksGpuWindow *window); -ksGpuWindowEvent ksGpuWindow_ProcessEvents(ksGpuWindow *window); -void ksGpuWindow_SwapInterval(ksGpuWindow *window, int swapInterval); -void ksGpuWindow_SwapBuffers(ksGpuWindow *window); -ksNanoseconds ksGpuWindow_GetNextSwapTimeNanoseconds(ksGpuWindow *window); -ksNanoseconds ksGpuWindow_GetFrameTimeNanoseconds(ksGpuWindow *window); - -/* -================================================================================================================================ - -GPU timer. - -A timer is used to measure the amount of time it takes to complete GPU commands. -For optimal performance a timer should only be created at load time, not at runtime. -To avoid synchronization, ksGpuTimer_GetNanoseconds() reports the time from KS_GPU_TIMER_FRAMES_DELAYED frames ago. -Timer queries are allowed to overlap and can be nested. -Timer queries that are issued inside a render pass may not produce accurate times on tiling GPUs. - -ksGpuTimer - -static void ksGpuTimer_Create( ksGpuContext * context, ksGpuTimer * timer ); -static void ksGpuTimer_Destroy( ksGpuContext * context, ksGpuTimer * timer ); -static ksNanoseconds ksGpuTimer_GetNanoseconds( ksGpuTimer * timer ); - -================================================================================================================================ -*/ - -#define KS_GPU_TIMER_FRAMES_DELAYED 2 - -typedef struct { - GLuint beginQueries[KS_GPU_TIMER_FRAMES_DELAYED]; - GLuint endQueries[KS_GPU_TIMER_FRAMES_DELAYED]; - int queryIndex; - ksNanoseconds gpuTime; -} ksGpuTimer; - -void ksGpuTimer_Create(ksGpuContext *context, ksGpuTimer *timer); -void ksGpuTimer_Destroy(ksGpuContext *context, ksGpuTimer *timer); -ksNanoseconds ksGpuTimer_GetNanoseconds(ksGpuTimer *timer); #ifdef __cplusplus } diff --git a/src/common/hex_and_handles.h b/src/common/hex_and_handles.h index 341013d32..300669033 100644 --- a/src/common/hex_and_handles.h +++ b/src/common/hex_and_handles.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // Copyright (c) 2019 Collabora, Ltd. diff --git a/src/common/loader_interfaces.h b/src/common/loader_interfaces.h index 9c74ed16f..020c3456e 100644 --- a/src/common/loader_interfaces.h +++ b/src/common/loader_interfaces.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017 Valve Corporation // Copyright (c) 2017 LunarG, Inc. // diff --git a/src/common/object_info.cpp b/src/common/object_info.cpp index 95b5aaf40..3f6b39c43 100644 --- a/src/common/object_info.cpp +++ b/src/common/object_info.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // Copyright (c) 2019 Collabora, Ltd. diff --git a/src/common/object_info.h b/src/common/object_info.h index 8e9742b60..247ede0dc 100644 --- a/src/common/object_info.h +++ b/src/common/object_info.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // Copyright (c) 2019 Collabora, Ltd. diff --git a/src/common/platform_utils.hpp b/src/common/platform_utils.hpp index 3e35d8613..6ea95f4ef 100644 --- a/src/common/platform_utils.hpp +++ b/src/common/platform_utils.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/common/stdfs_conditions.h b/src/common/stdfs_conditions.h index 6dc18cc62..0a551f08c 100644 --- a/src/common/stdfs_conditions.h +++ b/src/common/stdfs_conditions.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017 Valve Corporation // Copyright (c) 2017 LunarG, Inc. // diff --git a/src/common/unique_asset.h b/src/common/unique_asset.h index 4929039a0..a8ae8077b 100644 --- a/src/common/unique_asset.h +++ b/src/common/unique_asset.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // // SPDX-License-Identifier: Apache-2.0 OR MIT #pragma once diff --git a/src/common/vulkan_debug_object_namer.hpp b/src/common/vulkan_debug_object_namer.hpp new file mode 100644 index 000000000..451219d20 --- /dev/null +++ b/src/common/vulkan_debug_object_namer.hpp @@ -0,0 +1,63 @@ +// Copyright (c) 2017-2023, The Khronos Group Inc. +// +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#ifdef XR_USE_GRAPHICS_API_VULKAN + +#include +#include + +/// Utility class for assigning debug names to Vulkan objects we create. +class VulkanDebugObjectNamer { + public: + /// Construct without initializing + VulkanDebugObjectNamer() = default; + + /// Construct and initialize + VulkanDebugObjectNamer(VkInstance instance, VkDevice device) : m_vkDevice{device} { + vkSetDebugUtilsObjectNameEXT = + (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT"); + } + /// Copy constructor + VulkanDebugObjectNamer(const VulkanDebugObjectNamer&) = default; + /// Copy assignment operator + VulkanDebugObjectNamer& operator=(const VulkanDebugObjectNamer&) = default; + + /// Destructor + ~VulkanDebugObjectNamer() { Reset(); } + + /// (Re-) Initialize the namer: takes a valid `VkInstance` and `VkDevice` + void Init(VkInstance instance, VkDevice device) { + Reset(); + *this = VulkanDebugObjectNamer(instance, device); + } + + /// The main operation of the namer: actually set an object name. + /// + /// If the namer is not initialized, this exits silently. + VkResult SetName(VkObjectType objectType, uint64_t objectHandle, const char* pObjectName) const { + if (m_vkDevice == nullptr) { + return VK_SUCCESS; + } + if (vkSetDebugUtilsObjectNameEXT != nullptr) { + VkDebugUtilsObjectNameInfoEXT nameInfo{VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, nullptr, objectType, + objectHandle, pObjectName}; + return vkSetDebugUtilsObjectNameEXT(m_vkDevice, &nameInfo); + } + return VK_SUCCESS; + } + + /// De-initialize the namer, forgetting the device and the function pointer loaded from the instance. + void Reset() { + vkSetDebugUtilsObjectNameEXT = nullptr; + m_vkDevice = VK_NULL_HANDLE; + } + + private: + VkDevice m_vkDevice{VK_NULL_HANDLE}; + PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT{nullptr}; +}; + +#endif diff --git a/src/common/xr_dependencies.h b/src/common/xr_dependencies.h index e34527abc..5c7bd0477 100644 --- a/src/common/xr_dependencies.h +++ b/src/common/xr_dependencies.h @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2022, The Khronos Group Inc. +// Copyright (c) 2018-2023, The Khronos Group Inc. // // SPDX-License-Identifier: Apache-2.0 OR MIT // @@ -46,18 +46,6 @@ #ifdef XR_USE_PLATFORM_XLIB #include #include - -#ifdef Success -#undef Success -#endif // Success - -#ifdef Always -#undef Always -#endif // Always - -#ifdef None -#undef None -#endif // None #endif // XR_USE_PLATFORM_XLIB #ifdef XR_USE_PLATFORM_XCB @@ -72,7 +60,7 @@ #include #endif // XR_USE_PLATFORM_XCB #ifdef XR_USE_PLATFORM_MACOS -#include +#include #endif // XR_USE_PLATFORM_MACOS #endif // XR_USE_GRAPHICS_API_OPENGL @@ -87,3 +75,19 @@ #ifdef XR_USE_PLATFORM_WAYLAND #include "wayland-client.h" #endif // XR_USE_PLATFORM_WAYLAND + +#ifdef XR_USE_GRAPHICS_API_OPENGL +#if defined(XR_USE_PLATFORM_XLIB) || defined(XR_USE_PLATFORM_XCB) +#ifdef Success +#undef Success +#endif // Success + +#ifdef Always +#undef Always +#endif // Always + +#ifdef None +#undef None +#endif // None +#endif // defined(XR_USE_PLATFORM_XLIB) || defined(XR_USE_PLATFORM_XCB) +#endif // XR_USE_GRAPHICS_API_OPENGL diff --git a/src/common/xr_linear.h b/src/common/xr_linear.h index 1f0e803b7..5b0da645a 100644 --- a/src/common/xr_linear.h +++ b/src/common/xr_linear.h @@ -21,11 +21,6 @@ #ifndef XR_LINEAR_H_ #define XR_LINEAR_H_ -#if defined(OS_LINUX_XCB) || defined(OS_LINUX_XCB_GLX) || defined(OS_LINUX_WAYLAND) -#pragma GCC diagnostic ignored "-Wunused-function" -#pragma clang diagnostic ignored "-Wunused-function" -#endif - #include /* @@ -51,6 +46,7 @@ XrVector2f XrVector3f XrVector4f XrQuaternionf +XrPosef XrMatrix4x4f inline static void XrVector3f_Set(XrVector3f* v, const float value); @@ -64,8 +60,18 @@ inline static void XrVector3f_Scale(XrVector3f* result, const XrVector3f* a, con inline static void XrVector3f_Normalize(XrVector3f* v); inline static float XrVector3f_Length(const XrVector3f* v); +inline static void XrQuaternionf_CreateIdentity(XrQuaternionf* q); +inline static void XrQuaternionf_CreateFromAxisAngle(XrQuaternionf* result, const XrVector3f* axis, const float angleInRadians); inline static void XrQuaternionf_Lerp(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b, const float fraction); -inline static void XrQuaternionf_Multiply(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b; +inline static void XrQuaternionf_Multiply(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b); +inline static void XrQuaternionf_Invert(XrQuaternionf* result, const XrQuaternionf* q); +inline static void XrQuaternionf_Normalize(XrQuaternionf* q); +inline static void XrQuaternionf_RotateVector3f(XrVector3f* result, const XrQuaternionf* a, const XrVector3f* v); + +inline static void XrPosef_CreateIdentity(XrPosef* result); +inline static void XrPosef_TransformVector3f(XrVector3f* result, const XrPosef* a, const XrVector3f* v); +inline static void XrPosef_Multiply(XrPosef* result, const XrPosef* a, const XrPosef* b); +inline static void XrPosef_Invert(XrPosef* result, const XrPosef* a); inline static void XrMatrix4x4f_CreateIdentity(XrMatrix4x4f* result); inline static void XrMatrix4x4f_CreateTranslation(XrMatrix4x4f* result, const float x, const float y, const float z); @@ -74,13 +80,13 @@ inline static void XrMatrix4x4f_CreateRotation(XrMatrix4x4f* result, const float inline static void XrMatrix4x4f_CreateScale(XrMatrix4x4f* result, const float x, const float y, const float z); inline static void XrMatrix4x4f_CreateTranslationRotationScale(XrMatrix4x4f* result, const XrVector3f* translation, const XrQuaternionf* rotation, const XrVector3f* scale); -inline static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f* result, const float tanAngleLeft, const float tanAngleRight, - const float tanAngleUp, float const tanAngleDown, const float nearZ, - const float farZ); -inline static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f* result, const float fovDegreesLeft, const float fovDegreesRight, - const float fovDegreeUp, const float fovDegreesDown, const float nearZ, - const float farZ); -inline static void XrMatrix4x4f_CreateFromQuaternion(XrMatrix4x4f* result, const XrQuaternionf* src); +inline static void XrMatrix4x4f_CreateFromRigidTransform(XrMatrix4x4f* result, const XrPosef* s); +inline static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f* result, GraphicsAPI graphicsApi, const float tanAngleLeft, + const float tanAngleRight, const float tanAngleUp, float const tanAngleDown, + const float nearZ, const float farZ); +inline static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f* result, GraphicsAPI graphicsApi, const XrFovf fov, + const float nearZ, const float farZ); +inline static void XrMatrix4x4f_CreateFromQuaternion(XrMatrix4x4f* result, const XrQuaternionf* quat); inline static void XrMatrix4x4f_CreateOffsetScaleForBounds(XrMatrix4x4f* result, const XrMatrix4x4f* matrix, const XrVector3f* mins, const XrVector3f* maxs); @@ -207,6 +213,13 @@ inline static void XrVector3f_Normalize(XrVector3f* v) { inline static float XrVector3f_Length(const XrVector3f* v) { return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); } +inline static void XrQuaternionf_CreateIdentity(XrQuaternionf* q) { + q->x = 0.0f; + q->y = 0.0f; + q->z = 0.0f; + q->w = 1.0f; +} + inline static void XrQuaternionf_CreateFromAxisAngle(XrQuaternionf* result, const XrVector3f* axis, const float angleInRadians) { float s = sinf(angleInRadians / 2.0f); float lengthRcp = XrRcpSqrt(axis->x * axis->x + axis->y * axis->y + axis->z * axis->z); @@ -238,6 +251,58 @@ inline static void XrQuaternionf_Multiply(XrQuaternionf* result, const XrQuatern result->w = (b->w * a->w) - (b->x * a->x) - (b->y * a->y) - (b->z * a->z); } +inline static void XrQuaternionf_Invert(XrQuaternionf* result, const XrQuaternionf* q) { + result->x = -q->x; + result->y = -q->y; + result->z = -q->z; + result->w = q->w; +} + +inline static void XrQuaternionf_Normalize(XrQuaternionf* q) { + const float lengthRcp = XrRcpSqrt(q->x * q->x + q->y * q->y + q->z * q->z + q->w * q->w); + q->x *= lengthRcp; + q->y *= lengthRcp; + q->z *= lengthRcp; + q->w *= lengthRcp; +} + +inline static void XrQuaternionf_RotateVector3f(XrVector3f* result, const XrQuaternionf* a, const XrVector3f* v) { + XrQuaternionf q = {v->x, v->y, v->z, 0.0f}; + XrQuaternionf aq; + XrQuaternionf_Multiply(&aq, &q, a); + XrQuaternionf aInv; + XrQuaternionf_Invert(&aInv, a); + XrQuaternionf aqaInv; + XrQuaternionf_Multiply(&aqaInv, &aInv, &aq); + + result->x = aqaInv.x; + result->y = aqaInv.y; + result->z = aqaInv.z; +} + +inline static void XrPosef_CreateIdentity(XrPosef* result) { + XrQuaternionf_CreateIdentity(&result->orientation); + XrVector3f_Set(&result->position, 0); +} + +inline static void XrPosef_TransformVector3f(XrVector3f* result, const XrPosef* a, const XrVector3f* v) { + XrVector3f r0; + XrQuaternionf_RotateVector3f(&r0, &a->orientation, v); + XrVector3f_Add(result, &r0, &a->position); +} + +inline static void XrPosef_Multiply(XrPosef* result, const XrPosef* a, const XrPosef* b) { + XrQuaternionf_Multiply(&result->orientation, &b->orientation, &a->orientation); + XrPosef_TransformVector3f(&result->position, a, &b->position); +} + +inline static void XrPosef_Invert(XrPosef* result, const XrPosef* a) { + XrQuaternionf_Invert(&result->orientation, &a->orientation); + XrVector3f aPosNeg; + XrVector3f_Scale(&aPosNeg, &a->position, -1.0f); + XrQuaternionf_RotateVector3f(&result->position, &result->orientation, &aPosNeg); +} + // Use left-multiplication to accumulate transformations. inline static void XrMatrix4x4f_Multiply(XrMatrix4x4f* result, const XrMatrix4x4f* a, const XrMatrix4x4f* b) { result->m[0] = a->m[0] * b->m[0] + a->m[4] * b->m[1] + a->m[8] * b->m[2] + a->m[12] * b->m[3]; @@ -379,23 +444,31 @@ inline static void XrMatrix4x4f_CreateTranslation(XrMatrix4x4f* result, const fl } // Creates a rotation matrix. -// If -Z=forward, +Y=up, +X=right, then degreesX=pitch, degreesY=yaw, degreesZ=roll. -inline static void XrMatrix4x4f_CreateRotation(XrMatrix4x4f* result, const float degreesX, const float degreesY, - const float degreesZ) { - const float sinX = sinf(degreesX * (MATH_PI / 180.0f)); - const float cosX = cosf(degreesX * (MATH_PI / 180.0f)); +// If -Z=forward, +Y=up, +X=right, then radiansX=pitch, radiansY=yaw, radiansZ=roll. +inline static void XrMatrix4x4f_CreateRotationRadians(XrMatrix4x4f* result, const float radiansX, const float radiansY, + const float radiansZ) { + const float sinX = sinf(radiansX); + const float cosX = cosf(radiansX); const XrMatrix4x4f rotationX = {{1, 0, 0, 0, 0, cosX, sinX, 0, 0, -sinX, cosX, 0, 0, 0, 0, 1}}; - const float sinY = sinf(degreesY * (MATH_PI / 180.0f)); - const float cosY = cosf(degreesY * (MATH_PI / 180.0f)); + const float sinY = sinf(radiansY); + const float cosY = cosf(radiansY); const XrMatrix4x4f rotationY = {{cosY, 0, -sinY, 0, 0, 1, 0, 0, sinY, 0, cosY, 0, 0, 0, 0, 1}}; - const float sinZ = sinf(degreesZ * (MATH_PI / 180.0f)); - const float cosZ = cosf(degreesZ * (MATH_PI / 180.0f)); + const float sinZ = sinf(radiansZ); + const float cosZ = cosf(radiansZ); const XrMatrix4x4f rotationZ = {{cosZ, sinZ, 0, 0, -sinZ, cosZ, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}}; XrMatrix4x4f rotationXY; XrMatrix4x4f_Multiply(&rotationXY, &rotationY, &rotationX); XrMatrix4x4f_Multiply(result, &rotationZ, &rotationXY); } +// Creates a rotation matrix. +// If -Z=forward, +Y=up, +X=right, then degreesX=pitch, degreesY=yaw, degreesZ=roll. +inline static void XrMatrix4x4f_CreateRotation(XrMatrix4x4f* result, const float degreesX, const float degreesY, + const float degreesZ) { + XrMatrix4x4f_CreateRotationRadians(result, degreesX * (MATH_PI / 180.0f), degreesY * (MATH_PI / 180.0f), + degreesZ * (MATH_PI / 180.0f)); +} + // Creates a scale matrix. inline static void XrMatrix4x4f_CreateScale(XrMatrix4x4f* result, const float x, const float y, const float z) { result->m[0] = x; @@ -471,6 +544,11 @@ inline static void XrMatrix4x4f_CreateTranslationRotationScale(XrMatrix4x4f* res XrMatrix4x4f_Multiply(result, &translationMatrix, &combinedMatrix); } +inline static void XrMatrix4x4f_CreateFromRigidTransform(XrMatrix4x4f* result, const XrPosef* s) { + const XrVector3f identityScale = {1.0f, 1.0f, 1.0f}; + XrMatrix4x4f_CreateTranslationRotationScale(result, &s->position, &s->orientation, &identityScale); +} + // Creates a projection matrix based on the specified dimensions. // The projection matrix transforms -Z=forward, +Y=up, +X=right to the appropriate clip space for the graphics API. // The far plane is placed at infinity if farZ <= nearZ. diff --git a/src/common_config.h.in b/src/common_config.h.in index a8ffd850a..97cffe11b 100644 --- a/src/common_config.h.in +++ b/src/common_config.h.in @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017 Valve Corporation // Copyright (c) 2017 LunarG, Inc. // diff --git a/src/external/earcut/include/earcut.hpp b/src/external/earcut/include/earcut.hpp index aaea12e3d..a73ae87c8 100644 --- a/src/external/earcut/include/earcut.hpp +++ b/src/external/earcut/include/earcut.hpp @@ -1,21 +1,3 @@ -// ISC License - -// Copyright (c) 2015, Mapbox - -// Permission to use, copy, modify, and/or distribute this software for any purpose -// with or without fee is hereby granted, provided that the above copyright notice -// and this permission notice appear in all copies. - -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -// THIS SOFTWARE. - -// SPDX-License-Identifier: ISC - #pragma once #include @@ -31,25 +13,25 @@ namespace mapbox { namespace util { -template -struct nth { - inline static typename std::tuple_element::type get(const T& t) { return std::get(t); }; +template struct nth { + inline static typename std::tuple_element::type + get(const T& t) { return std::get(t); }; }; -} // namespace util +} namespace detail { template class Earcut { - public: +public: std::vector indices; std::size_t vertices = 0; template void operator()(const Polygon& points); - private: +private: struct Node { Node(N index, double x_, double y_) : i(index), x(x_), y(y_) {} Node(const Node&) = delete; @@ -76,16 +58,14 @@ class Earcut { bool steiner = false; }; - template - Node* linkedList(const Ring& points, const bool clockwise); + template Node* linkedList(const Ring& points, const bool clockwise); Node* filterPoints(Node* start, Node* end = nullptr); void earcutLinked(Node* ear, int pass = 0); bool isEar(Node* ear); bool isEarHashed(Node* ear); Node* cureLocalIntersections(Node* start); void splitEarcut(Node* start); - template - Node* eliminateHoles(const Polygon& points, Node* outerNode); + template Node* eliminateHoles(const Polygon& points, Node* outerNode); Node* eliminateHole(Node* hole, Node* outerNode); Node* findHoleBridge(Node* hole, Node* outerNode); bool sectorContainsSector(const Node* m, const Node* p); @@ -104,8 +84,7 @@ class Earcut { bool locallyInside(const Node* a, const Node* b); bool middleInside(const Node* a, const Node* b); Node* splitPolygon(Node* a, Node* b); - template - Node* insertNode(std::size_t i, const Point& p, Node* last); + template Node* insertNode(std::size_t i, const Point& p, Node* last); void removeNode(Node* p); bool hashing; @@ -115,10 +94,14 @@ class Earcut { template > class ObjectPool { - public: - ObjectPool() {} - ObjectPool(std::size_t blockSize_) { reset(blockSize_); } - ~ObjectPool() { clear(); } + public: + ObjectPool() { } + ObjectPool(std::size_t blockSize_) { + reset(blockSize_); + } + ~ObjectPool() { + clear(); + } template T* construct(Args&&... args) { if (currentIndex >= blockSize) { @@ -140,8 +123,7 @@ class Earcut { currentIndex = blockSize; } void clear() { reset(blockSize); } - - private: + private: T* currentBlock = nullptr; std::size_t currentIndex = 1; std::size_t blockSize = 1; @@ -152,8 +134,7 @@ class Earcut { ObjectPool nodes; }; -template -template +template template void Earcut::operator()(const Polygon& points) { // reset indices.clear(); @@ -171,7 +152,7 @@ void Earcut::operator()(const Polygon& points) { len += points[i].size(); } - // estimate size of nodes and indices + //estimate size of nodes and indices nodes.reset(len * 3 / 2); indices.reserve(len + points[0].size()); @@ -196,9 +177,9 @@ void Earcut::operator()(const Polygon& points) { p = p->next; } while (p != outerNode); - // minX, minY and size are later used to transform coords into integers for z-order calculation + // minX, minY and inv_size are later used to transform coords into integers for z-order calculation inv_size = std::max(maxX - minX, maxY - minY); - inv_size = inv_size != .0 ? (1. / inv_size) : .0; + inv_size = inv_size != .0 ? (32767. / inv_size) : .0; } earcutLinked(outerNode); @@ -207,9 +188,9 @@ void Earcut::operator()(const Polygon& points) { } // create a circular doubly linked list from polygon points in the specified winding order -template -template -typename Earcut::Node* Earcut::linkedList(const Ring& points, const bool clockwise) { +template template +typename Earcut::Node* +Earcut::linkedList(const Ring& points, const bool clockwise) { using Point = typename Ring::value_type; double sum = 0; const std::size_t len = points.size(); @@ -246,7 +227,8 @@ typename Earcut::Node* Earcut::linkedList(const Ring& points, const bool c // eliminate colinear or duplicate points template -typename Earcut::Node* Earcut::filterPoints(Node* start, Node* end) { +typename Earcut::Node* +Earcut::filterPoints(Node* start, Node* end) { if (!end) end = start; Node* p = start; @@ -316,9 +298,8 @@ void Earcut::earcutLinked(Node* ear, int pass) { ear = cureLocalIntersections(filterPoints(ear)); earcutLinked(ear, 2); - // as a last resort, try splitting the remaining polygon into two - } else if (pass == 2) - splitEarcut(ear); + // as a last resort, try splitting the remaining polygon into two + } else if (pass == 2) splitEarcut(ear); break; } @@ -332,13 +313,14 @@ bool Earcut::isEar(Node* ear) { const Node* b = ear; const Node* c = ear->next; - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear // now make sure we don't have other points inside the potential ear Node* p = ear->next->next; while (p != ear->prev) { - if (pointInTriangle(a->x, a->y, b->x, b->y, c->x, c->y, p->x, p->y) && area(p->prev, p, p->next) >= 0) return false; + if (pointInTriangle(a->x, a->y, b->x, b->y, c->x, c->y, p->x, p->y) && + area(p->prev, p, p->next) >= 0) return false; p = p->next; } @@ -351,7 +333,7 @@ bool Earcut::isEarHashed(Node* ear) { const Node* b = ear; const Node* c = ear->next; - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear // triangle bbox; min & max are calculated like this for speed const double minTX = std::min(a->x, std::min(b->x, c->x)); @@ -367,9 +349,9 @@ bool Earcut::isEarHashed(Node* ear) { Node* p = ear->nextZ; while (p && p->z <= maxZ) { - if (p != ear->prev && p != ear->next && pointInTriangle(a->x, a->y, b->x, b->y, c->x, c->y, p->x, p->y) && - area(p->prev, p, p->next) >= 0) - return false; + if (p != ear->prev && p != ear->next && + pointInTriangle(a->x, a->y, b->x, b->y, c->x, c->y, p->x, p->y) && + area(p->prev, p, p->next) >= 0) return false; p = p->nextZ; } @@ -377,9 +359,9 @@ bool Earcut::isEarHashed(Node* ear) { p = ear->prevZ; while (p && p->z >= minZ) { - if (p != ear->prev && p != ear->next && pointInTriangle(a->x, a->y, b->x, b->y, c->x, c->y, p->x, p->y) && - area(p->prev, p, p->next) >= 0) - return false; + if (p != ear->prev && p != ear->next && + pointInTriangle(a->x, a->y, b->x, b->y, c->x, c->y, p->x, p->y) && + area(p->prev, p, p->next) >= 0) return false; p = p->prevZ; } @@ -388,7 +370,8 @@ bool Earcut::isEarHashed(Node* ear) { // go through all polygon nodes and cure small local self-intersections template -typename Earcut::Node* Earcut::cureLocalIntersections(Node* start) { +typename Earcut::Node* +Earcut::cureLocalIntersections(Node* start) { Node* p = start; do { Node* a = p->prev; @@ -440,9 +423,9 @@ void Earcut::splitEarcut(Node* start) { } // link every hole into the outer loop, producing a single-ring polygon without holes -template -template -typename Earcut::Node* Earcut::eliminateHoles(const Polygon& points, Node* outerNode) { +template template +typename Earcut::Node* +Earcut::eliminateHoles(const Polygon& points, Node* outerNode) { const size_t len = points.size(); std::vector queue; @@ -453,12 +436,13 @@ typename Earcut::Node* Earcut::eliminateHoles(const Polygon& points, Node* queue.push_back(getLeftmost(list)); } } - std::sort(queue.begin(), queue.end(), [](const Node* a, const Node* b) { return a->x < b->x; }); + std::sort(queue.begin(), queue.end(), [](const Node* a, const Node* b) { + return a->x < b->x; + }); // process holes from left to right for (size_t i = 0; i < queue.size(); i++) { outerNode = eliminateHole(queue[i], outerNode); - outerNode = filterPoints(outerNode, outerNode->next); } return outerNode; @@ -466,7 +450,8 @@ typename Earcut::Node* Earcut::eliminateHoles(const Polygon& points, Node* // find a bridge between vertices that connects hole with an outer ring and and link it template -typename Earcut::Node* Earcut::eliminateHole(Node* hole, Node* outerNode) { +typename Earcut::Node* +Earcut::eliminateHole(Node* hole, Node* outerNode) { Node* bridge = findHoleBridge(hole, outerNode); if (!bridge) { return outerNode; @@ -475,16 +460,16 @@ typename Earcut::Node* Earcut::eliminateHole(Node* hole, Node* outerNode) Node* bridgeReverse = splitPolygon(bridge, hole); // filter collinear points around the cuts - Node* filteredBridge = filterPoints(bridge, bridge->next); filterPoints(bridgeReverse, bridgeReverse->next); // Check if input node was removed by the filtering - return outerNode == bridge ? filteredBridge : outerNode; + return filterPoints(bridge, bridge->next); } // David Eberly's algorithm for finding a bridge between hole and outer polygon template -typename Earcut::Node* Earcut::findHoleBridge(Node* hole, Node* outerNode) { +typename Earcut::Node* +Earcut::findHoleBridge(Node* hole, Node* outerNode) { Node* p = outerNode; double hx = hole->x; double hy = hole->y; @@ -495,23 +480,18 @@ typename Earcut::Node* Earcut::findHoleBridge(Node* hole, Node* outerNode) // segment's endpoint with lesser x will be potential connection Vertex do { if (hy <= p->y && hy >= p->next->y && p->next->y != p->y) { - double x = p->x + (hy - p->y) * (p->next->x - p->x) / (p->next->y - p->y); - if (x <= hx && x > qx) { - qx = x; - if (x == hx) { - if (hy == p->y) return p; - if (hy == p->next->y) return p->next; - } - m = p->x < p->next->x ? p : p->next; - } + double x = p->x + (hy - p->y) * (p->next->x - p->x) / (p->next->y - p->y); + if (x <= hx && x > qx) { + qx = x; + m = p->x < p->next->x ? p : p->next; + if (x == hx) return m; // hole touches outer segment; pick leftmost endpoint + } } p = p->next; } while (p != outerNode); if (!m) return 0; - if (hx == qx) return m; // hole touches outer segment; pick leftmost endpoint - // look for points inside the triangle of hole Vertex, segment intersection and endpoint; // if there are no points found, we have a valid connection; // otherwise choose the Vertex of the minimum angle with the ray as connection Vertex @@ -527,9 +507,11 @@ typename Earcut::Node* Earcut::findHoleBridge(Node* hole, Node* outerNode) do { if (hx >= p->x && p->x >= mx && hx != p->x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p->x, p->y)) { - tanCur = std::abs(hy - p->y) / (hx - p->x); // tangential - if (locallyInside(p, hole) && (tanCur < tanMin || (tanCur == tanMin && (p->x > m->x || sectorContainsSector(m, p))))) { + tanCur = std::abs(hy - p->y) / (hx - p->x); // tangential + + if (locallyInside(p, hole) && + (tanCur < tanMin || (tanCur == tanMin && (p->x > m->x || sectorContainsSector(m, p))))) { m = p; tanMin = tanCur; } @@ -569,7 +551,8 @@ void Earcut::indexCurve(Node* start) { // Simon Tatham's linked list merge sort algorithm // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html template -typename Earcut::Node* Earcut::sortLinked(Node* list) { +typename Earcut::Node* +Earcut::sortLinked(Node* list) { assert(list); Node* p; Node* q; @@ -597,6 +580,7 @@ typename Earcut::Node* Earcut::sortLinked(Node* list) { qSize = inSize; while (pSize > 0 || (qSize > 0 && q)) { + if (pSize == 0) { e = q; q = q->nextZ; @@ -615,10 +599,8 @@ typename Earcut::Node* Earcut::sortLinked(Node* list) { qSize--; } - if (tail) - tail->nextZ = e; - else - list = e; + if (tail) tail->nextZ = e; + else list = e; e->prevZ = tail; tail = e; @@ -639,8 +621,8 @@ typename Earcut::Node* Earcut::sortLinked(Node* list) { template int32_t Earcut::zOrder(const double x_, const double y_) { // coords are transformed into non-negative 15-bit integer range - int32_t x = static_cast(32767.0 * (x_ - minX) * inv_size); - int32_t y = static_cast(32767.0 * (y_ - minY) * inv_size); + int32_t x = static_cast((x_ - minX) * inv_size); + int32_t y = static_cast((y_ - minY) * inv_size); x = (x | (x << 8)) & 0x00FF00FF; x = (x | (x << 4)) & 0x0F0F0F0F; @@ -657,11 +639,13 @@ int32_t Earcut::zOrder(const double x_, const double y_) { // find the leftmost node of a polygon ring template -typename Earcut::Node* Earcut::getLeftmost(Node* start) { +typename Earcut::Node* +Earcut::getLeftmost(Node* start) { Node* p = start; Node* leftmost = start; do { - if (p->x < leftmost->x || (p->x == leftmost->x && p->y < leftmost->y)) leftmost = p; + if (p->x < leftmost->x || (p->x == leftmost->x && p->y < leftmost->y)) + leftmost = p; p = p->next; } while (p != start); @@ -671,17 +655,18 @@ typename Earcut::Node* Earcut::getLeftmost(Node* start) { // check if a point lies within a convex triangle template bool Earcut::pointInTriangle(double ax, double ay, double bx, double by, double cx, double cy, double px, double py) const { - return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && - (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0; + return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && + (ax - px) * (by - py) >= (bx - px) * (ay - py) && + (bx - px) * (cy - py) >= (cx - px) * (by - py); } // check if a diagonal between two polygon nodes is valid (lies in polygon interior) template bool Earcut::isValidDiagonal(Node* a, Node* b) { - return a->next->i != b->i && a->prev->i != b->i && !intersectsPolygon(a, b) && // dones't intersect other edges - ((locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible - (area(a->prev, a, b->prev) != 0.0 || area(a, b->prev, b) != 0.0)) || // does not create opposite-facing sectors - (equals(a, b) && area(a->prev, a, a->next) > 0 && area(b->prev, b, b->next) > 0)); // special zero-length case + return a->next->i != b->i && a->prev->i != b->i && !intersectsPolygon(a, b) && // dones't intersect other edges + ((locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible + (area(a->prev, a, b->prev) != 0.0 || area(a, b->prev, b) != 0.0)) || // does not create opposite-facing sectors + (equals(a, b) && area(a->prev, a, a->next) > 0 && area(b->prev, b, b->next) > 0)); // special zero-length case } // signed area of a triangle @@ -704,12 +689,12 @@ bool Earcut::intersects(const Node* p1, const Node* q1, const Node* p2, const int o3 = sign(area(p2, q2, p1)); int o4 = sign(area(p2, q2, q1)); - if (o1 != o2 && o3 != o4) return true; // general case + if (o1 != o2 && o3 != o4) return true; // general case - if (o1 == 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1 - if (o2 == 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1 - if (o3 == 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 - if (o4 == 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2 + if (o1 == 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1 + if (o2 == 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1 + if (o3 == 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 + if (o4 == 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2 return false; } @@ -717,8 +702,10 @@ bool Earcut::intersects(const Node* p1, const Node* q1, const Node* p2, const // for collinear points p, q, r, check if point q lies on segment pr template bool Earcut::onSegment(const Node* p, const Node* q, const Node* r) { - return q->x <= std::max(p->x, r->x) && q->x >= std::min(p->x, r->x) && q->y <= std::max(p->y, r->y) && - q->y >= std::min(p->y, r->y); + return q->x <= std::max(p->x, r->x) && + q->x >= std::min(p->x, r->x) && + q->y <= std::max(p->y, r->y) && + q->y >= std::min(p->y, r->y); } template @@ -731,7 +718,8 @@ template bool Earcut::intersectsPolygon(const Node* a, const Node* b) { const Node* p = a; do { - if (p->i != a->i && p->next->i != a->i && p->i != b->i && p->next->i != b->i && intersects(p, p->next, a, b)) return true; + if (p->i != a->i && p->next->i != a->i && p->i != b->i && p->next->i != b->i && + intersects(p, p->next, a, b)) return true; p = p->next; } while (p != a); @@ -741,8 +729,9 @@ bool Earcut::intersectsPolygon(const Node* a, const Node* b) { // check if a polygon diagonal is locally inside the polygon template bool Earcut::locallyInside(const Node* a, const Node* b) { - return area(a->prev, a, a->next) < 0 ? area(a, b, a->next) >= 0 && area(a, a->prev, b) >= 0 - : area(a, b, a->prev) < 0 || area(a, a->next, b) < 0; + return area(a->prev, a, a->next) < 0 ? + area(a, b, a->next) >= 0 && area(a, a->prev, b) >= 0 : + area(a, b, a->prev) < 0 || area(a, a->next, b) < 0; } // check if the middle Vertex of a polygon diagonal is inside the polygon @@ -754,7 +743,7 @@ bool Earcut::middleInside(const Node* a, const Node* b) { double py = (a->y + b->y) / 2; do { if (((p->y > py) != (p->next->y > py)) && p->next->y != p->y && - (px < (p->next->x - p->x) * (py - p->y) / (p->next->y - p->y) + p->x)) + (px < (p->next->x - p->x) * (py - p->y) / (p->next->y - p->y) + p->x)) inside = !inside; p = p->next; } while (p != a); @@ -766,7 +755,8 @@ bool Earcut::middleInside(const Node* a, const Node* b) { // polygon into two; if one belongs to the outer ring and another to a hole, it merges it into a // single ring template -typename Earcut::Node* Earcut::splitPolygon(Node* a, Node* b) { +typename Earcut::Node* +Earcut::splitPolygon(Node* a, Node* b) { Node* a2 = nodes.construct(a->i, a->x, a->y); Node* b2 = nodes.construct(b->i, b->x, b->y); Node* an = a->next; @@ -788,9 +778,9 @@ typename Earcut::Node* Earcut::splitPolygon(Node* a, Node* b) { } // create a node and util::optionally link it with previous one (in a circular doubly linked list) -template -template -typename Earcut::Node* Earcut::insertNode(std::size_t i, const Point& pt, Node* last) { +template template +typename Earcut::Node* +Earcut::insertNode(std::size_t i, const Point& pt, Node* last) { Node* p = nodes.construct(static_cast(i), util::nth<0, Point>::get(pt), util::nth<1, Point>::get(pt)); if (!last) { @@ -815,7 +805,7 @@ void Earcut::removeNode(Node* p) { if (p->prevZ) p->prevZ->nextZ = p->nextZ; if (p->nextZ) p->nextZ->prevZ = p->prevZ; } -} // namespace detail +} template std::vector earcut(const Polygon& poly) { @@ -823,4 +813,4 @@ std::vector earcut(const Polygon& poly) { earcut(poly); return std::move(earcut.indices); } -} // namespace mapbox +} diff --git a/src/external/earcut/include/earcut.hpp.license b/src/external/earcut/include/earcut.hpp.license new file mode 100644 index 000000000..612906b5d --- /dev/null +++ b/src/external/earcut/include/earcut.hpp.license @@ -0,0 +1,6 @@ +Copyright (c) 2015, Mapbox + +SPDX-License-Identifier: ISC + + +From https://github.com/mapbox/earcut.hpp diff --git a/src/loader/AndroidManifest.xml b/src/loader/AndroidManifest.xml index fc4c3b37d..291b1d307 100644 --- a/src/loader/AndroidManifest.xml +++ b/src/loader/AndroidManifest.xml @@ -1,7 +1,7 @@ diff --git a/src/loader/OpenXRConfig.cmake.in b/src/loader/OpenXRConfig.cmake.in index 766490a51..edf34ee46 100644 --- a/src/loader/OpenXRConfig.cmake.in +++ b/src/loader/OpenXRConfig.cmake.in @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 OR MIT diff --git a/src/loader/android_utilities.cpp b/src/loader/android_utilities.cpp index 59d9a99b7..11c112dc6 100644 --- a/src/loader/android_utilities.cpp +++ b/src/loader/android_utilities.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2022, The Khronos Group Inc. +// Copyright (c) 2020-2023, The Khronos Group Inc. // Copyright (c) 2020-2021, Collabora, Ltd. // // SPDX-License-Identifier: Apache-2.0 OR MIT diff --git a/src/loader/android_utilities.h b/src/loader/android_utilities.h index adb8abaf1..f66c9bf1d 100644 --- a/src/loader/android_utilities.h +++ b/src/loader/android_utilities.h @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2022, The Khronos Group Inc. +// Copyright (c) 2020-2023, The Khronos Group Inc. // Copyright (c) 2020-2021, Collabora, Ltd. // // SPDX-License-Identifier: Apache-2.0 OR MIT diff --git a/src/loader/api_layer_interface.cpp b/src/loader/api_layer_interface.cpp index b946e0940..93a225f3e 100644 --- a/src/loader/api_layer_interface.cpp +++ b/src/loader/api_layer_interface.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/loader/api_layer_interface.hpp b/src/loader/api_layer_interface.hpp index b93e44584..98685b0c3 100644 --- a/src/loader/api_layer_interface.hpp +++ b/src/loader/api_layer_interface.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/loader/build.gradle b/src/loader/build.gradle index 2b59f7493..acf7971f9 100644 --- a/src/loader/build.gradle +++ b/src/loader/build.gradle @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2022, The Khronos Group Inc. +// Copyright (c) 2020-2023, The Khronos Group Inc. // // SPDX-License-Identifier: Apache-2.0 diff --git a/src/loader/exception_handling.hpp b/src/loader/exception_handling.hpp index 428dd0027..bc0d9b65e 100644 --- a/src/loader/exception_handling.hpp +++ b/src/loader/exception_handling.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2022, The Khronos Group Inc. +// Copyright (c) 2019-2023, The Khronos Group Inc. // // SPDX-License-Identifier: Apache-2.0 OR MIT // diff --git a/src/loader/loader.rc b/src/loader/loader.rc index b5db540a2..8f36b13bb 100644 --- a/src/loader/loader.rc +++ b/src/loader/loader.rc @@ -1,5 +1,5 @@ // -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017 Valve Corporation // Copyright (c) 2017 LunarG, Inc. // diff --git a/src/loader/loader_core.cpp b/src/loader/loader_core.cpp index f2bc87d1f..98d3fa971 100644 --- a/src/loader/loader_core.cpp +++ b/src/loader/loader_core.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/loader/loader_instance.cpp b/src/loader/loader_instance.cpp index b24c8de53..21fc4632b 100644 --- a/src/loader/loader_instance.cpp +++ b/src/loader/loader_instance.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/loader/loader_instance.hpp b/src/loader/loader_instance.hpp index 1d43ed758..a0268a855 100644 --- a/src/loader/loader_instance.hpp +++ b/src/loader/loader_instance.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/loader/loader_logger.cpp b/src/loader/loader_logger.cpp index 762e67728..1c8d64f39 100644 --- a/src/loader/loader_logger.cpp +++ b/src/loader/loader_logger.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/loader/loader_logger.hpp b/src/loader/loader_logger.hpp index 260ebe354..d31fac093 100644 --- a/src/loader/loader_logger.hpp +++ b/src/loader/loader_logger.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/loader/loader_logger_recorders.cpp b/src/loader/loader_logger_recorders.cpp index 7673678c6..1b3892b89 100644 --- a/src/loader/loader_logger_recorders.cpp +++ b/src/loader/loader_logger_recorders.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -160,16 +160,13 @@ bool DebugUtilsLogRecorder::LogMessage(XrLoaderLogMessageSeverityFlagBits messag XrDebugUtilsMessageTypeFlagsEXT utils_type = LoaderLogMessageTypesToDebugUtilsMessageTypes(message_type); // Convert the loader log message into the debug utils log message information - XrDebugUtilsMessengerCallbackDataEXT utils_callback_data = {}; - utils_callback_data.type = XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT; + XrDebugUtilsMessengerCallbackDataEXT utils_callback_data = {XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; utils_callback_data.messageId = callback_data->message_id; utils_callback_data.functionName = callback_data->command_name; utils_callback_data.message = callback_data->message; - std::vector utils_objects; - utils_objects.resize(callback_data->object_count); + std::vector utils_objects(callback_data->object_count, + {XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT}); for (uint8_t object = 0; object < callback_data->object_count; ++object) { - utils_objects[object].type = XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; - utils_objects[object].next = nullptr; utils_objects[object].objectHandle = callback_data->objects[object].handle; utils_objects[object].objectType = callback_data->objects[object].type; utils_objects[object].objectName = callback_data->objects[object].name.c_str(); diff --git a/src/loader/loader_logger_recorders.hpp b/src/loader/loader_logger_recorders.hpp index 31e5243c4..7b934202d 100644 --- a/src/loader/loader_logger_recorders.hpp +++ b/src/loader/loader_logger_recorders.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/loader/loader_platform.hpp b/src/loader/loader_platform.hpp index e2757fffb..0ea80c05b 100644 --- a/src/loader/loader_platform.hpp +++ b/src/loader/loader_platform.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/loader/manifest_file.cpp b/src/loader/manifest_file.cpp index 26c03ee15..bba6b8ca0 100644 --- a/src/loader/manifest_file.cpp +++ b/src/loader/manifest_file.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -447,9 +447,7 @@ static void GetExtensionProperties(const std::vector &extensio if (it != props.end()) { it->extensionVersion = std::max(it->extensionVersion, ext.extension_version); } else { - XrExtensionProperties prop = {}; - prop.type = XR_TYPE_EXTENSION_PROPERTIES; - prop.next = nullptr; + XrExtensionProperties prop = {XR_TYPE_EXTENSION_PROPERTIES}; strncpy(prop.extensionName, ext.name.c_str(), XR_MAX_EXTENSION_NAME_SIZE - 1); prop.extensionName[XR_MAX_EXTENSION_NAME_SIZE - 1] = '\0'; prop.extensionVersion = ext.extension_version; diff --git a/src/loader/openxr-loader.def b/src/loader/openxr-loader.def index 2410d16aa..c0ef71787 100644 --- a/src/loader/openxr-loader.def +++ b/src/loader/openxr-loader.def @@ -1,7 +1,7 @@ ;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; -; Copyright (c) 2019-2022, The Khronos Group Inc. +; Copyright (c) 2019-2023, The Khronos Group Inc. ; ; SPDX-License-Identifier: Apache-2.0 OR MIT ; diff --git a/src/loader/openxr-loader.map.license b/src/loader/openxr-loader.map.license index 5c53cb140..1eda462d8 100644 --- a/src/loader/openxr-loader.map.license +++ b/src/loader/openxr-loader.map.license @@ -1,3 +1,3 @@ -Copyright (c) 2019-2022, The Khronos Group Inc. +Copyright (c) 2019-2023, The Khronos Group Inc. SPDX-License-Identifier: Apache-2.0 OR MIT diff --git a/src/loader/openxr.pc.in.license b/src/loader/openxr.pc.in.license index 005293c39..1811d3917 100644 --- a/src/loader/openxr.pc.in.license +++ b/src/loader/openxr.pc.in.license @@ -1,3 +1,3 @@ -Copyright (c) 2017-2022, The Khronos Group Inc. +Copyright (c) 2017-2023, The Khronos Group Inc. SPDX-License-Identifier: Apache-2.0 diff --git a/src/loader/runtime_interface.cpp b/src/loader/runtime_interface.cpp index 0f081ff9b..cb1a98af7 100644 --- a/src/loader/runtime_interface.cpp +++ b/src/loader/runtime_interface.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -430,12 +430,8 @@ void RuntimeInterface::GetInstanceExtensionProperties(std::vector 0) { - runtime_extension_properties.resize(count_output); + runtime_extension_properties.resize(count_output, {XR_TYPE_EXTENSION_PROPERTIES}); count = count_output; - for (XrExtensionProperties& ext_prop : runtime_extension_properties) { - ext_prop.type = XR_TYPE_EXTENSION_PROPERTIES; - ext_prop.next = nullptr; - } rt_xrEnumerateInstanceExtensionProperties(nullptr, count, &count_output, runtime_extension_properties.data()); } size_t ext_count = runtime_extension_properties.size(); diff --git a/src/loader/runtime_interface.hpp b/src/loader/runtime_interface.hpp index fa53ee03f..8d55ec674 100644 --- a/src/loader/runtime_interface.hpp +++ b/src/loader/runtime_interface.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/loader/settings.gradle b/src/loader/settings.gradle index 7225b2bf8..9b51150d4 100644 --- a/src/loader/settings.gradle +++ b/src/loader/settings.gradle @@ -1,3 +1,3 @@ -// Copyright (c) 2020-2022, The Khronos Group Inc. +// Copyright (c) 2020-2023, The Khronos Group Inc. // // SPDX-License-Identifier: Apache-2.0 diff --git a/src/scripts/api_dump_generator.py b/src/scripts/api_dump_generator.py index 36ffa9cf4..5b409c33b 100755 --- a/src/scripts/api_dump_generator.py +++ b/src/scripts/api_dump_generator.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -i # -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # Copyright (c) 2017-2019 Valve Corporation # Copyright (c) 2017-2019 LunarG, Inc. # @@ -98,7 +98,7 @@ def endFile(self): AutomaticSourceOutputGenerator.endFile(self) # Output the externs required by the manual code to work with the API Dump - # gnerated code. + # generated code. # self the ApiDumpOutputGenerator object def outputApiDumpExterns(self): externs = '\n// Externs for API dump\n' diff --git a/src/scripts/automatic_source_generator.py b/src/scripts/automatic_source_generator.py index 5f79e805b..3866fada0 100755 --- a/src/scripts/automatic_source_generator.py +++ b/src/scripts/automatic_source_generator.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -i # -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # Copyright (c) 2017-2019 Valve Corporation # Copyright (c) 2017-2019 LunarG, Inc. # @@ -35,6 +35,9 @@ from spec_tools.util import getElemName +EXTNAME_RE = re.compile("^(?PXR|VK)_(?P(?P[A-Z]+?)(?PX*[0-9]*))_(?P.*)$") + + def undecorate(name): """Undecorate a name by removing the leading Xr and making it lowercase.""" lower = name.lower() @@ -448,7 +451,7 @@ def outputErrorIfNeeded(self): # overridden by a derived class. # self the AutomaticSourceOutputGenerator object def outputCopywriteHeader(self): - notice = '// Copyright (c) 2017-2022, The Khronos Group Inc.\n' + notice = '// Copyright (c) 2017-2023, The Khronos Group Inc.\n' notice += '// Copyright (c) 2017-2019 Valve Corporation\n' notice += '// Copyright (c) 2017-2019 LunarG, Inc.\n' notice += '//\n' @@ -540,14 +543,12 @@ def beginFeature(self, interface, emit): self.required_exts.append(self.currentExtension) # Make sure the extension has the proper vendor tags valid_extension_vendor = False - for cur_vendor_tag in self.vendor_tags: - extension_prefix_with_tag = "XR_" - extension_prefix_with_tag += cur_vendor_tag - extension_prefix_with_tag += "_" - if self.currentExtension.startswith(extension_prefix_with_tag): - valid_extension_vendor = True - # Save the extension tag to check every type, etc with - self.current_vendor_tag = cur_vendor_tag + extension_tag = EXTNAME_RE.sub("\\g", self.currentExtension) + extension_base_tag = EXTNAME_RE.sub("\\g", self.currentExtension) + if extension_base_tag in self.vendor_tags or extension_tag in self.vendor_tags: + valid_extension_vendor = True + self.current_vendor_tag = extension_tag + if not valid_extension_vendor: self.printCodeGenErrorMessage('Extension %s does not appear to begin with a' ' valid vendor tag! (for example XR_KHR_)' % self.currentExtension) @@ -627,7 +628,8 @@ def genGroup(self, group_info, name, alias): self.featureExtraProtect, elem.get('protect')) elem_name = elem.get('name') # TODO this variable is never read - if is_extension and not elem_name.endswith(tuple(self.vendor_tags)): + elem_name_base = re.sub("X[0-9]*$", "", elem_name) + if is_extension and not (elem_name_base.endswith(tuple(self.vendor_tags)) or elem_name.endswith(tuple(self.vendor_tags))): self.printCodeGenErrorMessage('Enum value %s in XML (for extension %s) does' ' not end with a suitable vendor tag (such as\"%s\")' % ( elem_name, self.currentExtension, self.current_vendor_tag)) diff --git a/src/scripts/generate_runtime_manifest.py b/src/scripts/generate_runtime_manifest.py index 7c4544a96..8de78dacc 100755 --- a/src/scripts/generate_runtime_manifest.py +++ b/src/scripts/generate_runtime_manifest.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 # -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # diff --git a/src/scripts/loader_source_generator.py b/src/scripts/loader_source_generator.py index 82826f8f5..29eef0302 100755 --- a/src/scripts/loader_source_generator.py +++ b/src/scripts/loader_source_generator.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -i # -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # Copyright (c) 2017-2019 Valve Corporation # Copyright (c) 2017-2019 LunarG, Inc. # @@ -82,7 +82,7 @@ def getProto(self, cur_cmd): def outputGeneratedHeaderWarning(self): generated_warning = '' - generated_warning += '// Copyright (c) 2017-2022, The Khronos Group Inc.\n' + generated_warning += '// Copyright (c) 2017-2023, The Khronos Group Inc.\n' generated_warning += '// Copyright (c) 2017-2019 Valve Corporation\n' generated_warning += '// Copyright (c) 2017-2019 LunarG, Inc.\n' # Broken string is to avoid confusing the REUSE tool here. diff --git a/src/scripts/src_genxr.py b/src/scripts/src_genxr.py index 3171c164c..6bab4654d 100755 --- a/src/scripts/src_genxr.py +++ b/src/scripts/src_genxr.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 # -# Copyright 2013-2022 The Khronos Group Inc. +# Copyright 2013-2023 The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -99,7 +99,7 @@ def makeGenOpts(args): # Copyright text prefixing all headers (list of strings). prefixStrings = [ '/*', - '** Copyright (c) 2017-2022, The Khronos Group Inc.', + '** Copyright (c) 2017-2023, 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.', diff --git a/src/scripts/utility_source_generator.py b/src/scripts/utility_source_generator.py index 7d087e8b7..1db955b5d 100755 --- a/src/scripts/utility_source_generator.py +++ b/src/scripts/utility_source_generator.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -i # -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # Copyright (c) 2017-2019 Valve Corporation # Copyright (c) 2017-2019 LunarG, Inc. # @@ -30,7 +30,7 @@ class UtilitySourceOutputGenerator(AutomaticSourceOutputGenerator): # self the UtilitySourceOutputGenerator object def outputGeneratedHeaderWarning(self): generated_warning = '' - generated_warning += '// Copyright (c) 2017-2022, The Khronos Group Inc.\n' + generated_warning += '// Copyright (c) 2017-2023, The Khronos Group Inc.\n' generated_warning += '// Copyright (c) 2017-2019 Valve Corporation\n' generated_warning += '// Copyright (c) 2017-2019 LunarG, Inc.\n' # Broken string is to avoid confusing the REUSE tool here. diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index c6534ac2f..d4b367966 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -18,6 +18,7 @@ # add_subdirectory(hello_xr) +add_subdirectory(list_json) if(NOT ANDROID) add_subdirectory(c_compile_test) add_subdirectory(list) diff --git a/src/tests/c_compile_test/main.c b/src/tests/c_compile_test/main.c index b3e5e2633..56ab373d1 100644 --- a/src/tests/c_compile_test/main.c +++ b/src/tests/c_compile_test/main.c @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // // SPDX-License-Identifier: Apache-2.0 diff --git a/src/tests/hello_xr/AndroidManifest.xml b/src/tests/hello_xr/AndroidManifest.xml index 77673c930..7cc8a1c68 100644 --- a/src/tests/hello_xr/AndroidManifest.xml +++ b/src/tests/hello_xr/AndroidManifest.xml @@ -1,12 +1,12 @@ diff --git a/src/tests/hello_xr/android_resources/drawable/ic_helloxr_es.xml b/src/tests/hello_xr/android_resources/drawable/ic_helloxr_es.xml index 95953e09f..1e46db2de 100644 --- a/src/tests/hello_xr/android_resources/drawable/ic_helloxr_es.xml +++ b/src/tests/hello_xr/android_resources/drawable/ic_helloxr_es.xml @@ -9,7 +9,7 @@ android:translateX="23.75" android:translateY="24.3"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/list_json/CMakeLists.txt b/src/tests/list_json/CMakeLists.txt new file mode 100644 index 000000000..eb9a3f4b3 --- /dev/null +++ b/src/tests/list_json/CMakeLists.txt @@ -0,0 +1,84 @@ +# Copyright (c) 2017 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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: +# + +file(GLOB LOCAL_HEADERS "*.h") +file(GLOB LOCAL_SOURCE "*.cpp") + +# For including compiled shaders +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +if(ANDROID) + add_library(list_json MODULE + ${LOCAL_SOURCE} + ${LOCAL_HEADERS} + $) + target_link_libraries(list_json ${ANDROID_LIBRARY} ${ANDROID_LOG_LIBRARY}) + target_include_directories(list_json PRIVATE ${ANDROID_NATIVE_APP_GLUE}) +else() + add_executable(list_json + ${LOCAL_SOURCE} + ${LOCAL_HEADERS}) +endif() +set_target_properties(list_json PROPERTIES FOLDER ${SAMPLES_FOLDER}) + +source_group("Headers" FILES ${LOCAL_HEADERS}) +source_group("Shaders" FILES ${VULKAN_SHADERS}) + +target_include_directories(list_json + PRIVATE + ${PROJECT_SOURCE_DIR}/src + ${PROJECT_SOURCE_DIR}/src/common + + # for OpenXR headers + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_BINARY_DIR}/include +) + +if(Vulkan_FOUND) + target_include_directories(list_json + PRIVATE + ${Vulkan_INCLUDE_DIRS} + ) +endif() + +target_link_libraries(list_json openxr_loader) +if(WIN32) + if(MSVC) + target_compile_definitions(list_json PRIVATE _CRT_SECURE_NO_WARNINGS) + target_compile_options(list_json PRIVATE /Zc:wchar_t /Zc:forScope /W4 /WX) + endif() + target_link_libraries(list_json ole32) + if(MSVC) + # Right now can't build this on MinGW because of directxcolors, etc. + target_link_libraries(list_json d3d11 d3d12 d3dcompiler dxgi) + else() + target_compile_definitions(list_json PRIVATE MISSING_DIRECTX_COLORS) + endif() +endif() + +if(Vulkan_LIBRARY) + target_link_libraries(list_json ${Vulkan_LIBRARY}) +endif() + +if(NOT ANDROID) + install(TARGETS list_json + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT list_json) +endif() + diff --git a/src/tests/list_json/list_json.cpp b/src/tests/list_json/list_json.cpp new file mode 100644 index 000000000..78cb007b2 --- /dev/null +++ b/src/tests/list_json/list_json.cpp @@ -0,0 +1,331 @@ +// Copyright (c) 2017-2023, The Khronos Group Inc. +// +// SPDX-License-Identifier: Apache-2.0 + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif // defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) + +#include "xr_dependencies.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include // tolower +#include +#include + +#if defined(XR_USE_PLATFORM_ANDROID) +#include +#include + +#define LOG_TAG "list_json" +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) +#else // !defined(XR_USE_PLATFORM_ANDROID) +#define LOGE(...) fprintf(stderr, __VA_ARGS__) +#define LOGI(...) printf(__VA_ARGS__) +#endif // defined(XR_USE_PLATFORM_ANDROID) + +// The equivalent of C++17 std::size. A helper to get the dimension for an array. +template +constexpr size_t ArraySize(const T (&/*unused*/)[Size]) noexcept { + return Size; +} + +static std::string uint32_to_hex(uint32_t val) { + char buf[32]{0}; + snprintf(buf, sizeof(buf), "0x%08" PRIx32, val); + return std::string{buf}; +} + +static std::string vendorNameFromRuntimeName(const char* runtimeName) { + static constexpr std::pair vendorLookup[] = { + {"Qualcomm", "QUALCOMM"}, + {"PICO", "BYTEDANCE"}, + {"HTC", "HTC America, Inc."}, + {"Windows Mixed Reality", "Microsoft Corporation"}, + {"Oculus", "Meta Platforms"}, + {"SteamVR", "Valve Corporation"}, + {"Varjo", "Varjo Technologies Oy"}, + // Monado needs to appear last in this last as other vendors may be using + // Monado runtime for their headsets. + {"Monado", "Monado Community + Collabora, Ltd."}, + }; + + for (auto it : vendorLookup) { + if (strstr(runtimeName, it.first) != nullptr) { + return it.second; + } + } + + return "Unknown vendor (" + std::string(runtimeName) + ")"; +} + +static std::string viewConfigurationTypeName(XrViewConfigurationType config) { +#define AS_LIST(name, val) {name, #name}, + static constexpr std::pair KnownViewTypes[] = { + XR_LIST_ENUM_XrViewConfigurationType(AS_LIST)}; +#undef AS_LIST + + auto it = std::find_if(KnownViewTypes, KnownViewTypes + ArraySize(KnownViewTypes), + [&](const auto& vt) { return vt.first == config; }); + if (it != KnownViewTypes + ArraySize(KnownViewTypes)) { + return it->second; + } else { + return "Unknown XrViewConfigurationType (" + uint32_to_hex((uint32_t)config) + ")"; + } +} + +static std::string envBlendModeTypeName(XrEnvironmentBlendMode blendMode) { + // JSON schema for our files requires blend modes to be short strings rather than + // the spec strings. + + constexpr bool useShortBlendModes = true; + + if (useShortBlendModes) { + switch (blendMode) { + case XR_ENVIRONMENT_BLEND_MODE_OPAQUE: + return "OPAQUE"; + case XR_ENVIRONMENT_BLEND_MODE_ADDITIVE: + return "ADDITIVE"; + case XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND: + return "ALPHA_BLEND"; + default: + return "UNKNOWN"; + } + } else { +#define AS_LIST(name, val) {name, #name}, + static constexpr std::pair KnownBlendModes[] = { + XR_LIST_ENUM_XrEnvironmentBlendMode(AS_LIST)}; +#undef AS_LIST + + auto it = std::find_if(KnownBlendModes, KnownBlendModes + ArraySize(KnownBlendModes), + [&](const auto& vt) { return vt.first == blendMode; }); + if (it != KnownBlendModes + ArraySize(KnownBlendModes)) { + return it->second; + } else { + return "Unknown XrEnvironmentBlendMode (" + uint32_to_hex((uint32_t)blendMode) + ")"; + } + } +} + +static std::string stringFromXrVersion(XrVersion ver) { + char buf[128]{0}; + snprintf(buf, sizeof(buf), "%d.%d.%d", XR_VERSION_MAJOR(ver), XR_VERSION_MINOR(ver), XR_VERSION_PATCH(ver)); + return std::string{buf}; +} + +static int main_body() { + XrInstanceCreateInfo instanceCreateInfo = {XR_TYPE_INSTANCE_CREATE_INFO}; + strncpy(instanceCreateInfo.applicationInfo.applicationName, "OpenXR-Inventory List", XR_MAX_APPLICATION_NAME_SIZE); + instanceCreateInfo.applicationInfo.apiVersion = XR_CURRENT_API_VERSION; + + XrInstance instance = XR_NULL_HANDLE; + + if (xrCreateInstance(&instanceCreateInfo, &instance) != XR_SUCCESS) { + LOGE("Failed to create XR instance.\n"); + return 1; + } + + auto instanceDestroyer = [](XrInstance* instance) { + if (instance != XR_NULL_HANDLE) { + xrDestroyInstance(*instance); + } + }; + + std::unique_ptr wrapperInstance({&instance, instanceDestroyer}); + + XrInstanceProperties instanceProperties{XR_TYPE_INSTANCE_PROPERTIES}; + if (xrGetInstanceProperties(instance, &instanceProperties) != XR_SUCCESS) { + LOGE("Failed to get instance properties.\n"); + return 1; + } + + // TODO: might be a bit neater to use jsoncpp here. + + LOGI("{\n"); + std::string versionStr = stringFromXrVersion(instanceProperties.runtimeVersion); + LOGI(" \"notes\": \"Generated using list_json: '%s' (%s)\",\n", instanceProperties.runtimeName, versionStr.c_str()); + LOGI(" \"$schema\": \"../schema.json\",\n"); + LOGI(" \"name\": \"TODO\",\n"); + LOGI(" \"conformance_submission\": 0,\n"); + +#if defined(WIN32) + LOGI(" \"platform\": \"Windows (Desktop)\",\n"); +#elif defined(__ANDROID__) + LOGI(" \"platform\": \"Android (All-in-one)\",\n"); +#endif + + std::string vendorName = vendorNameFromRuntimeName(instanceProperties.runtimeName); + LOGI(" \"vendor\": \"%s\",\n", vendorName.c_str()); + + uint32_t size; + xrEnumerateInstanceExtensionProperties(nullptr, 0, &size, nullptr); + std::vector extensions(size, {XR_TYPE_EXTENSION_PROPERTIES}); + xrEnumerateInstanceExtensionProperties(nullptr, size, &size, extensions.data()); + + // remove XR_EXT_debug_utils + // The loader implements XR_EXT_debug_utils so it will always look like + // the runtime implements the extension... + auto const& debugUtilsIt = std::find_if(extensions.begin(), extensions.end(), + [](auto const& ext) { return strcmp(ext.extensionName, "XR_EXT_debug_utils") == 0; }); + if (debugUtilsIt != extensions.end()) { + extensions.erase(debugUtilsIt); + } + + // case insensitive sort first + // then we will print KHR, EXT and others in order after + std::sort(extensions.begin(), extensions.end(), [](auto const& a, auto const& b) { + return std::lexicographical_compare(a.extensionName, a.extensionName + strlen(a.extensionName), b.extensionName, + b.extensionName + strlen(b.extensionName), + [](char a, char b) { return tolower(a) < tolower(b); }); + }); + + // skip extensions which are not listed in openxr_reflection.h + auto isPublicExtension = [](const XrExtensionProperties& extension) -> bool { +#define MAKE_EXTENSION_NAME_LIST(NAME, NUM) #NAME, + static const std::vector publicExtensions = {XR_LIST_EXTENSIONS(MAKE_EXTENSION_NAME_LIST)}; +#undef MAKE_EXTENSION_NAME_LIST + return std::find_if(publicExtensions.begin(), publicExtensions.end(), [&](const char* extensionName) { + return strcmp(extensionName, extension.extensionName) == 0; + }) != publicExtensions.end(); + }; + + std::vector runtimePublicExtensions; + std::vector runtimeNonPublicExtensions; + std::copy_if(extensions.begin(), extensions.end(), std::back_inserter(runtimePublicExtensions), isPublicExtension); + std::copy_if(extensions.begin(), extensions.end(), std::back_inserter(runtimeNonPublicExtensions), + [isPublicExtension](const XrExtensionProperties& extension) { return !isPublicExtension(extension); }); + + auto hasPrefix = [](XrExtensionProperties const& props, const char* prefix) -> bool { + return strncmp(prefix, props.extensionName, strlen(prefix)) == 0; + }; + + LOGI(" \"extensions\": [\n"); + for (XrExtensionProperties extension : runtimePublicExtensions) { + if (hasPrefix(extension, "XR_KHR")) { + LOGI(" \"%s\",\n", extension.extensionName); + } + } + for (XrExtensionProperties extension : runtimePublicExtensions) { + if (hasPrefix(extension, "XR_EXT")) { + LOGI(" \"%s\",\n", extension.extensionName); + } + } + for (XrExtensionProperties extension : runtimePublicExtensions) { + if (!hasPrefix(extension, "XR_KHR") && !hasPrefix(extension, "XR_EXT")) { + LOGI(" \"%s\",\n", extension.extensionName); + } + } + LOGI(" ],\n"); + + constexpr bool writeNonPublicExtensions = false; + if (writeNonPublicExtensions) { + if (!runtimeNonPublicExtensions.empty()) { + LOGI(" \"private_extensions\": [\n"); + for (XrExtensionProperties extension : runtimeNonPublicExtensions) { + LOGI(" \"%s\",\n", extension.extensionName); + } + LOGI(" ],\n"); + } + } + + LOGI(" \"form_factors\": [\n"); + +#define AS_LIST(name, val) {name, #name}, + static constexpr std::pair KnownFormFactors[] = {XR_LIST_ENUM_XrFormFactor(AS_LIST)}; +#undef AS_LIST + + // Iterate over known form factors and list any form factors that are supported + for (auto formFactor : KnownFormFactors) { + // Get the default system for the HMD form factor. + XrSystemGetInfo systemGetInfo = {XR_TYPE_SYSTEM_GET_INFO}; + systemGetInfo.formFactor = formFactor.first; + + XrSystemId systemId; + if (xrGetSystem(instance, &systemGetInfo, &systemId) != XR_SUCCESS) { + continue; + } + + LOGI(" {\n"); + LOGI(" \"form_factor\": \"%s\",\n", formFactor.second); + LOGI(" \"view_configurations\": [\n"); + + uint32_t viewConfigurationCount = 0; + xrEnumerateViewConfigurations(instance, systemId, 0, &viewConfigurationCount, nullptr); + std::vector viewConfigurationTypes(viewConfigurationCount); + xrEnumerateViewConfigurations(instance, systemId, (uint32_t)viewConfigurationTypes.size(), &viewConfigurationCount, + viewConfigurationTypes.data()); + + for (auto const& config : viewConfigurationTypes) { + std::string configName = viewConfigurationTypeName(config); + LOGI(" {\n"); + LOGI(" \"view_configuration\": \"%s\",\n", configName.c_str()); + + uint32_t blendModeCount = 0; + xrEnumerateEnvironmentBlendModes(instance, systemId, config, 0, &blendModeCount, nullptr); + std::vector blendModes(blendModeCount); + xrEnumerateEnvironmentBlendModes(instance, systemId, config, (uint32_t)blendModes.size(), &blendModeCount, + blendModes.data()); + + LOGI(" \"environment_blend_modes\": [\n"); + for (auto const& blendMode : blendModes) { + std::string blendModeName = envBlendModeTypeName(blendMode); + LOGI(" \"%s\",\n", blendModeName.c_str()); + } + LOGI(" ]\n"); + + LOGI(" }\n"); + } + + LOGI(" ]\n"); + LOGI(" }\n"); + } + + LOGI(" ]\n"); + LOGI("}\n"); + + return 0; +} + +#if defined(XR_USE_PLATFORM_ANDROID) + +static void app_handle_cmd(struct android_app*, int32_t) {} + +void android_main(struct android_app* app) { + JNIEnv* Env; + app->activity->vm->AttachCurrentThread(&Env, nullptr); + + app->userData = nullptr; + app->onAppCmd = app_handle_cmd; + + PFN_xrInitializeLoaderKHR initializeLoader = nullptr; + if (XR_SUCCEEDED(xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR", (PFN_xrVoidFunction*)(&initializeLoader)))) { + XrLoaderInitInfoAndroidKHR loaderInitInfoAndroid{XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR}; + loaderInitInfoAndroid.applicationVM = app->activity->vm; + loaderInitInfoAndroid.applicationContext = app->activity->clazz; + initializeLoader(reinterpret_cast(&loaderInitInfoAndroid)); + } + + main_body(); + + ANativeActivity_finish(app->activity); + app->activity->vm->DetachCurrentThread(); +} + +#else // !defined(XR_USE_PLATFORM_ANDROID) + +int main() { main_body(); } + +#endif // defined(XR_USE_PLATFORM_ANDROID) diff --git a/src/tests/loader_test/loader_test.cpp b/src/tests/loader_test/loader_test.cpp index 58fa526c5..bf1de9d5f 100644 --- a/src/tests/loader_test/loader_test.cpp +++ b/src/tests/loader_test/loader_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -608,8 +608,7 @@ DEFINE_TEST(TestCreateDestroyInstance) { XrInstance instance = XR_NULL_HANDLE; XrResult create_result = XR_ERROR_VALIDATION_FAILURE; std::string current_test_string; - XrInstanceCreateInfo instance_create_info = {}; - instance_create_info.type = XR_TYPE_INSTANCE_CREATE_INFO; + XrInstanceCreateInfo instance_create_info = {XR_TYPE_INSTANCE_CREATE_INFO}; instance_create_info.applicationInfo = application_info; switch (test_num) { @@ -713,14 +712,12 @@ DEFINE_TEST(TestGetSystem) { strcpy(application_info.engineName, "Infinite Improbability Drive"); application_info.engineVersion = 42; application_info.apiVersion = XR_CURRENT_API_VERSION; - XrInstanceCreateInfo instance_create_info = {}; - instance_create_info.type = XR_TYPE_INSTANCE_CREATE_INFO; + XrInstanceCreateInfo instance_create_info = {XR_TYPE_INSTANCE_CREATE_INFO}; instance_create_info.applicationInfo = application_info; TEST_EQUAL(xrCreateInstance(&instance_create_info, &instance), XR_SUCCESS, "Creating instance") - XrSystemGetInfo system_get_info = {}; - system_get_info.type = XR_TYPE_SYSTEM_GET_INFO; + XrSystemGetInfo system_get_info = {XR_TYPE_SYSTEM_GET_INFO}; system_get_info.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY; XrSystemId systemId; @@ -762,8 +759,7 @@ DEFINE_TEST(TestCreateDestroySession) { app_info.engineVersion = 42; app_info.apiVersion = XR_CURRENT_API_VERSION; - XrInstanceCreateInfo instance_ci = {}; - instance_ci.type = XR_TYPE_INSTANCE_CREATE_INFO; + XrInstanceCreateInfo instance_ci = {XR_TYPE_INSTANCE_CREATE_INFO}; instance_ci.applicationInfo = app_info; std::string ext_name; @@ -790,9 +786,7 @@ DEFINE_TEST(TestCreateDestroySession) { TEST_EQUAL(xrCreateInstance(&instance_ci, &instance), XR_SUCCESS, "Creating instance") - XrSystemGetInfo system_get_info; - memset(&system_get_info, 0, sizeof(system_get_info)); - system_get_info.type = XR_TYPE_SYSTEM_GET_INFO; + XrSystemGetInfo system_get_info = {XR_TYPE_SYSTEM_GET_INFO}; system_get_info.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY; XrSystemId systemId; @@ -829,15 +823,13 @@ DEFINE_TEST(TestCreateDestroySession) { TEST_NOT_EQUAL(pfn_get_vulkan_graphics_requirements_khr, nullptr, "TestCreateDestroySession invalid xrGetVulkanGraphicsRequirementsKHR function pointer"); - XrGraphicsRequirementsVulkanKHR vulkan_graphics_requirements = {}; - vulkan_graphics_requirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR; - vulkan_graphics_requirements.next = nullptr; + XrGraphicsRequirementsVulkanKHR vulkan_graphics_requirements = {XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR}; TEST_EQUAL(pfn_get_vulkan_graphics_requirements_khr(instance, systemId, &vulkan_graphics_requirements), XR_SUCCESS, "TestCreateDestroySession calling xrGetVulkanGraphicsRequirementsKHR"); // TODO: Just need something other than NULL here for now (for validation). Eventually need // to correctly put in a valid pointer to an Display - vulkan_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR; + vulkan_graphics_binding = {XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR}; vulkan_graphics_binding.instance = VK_NULL_HANDLE; vulkan_graphics_binding.physicalDevice = VK_NULL_HANDLE; vulkan_graphics_binding.device = VK_NULL_HANDLE; @@ -849,13 +841,13 @@ DEFINE_TEST(TestCreateDestroySession) { #ifdef XR_USE_GRAPHICS_API_OPENGL #ifdef _WIN32 - XrGraphicsBindingOpenGLWin32KHR win32_gl_graphics_binding = {}; + XrGraphicsBindingOpenGLWin32KHR win32_gl_graphics_binding = {XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR}; #elif defined(OS_LINUX_XLIB) - XrGraphicsBindingOpenGLXlibKHR glx_gl_graphics_binding = {}; + XrGraphicsBindingOpenGLXlibKHR glx_gl_graphics_binding = {XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR}; #elif defined(OS_LINUX_XCB) || defined(OS_LINUX_XCB_GLX) - XrGraphicsBindingOpenGLXcbKHR xcb_gl_graphics_binding = {}; + XrGraphicsBindingOpenGLXcbKHR xcb_gl_graphics_binding = {XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR}; #elif defined(OS_LINUX_WAYLAND) - XrGraphicsBindingOpenGLWaylandKHR wayland_gl_graphics_binding = {}; + XrGraphicsBindingOpenGLWaylandKHR wayland_gl_graphics_binding = {XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR}; #endif if (g_graphics_api_to_use == GRAPHICS_API_OPENGL) { PFN_xrGetOpenGLGraphicsRequirementsKHR pfn_get_opengl_graphics_requirements_khr; @@ -864,28 +856,22 @@ DEFINE_TEST(TestCreateDestroySession) { XR_SUCCESS, "TestCreateDestroySession get xrGetOpenGLGraphicsRequirementsKHR function pointer"); TEST_NOT_EQUAL(pfn_get_opengl_graphics_requirements_khr, nullptr, "TestCreateDestroySession invalid xrGetOpenGLGraphicsRequirementsKHR function pointer"); - XrGraphicsRequirementsOpenGLKHR opengl_graphics_requirements = {}; - opengl_graphics_requirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR; - opengl_graphics_requirements.next = nullptr; + XrGraphicsRequirementsOpenGLKHR opengl_graphics_requirements = {XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR}; TEST_EQUAL(pfn_get_opengl_graphics_requirements_khr(instance, systemId, &opengl_graphics_requirements), XR_SUCCESS, "TestCreateDestroySession calling xrGetOpenGLGraphicsRequirementsKHR"); #ifdef _WIN32 - win32_gl_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR; graphics_binding = reinterpret_cast(&win32_gl_graphics_binding); #elif defined(OS_LINUX_XLIB) - glx_gl_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR; // TODO: Just need something other than NULL here for now (for validation). Eventually need // to correctly put in a valid pointer to an Display glx_gl_graphics_binding.xDisplay = reinterpret_cast(0xFFFFFFFF); graphics_binding = reinterpret_cast(&glx_gl_graphics_binding); #elif defined(OS_LINUX_XCB) || defined(OS_LINUX_XCB_GLX) - xcb_gl_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR; // TODO: Just need something other than NULL here for now (for validation). Eventually need // to correctly put in a valid pointer to an xcb_connection_t xcb_gl_graphics_binding.connection = reinterpret_cast(0xFFFFFFFF); graphics_binding = reinterpret_cast(&xcb_gl_graphics_binding); #elif defined(OS_LINUX_WAYLAND) - wayland_gl_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR; // TODO: Just need something other than NULL here for now (for validation). Eventually need // to correctly put in a valid pointer to an wl_display wayland_gl_graphics_binding.display = reinterpret_cast(0xFFFFFFFF); @@ -895,7 +881,7 @@ DEFINE_TEST(TestCreateDestroySession) { #endif // XR_USE_GRAPHICS_API_OPENGL #ifdef XR_USE_GRAPHICS_API_D3D11 - XrGraphicsBindingD3D11KHR d3d11_graphics_binding = {}; + XrGraphicsBindingD3D11KHR d3d11_graphics_binding = {XR_TYPE_GRAPHICS_BINDING_D3D11_KHR}; ID3D11Device* d3d_device = NULL; if (g_graphics_api_to_use == GRAPHICS_API_D3D) { PFN_xrGetD3D11GraphicsRequirementsKHR pfn_get_d3d11_reqs; @@ -904,16 +890,13 @@ DEFINE_TEST(TestCreateDestroySession) { XR_SUCCESS, "TestCreateDestroySession get xrGetD3D11GraphicsRequirementsKHR function pointer"); TEST_NOT_EQUAL(pfn_get_d3d11_reqs, nullptr, "TestCreateDestroySession invalid xrGetD3D11GraphicsRequirementsKHR function pointer"); - XrGraphicsRequirementsD3D11KHR d3d_reqs = {}; - d3d_reqs.type = XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR; - d3d_reqs.next = nullptr; + XrGraphicsRequirementsD3D11KHR d3d_reqs = {XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR}; TEST_EQUAL(pfn_get_d3d11_reqs(instance, systemId, &d3d_reqs), XR_SUCCESS, "TestCreateDestroySession calling xrGetD3D11GraphicsRequirementsKHR"); HRESULT res = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &d3d_device, NULL, NULL); TEST_EQUAL(res, S_OK, "TestCreateDestroySession creating D3D11 reference device") - d3d11_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_D3D11_KHR; d3d11_graphics_binding.device = d3d_device; graphics_binding = reinterpret_cast(&d3d11_graphics_binding); } @@ -922,8 +905,7 @@ DEFINE_TEST(TestCreateDestroySession) { if (graphics_binding != nullptr) { // Create a session for us to begin XrSession session; - XrSessionCreateInfo session_create_info = {}; - session_create_info.type = XR_TYPE_SESSION_CREATE_INFO; + XrSessionCreateInfo session_create_info = {XR_TYPE_SESSION_CREATE_INFO}; session_create_info.systemId = systemId; session_create_info.next = graphics_binding; TEST_EQUAL(xrCreateSession(instance, &session_create_info, &session), XR_SUCCESS, "xrCreateSession") @@ -1197,14 +1179,12 @@ DEFINE_TEST(TestDebugUtils) { app_info.engineVersion = 42; app_info.apiVersion = XR_CURRENT_API_VERSION; - XrInstanceCreateInfo instance_ci = {}; - instance_ci.type = XR_TYPE_INSTANCE_CREATE_INFO; + XrInstanceCreateInfo instance_ci = {XR_TYPE_INSTANCE_CREATE_INFO}; instance_ci.applicationInfo = app_info; char dbg_ext_name[] = XR_EXT_DEBUG_UTILS_EXTENSION_NAME; std::string gfx_name("None"); const char* ext_array[2]; - instance_ci.type = XR_TYPE_INSTANCE_CREATE_INFO; instance_ci.enabledExtensionCount = 2; instance_ci.enabledExtensionNames = ext_array; @@ -1229,8 +1209,7 @@ DEFINE_TEST(TestDebugUtils) { instance_ci.enabledExtensionNames = ext_array; // Create an instance with the appropriate data for the debug utils messenger - XrDebugUtilsMessengerCreateInfoEXT dbg_msg_ci = {}; - dbg_msg_ci.type = XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; + XrDebugUtilsMessengerCreateInfoEXT dbg_msg_ci = {XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; dbg_msg_ci.messageSeverities = XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT; @@ -1239,8 +1218,7 @@ DEFINE_TEST(TestDebugUtils) { dbg_msg_ci.userCallback = TestDebugUtilsCallback; // Create an instacne with the general information setup for a message - XrDebugUtilsMessengerCallbackDataEXT callback_data = {}; - callback_data.type = XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT; + XrDebugUtilsMessengerCallbackDataEXT callback_data = {XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; callback_data.messageId = &message_id[0]; callback_data.functionName = &test_function_name[0]; callback_data.message = &test_message[0]; @@ -1748,9 +1726,7 @@ DEFINE_TEST(TestDebugUtils) { num_objects_matches = false; object_contents_match = false; - XrSystemGetInfo system_get_info; - memset(&system_get_info, 0, sizeof(system_get_info)); - system_get_info.type = XR_TYPE_SYSTEM_GET_INFO; + XrSystemGetInfo system_get_info = {XR_TYPE_SYSTEM_GET_INFO}; system_get_info.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY; XrSystemId systemId; TEST_EQUAL(xrGetSystem(instance, &system_get_info, &systemId), XR_SUCCESS, "xrGetSystem"); @@ -1786,11 +1762,10 @@ DEFINE_TEST(TestDebugUtils) { TEST_NOT_EQUAL(pfn_get_vulkan_graphics_requirements_khr, nullptr, "TestDebugUtils invalid xrGetVulkanGraphicsRequirementsKHR function pointer"); - XrGraphicsRequirementsVulkanKHR vulkan_graphics_requirements = {}; + XrGraphicsRequirementsVulkanKHR vulkan_graphics_requirements = {XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR}; TEST_EQUAL(pfn_get_vulkan_graphics_requirements_khr(instance, systemId, &vulkan_graphics_requirements), XR_SUCCESS, "TestDebugUtils calling xrGetVulkanGraphicsRequirementsKHR"); - vulkan_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR; // TODO: Just need something other than NULL here for now (for validation). Eventually need // to correctly put in a valid pointer to an Display vulkan_graphics_binding.instance = VK_NULL_HANDLE; @@ -1803,13 +1778,13 @@ DEFINE_TEST(TestDebugUtils) { #endif // XR_USE_GRAPHICS_API_VULKAN #ifdef XR_USE_GRAPHICS_API_OPENGL #ifdef _WIN32 - XrGraphicsBindingOpenGLWin32KHR win32_gl_graphics_binding = {}; + XrGraphicsBindingOpenGLWin32KHR win32_gl_graphics_binding = {XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR}; #elif defined(OS_LINUX_XLIB) - XrGraphicsBindingOpenGLXlibKHR glx_gl_graphics_binding = {}; + XrGraphicsBindingOpenGLXlibKHR glx_gl_graphics_binding = {XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR}; #elif defined(OS_LINUX_XCB) || defined(OS_LINUX_XCB_GLX) - XrGraphicsBindingOpenGLXcbKHR xcb_gl_graphics_binding = {}; + XrGraphicsBindingOpenGLXcbKHR xcb_gl_graphics_binding = {XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR}; #elif defined(OS_LINUX_WAYLAND) - XrGraphicsBindingOpenGLWaylandKHR wayland_gl_graphics_binding = {}; + XrGraphicsBindingOpenGLWaylandKHR wayland_gl_graphics_binding = {XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR}; #endif if (g_graphics_api_to_use == GRAPHICS_API_OPENGL) { PFN_xrGetOpenGLGraphicsRequirementsKHR pfn_get_opengl_graphics_requirements_khr; @@ -1822,22 +1797,18 @@ DEFINE_TEST(TestDebugUtils) { TEST_EQUAL(pfn_get_opengl_graphics_requirements_khr(instance, systemId, &opengl_graphics_requirements), XR_SUCCESS, "TestDebugUtils calling xrGetOpenGLGraphicsRequirementsKHR"); #ifdef _WIN32 - win32_gl_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR; graphics_binding = reinterpret_cast(&win32_gl_graphics_binding); #elif defined(OS_LINUX_XLIB) - glx_gl_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR; // TODO: Just need something other than NULL here for now (for validation). Eventually need // to correctly put in a valid pointer to an Display glx_gl_graphics_binding.xDisplay = reinterpret_cast(0xFFFFFFFF); graphics_binding = reinterpret_cast(&glx_gl_graphics_binding); #elif defined(OS_LINUX_XCB) || defined(OS_LINUX_XCB_GLX) - xcb_gl_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR; // TODO: Just need something other than NULL here for now (for validation). Eventually need // to correctly put in a valid pointer to an xcb_connection_t xcb_gl_graphics_binding.connection = reinterpret_cast(0xFFFFFFFF); graphics_binding = reinterpret_cast(&xcb_gl_graphics_binding); #elif defined(OS_LINUX_WAYLAND) - wayland_gl_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR; // TODO: Just need something other than NULL here for now (for validation). Eventually need // to correctly put in a valid pointer to an wl_display wayland_gl_graphics_binding.display = reinterpret_cast(0xFFFFFFFF); @@ -1846,7 +1817,7 @@ DEFINE_TEST(TestDebugUtils) { } #endif // XR_USE_GRAPHICS_API_OPENGL #ifdef XR_USE_GRAPHICS_API_D3D11 - XrGraphicsBindingD3D11KHR d3d11_graphics_binding = {}; + XrGraphicsBindingD3D11KHR d3d11_graphics_binding = {XR_TYPE_GRAPHICS_BINDING_D3D11_KHR}; if (g_graphics_api_to_use == GRAPHICS_API_D3D) { PFN_xrGetD3D11GraphicsRequirementsKHR pfn_get_d3d11_graphics_requirements_khr; TEST_EQUAL(xrGetInstanceProcAddr(instance, "xrGetD3D11GraphicsRequirementsKHR", @@ -1863,13 +1834,6 @@ DEFINE_TEST(TestDebugUtils) { D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &d3d_device, NULL, NULL); TEST_EQUAL(res, S_OK, "TestDebugUtils creating D3D11 reference device") - d3d11_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_D3D11_KHR; - d3d11_graphics_binding.device = d3d_device; - graphics_binding = reinterpret_cast(&d3d11_graphics_binding); - - d3d11_graphics_binding.type = XR_TYPE_GRAPHICS_BINDING_D3D11_KHR; - // TODO: Just need something other than NULL here for now (for validation). Eventually need - // to correctly put in a valid pointer to an Display d3d11_graphics_binding.device = d3d_device; graphics_binding = reinterpret_cast(&d3d11_graphics_binding); } @@ -1898,14 +1862,12 @@ DEFINE_TEST(TestDebugUtils) { g_expecting_labels = true; // Create a label struct for initial testing - XrDebugUtilsLabelEXT first_label = {}; - first_label.type = XR_TYPE_DEBUG_UTILS_LABEL_EXT; + XrDebugUtilsLabelEXT first_label = {XR_TYPE_DEBUG_UTILS_LABEL_EXT}; first_label.labelName = g_first_individual_label_name; // Create a session for us to begin XrSession session; - XrSessionCreateInfo session_create_info = {}; - session_create_info.type = XR_TYPE_SESSION_CREATE_INFO; + XrSessionCreateInfo session_create_info = {XR_TYPE_SESSION_CREATE_INFO}; session_create_info.systemId = systemId; session_create_info.next = graphics_binding; @@ -1972,14 +1934,12 @@ DEFINE_TEST(TestDebugUtils) { TEST_EQUAL(g_captured_only_expected_labels, true, "TestDebugUtils - First Label Region : Captured Correct Labels") // Begin the session now. - XrSessionBeginInfo session_begin_info = {}; - session_begin_info.type = XR_TYPE_SESSION_BEGIN_INFO; + XrSessionBeginInfo session_begin_info = {XR_TYPE_SESSION_BEGIN_INFO}; session_begin_info.primaryViewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO; TEST_EQUAL(xrBeginSession(session, &session_begin_info), XR_SUCCESS, "xrBeginSession") - XrDebugUtilsLabelEXT individual_label = {}; - individual_label.type = XR_TYPE_DEBUG_UTILS_LABEL_EXT; + XrDebugUtilsLabelEXT individual_label = {XR_TYPE_DEBUG_UTILS_LABEL_EXT}; individual_label.labelName = g_second_individual_label_name; TEST_EQUAL(pfn_insert_debug_utils_label_ext(session, &individual_label), XR_SUCCESS, "TestDebugUtils calling xrSessionInsertDebugUtilsLabelEXT"); @@ -2015,8 +1975,7 @@ DEFINE_TEST(TestDebugUtils) { "TestDebugUtils - Third Individual and First Region : Captured Correct Labels") // Begin a label region - XrDebugUtilsLabelEXT second_label_region = {}; - second_label_region.type = XR_TYPE_DEBUG_UTILS_LABEL_EXT; + XrDebugUtilsLabelEXT second_label_region = {XR_TYPE_DEBUG_UTILS_LABEL_EXT}; second_label_region.labelName = g_second_label_region_name; TEST_EQUAL(pfn_begin_debug_utils_label_region_ext(session, &second_label_region), XR_SUCCESS, "TestDebugUtils calling xrSessionBeginDebugUtilsLabelRegionEXT"); diff --git a/src/tests/loader_test/loader_test_utils.cpp b/src/tests/loader_test/loader_test_utils.cpp index 86f5e244a..583cc4b79 100644 --- a/src/tests/loader_test/loader_test_utils.cpp +++ b/src/tests/loader_test/loader_test_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/src/tests/loader_test/test_layers/layer_test.cpp b/src/tests/loader_test/test_layers/layer_test.cpp index 40caf3827..2f8131c72 100644 --- a/src/tests/loader_test/test_layers/layer_test.cpp +++ b/src/tests/loader_test/test_layers/layer_test.cpp @@ -104,8 +104,8 @@ XRAPI_ATTR XrResult XRAPI_CALL LayerTestXrCreateApiLayerInstance(const XrInstanc // Function used to negotiate an interface betewen the loader and a layer. Each library exposing one or // more layers needs to expose at least this function. -LAYER_EXPORT XrResult xrNegotiateLoaderApiLayerInterface(const XrNegotiateLoaderInfo *loaderInfo, const char *layerName, - XrNegotiateApiLayerRequest *layerRequest) { +LAYER_EXPORT XrResult XRAPI_CALL xrNegotiateLoaderApiLayerInterface(const XrNegotiateLoaderInfo *loaderInfo, const char *layerName, + XrNegotiateApiLayerRequest *layerRequest) { if (nullptr == loaderInfo || nullptr == layerRequest || loaderInfo->structType != XR_LOADER_INTERFACE_STRUCT_LOADER_INFO || loaderInfo->structVersion != XR_LOADER_INFO_STRUCT_VERSION || loaderInfo->structSize != sizeof(XrNegotiateLoaderInfo) || layerRequest->structType != XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST || diff --git a/src/version.cmake b/src/version.cmake index 18b73c71e..d863918df 100644 --- a/src/version.cmake +++ b/src/version.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # diff --git a/src/version.gradle b/src/version.gradle index e31eb5964..32cf7bf3d 100644 --- a/src/version.gradle +++ b/src/version.gradle @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2022, The Khronos Group Inc. +// Copyright (c) 2020-2023, The Khronos Group Inc. // // SPDX-License-Identifier: Apache-2.0 diff --git a/tox.ini b/tox.ini index bf9cf26db..f35118913 100644 --- a/tox.ini +++ b/tox.ini @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022, The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 # tox (https://tox.readthedocs.io/) is a tool for running tests