diff --git a/.azure-pipelines/shared/generate_windows_matrix_build.py b/.azure-pipelines/shared/generate_windows_matrix_build.py index b74409b7..0f462201 100644 --- a/.azure-pipelines/shared/generate_windows_matrix_build.py +++ b/.azure-pipelines/shared/generate_windows_matrix_build.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2019 The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 from itertools import product diff --git a/.azure-pipelines/shared/install_vulkan.ps1 b/.azure-pipelines/shared/install_vulkan.ps1 index aee09e94..c1f2ab59 100644 --- a/.azure-pipelines/shared/install_vulkan.ps1 +++ b/.azure-pipelines/shared/install_vulkan.ps1 @@ -1,4 +1,4 @@ -# Copyright (c) 2019 The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 if (-not $env:VULKAN_SDK_VERSION) { diff --git a/.azure-pipelines/shared/organize_windows_artifacts.py b/.azure-pipelines/shared/organize_windows_artifacts.py index fc80354d..d59c53be 100644 --- a/.azure-pipelines/shared/organize_windows_artifacts.py +++ b/.azure-pipelines/shared/organize_windows_artifacts.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2019 The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 from itertools import product diff --git a/.azure-pipelines/shared/print_windows_artifact_names.py b/.azure-pipelines/shared/print_windows_artifact_names.py index f7ab0da6..d58bfdfc 100644 --- a/.azure-pipelines/shared/print_windows_artifact_names.py +++ b/.azure-pipelines/shared/print_windows_artifact_names.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2019 The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 from itertools import product diff --git a/.azure-pipelines/shared/shared.py b/.azure-pipelines/shared/shared.py index aae8cb70..4276880c 100644 --- a/.azure-pipelines/shared/shared.py +++ b/.azure-pipelines/shared/shared.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019 The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 import json diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 5519b09d..9925f530 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -9,8 +9,11 @@ # and do try to make sure that the bulk change is made # **separate from a release commit** on all repos. # See -# for how to use this. +# for how to use this, probably something like: +# git config blame.ignoreRevsFile .git-blame-ignore-revs +## Old changes +767537d9523253de1615b01450a8b22c8e2cc6a2 ## 1.0.17 - Fix XML indentation diff --git a/.github/scripts/generate_windows_matrix_build.py b/.github/scripts/generate_windows_matrix_build.py index ef2d153b..f8538b87 100644 --- a/.github/scripts/generate_windows_matrix_build.py +++ b/.github/scripts/generate_windows_matrix_build.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2019 The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 from itertools import product diff --git a/.github/scripts/shared.py b/.github/scripts/shared.py index c9303515..b9ab2e95 100644 --- a/.github/scripts/shared.py +++ b/.github/scripts/shared.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019 The Khronos Group Inc. +# Copyright (c) 2019-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 import json diff --git a/.gitignore b/.gitignore index 13a23f16..fbafc27f 100644 --- a/.gitignore +++ b/.gitignore @@ -54,6 +54,7 @@ local.properties # Don't ignore these things !.*.license +!.artifact-bot.md !.appveyor.yml !.azure-pipelines/ !.azure-pipelines/nuget/NugetTemplate/build diff --git a/.reuse/dep5 b/.reuse/dep5 index cefd0765..3df6553a 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -3,7 +3,12 @@ Upstream-Name: OpenXR Upstream-Contact: Ryan Pavlik Source: https://khronos.org/registry/OpenXR/ -Files: changes/* +Files: changes/conformance/* + changes/registry/* + changes/sdk/* + changes/specification/* + changes/README.md + changes/template.md HOTFIX Copyright: 2019-2023, The Khronos Group Inc. License: CC-BY-4.0 @@ -30,25 +35,22 @@ Comment: Based on a Material Icons asset ("emoji-people") with added text Rasterized with Android Studio. Files: src/external/catch2/* -Copyright: Copyright (c) 2022 Two Blue Cubes Ltd. +Copyright: Copyright (c) 2023 Two Blue Cubes Ltd. License: BSL-1.0 -Comment: Unmodified, vendored copy of Catch2 3.1.1 +Comment: Unmodified, vendored copy of Catch2 v3.3.2 Files: src/external/jsoncpp/* Copyright: 2007-2010 Baptiste Lepilleur and The JsonCpp Authors License: MIT OR LicenseRef-jsoncpp-public-domain Comment: Unmodified, vendored copy of jsoncpp 1.9.5 -Files: src/external/tinygltf/* -Copyright: 2017 Syoyo Fujita, Aurélien Chatelain and many contributors +Files: src/external/tinygltf/README.md + src/external/tinygltf/tiny_gltf.cc + src/external/tinygltf/tiny_gltf.h +Copyright: 2015-Present, Syoyo Fujita, Aurélien Chatelain and many contributors License: MIT Comment: Unmodified, vendored copy of a subset of the tiny-gltf repo v2.8.9 -Files: src/external/tinygltf/json.hpp -Copyright: 2013-2017 Niels Lohmann -License: MIT -Comment: Unmodified, included in tiny-gltf repo. - Files: src/external/d3dx12/* Copyright: Copyright (c) Microsoft Corporation. License: MIT @@ -82,11 +84,6 @@ Copyright: 2020, Epic Games, Inc. License: CC-BY-4.0 Comment: In-line license comments requested, https://gitlab.khronos.org/openxr/openxr/-/issues/1422 -Files: specification/sources/chapters/extensions/oculus/oculus_android_session_state_enable.adoc -Copyright: 2019, Oculus VR, LLC. -License: CC-BY-4.0 -Comment: In-line license comments requested, https://gitlab.khronos.org/openxr/openxr/-/issues/1418 - Files: specification/sources/chapters/extensions/ext/ext_performance_settings.adoc specification/sources/chapters/extensions/ext/ext_thermal_query.adoc Copyright: 2017-2023, The Khronos Group Inc. diff --git a/HOTFIX b/HOTFIX deleted file mode 100644 index 0cfbf088..00000000 --- a/HOTFIX +++ /dev/null @@ -1 +0,0 @@ -2 diff --git a/changes/conformance/mr.2387.gl.md b/changes/conformance/mr.2387.gl.md new file mode 100644 index 00000000..988c6921 --- /dev/null +++ b/changes/conformance/mr.2387.gl.md @@ -0,0 +1,4 @@ +--- +- mr.2858.gl +--- +New test: Verify two-call idiom behavior of `XR_MSFT_controller_model` as well as handling of invalid model keys. diff --git a/changes/conformance/mr.2672.gl.md b/changes/conformance/mr.2672.gl.md new file mode 100644 index 00000000..a703b406 --- /dev/null +++ b/changes/conformance/mr.2672.gl.md @@ -0,0 +1 @@ +Improvement: Add non-interactive test for XR_EXT_palm_pose vendor extension. diff --git a/changes/conformance/mr.2685.gl.md b/changes/conformance/mr.2685.gl.md new file mode 100644 index 00000000..c77f7c89 --- /dev/null +++ b/changes/conformance/mr.2685.gl.md @@ -0,0 +1,4 @@ +--- +- issue.1978.gl +--- +Improvement: Refactor and standardize creation of swapchain image format tables, fixing some Vulkan invalid usage. diff --git a/changes/conformance/mr.2704.gl.md b/changes/conformance/mr.2704.gl.md index 71b2bf72..a792439d 100644 --- a/changes/conformance/mr.2704.gl.md +++ b/changes/conformance/mr.2704.gl.md @@ -2,5 +2,6 @@ - mr.2784.gl - mr.2785.gl - mr.2808.gl +- mr.2809.gl --- Improvement: Cleanup and code quality work. diff --git a/changes/conformance/mr.2729.gl.md b/changes/conformance/mr.2729.gl.md index 95e4d03c..7e44ad1a 100644 --- a/changes/conformance/mr.2729.gl.md +++ b/changes/conformance/mr.2729.gl.md @@ -1 +1,5 @@ +--- +- mr.2795.gl +- mr.2858.gl +--- Improvement: Add joint query to non-interactive test for `XR_EXT_hand_tracking`. diff --git a/changes/conformance/mr.2737.gl.md b/changes/conformance/mr.2737.gl.md index 869cf7aa..1f289d4d 100644 --- a/changes/conformance/mr.2737.gl.md +++ b/changes/conformance/mr.2737.gl.md @@ -1 +1,4 @@ +--- +- issue.1932.gl +--- Improvement: Migrate more tests to use the `SKIP` macro when appropriate. diff --git a/changes/conformance/mr.2756.gl.md b/changes/conformance/mr.2756.gl.md index fef78530..ddfb77dc 100644 --- a/changes/conformance/mr.2756.gl.md +++ b/changes/conformance/mr.2756.gl.md @@ -1 +1,4 @@ +--- +- issue.1387.gl +--- Fix: Do not use Catch2 assertion macros in graphics plugin methods that may be called before the first test case execution begins. diff --git a/changes/conformance/mr.2766.gl.md b/changes/conformance/mr.2766.gl.md index 7a0fd1ec..944b119d 100644 --- a/changes/conformance/mr.2766.gl.md +++ b/changes/conformance/mr.2766.gl.md @@ -1 +1 @@ -Fix spelling. +Fix: spelling. diff --git a/changes/conformance/mr.2775.gl.md b/changes/conformance/mr.2775.gl.md new file mode 100644 index 00000000..c2164b35 --- /dev/null +++ b/changes/conformance/mr.2775.gl.md @@ -0,0 +1 @@ +Improvement: Add additional tests for XR_EXT_debug_utils based on the test app loader_test. diff --git a/changes/conformance/mr.2850.gl.md b/changes/conformance/mr.2850.gl.md new file mode 100644 index 00000000..85701ee8 --- /dev/null +++ b/changes/conformance/mr.2850.gl.md @@ -0,0 +1 @@ +Fix building CTS with mingw compiler. diff --git a/maintainer-scripts/common.sh b/maintainer-scripts/common.sh index 37043223..065300c2 100644 --- a/maintainer-scripts/common.sh +++ b/maintainer-scripts/common.sh @@ -34,7 +34,7 @@ makeSubset() { } -COMMON_FILES=".gitignore .gitattributes .git-blame-ignore-revs CODE_OF_CONDUCT.md LICENSES .reuse .editorconfig" +COMMON_FILES=".gitignore .gitattributes .git-blame-ignore-revs CODE_OF_CONDUCT.md LICENSES .reuse .editorconfig HOTFIX" export COMMON_FILES COMMON_EXCLUDE_PATTERN="KhronosExperimental" export COMMON_EXCLUDE_PATTERN diff --git a/specification/Makefile b/specification/Makefile index 5b69343d..fcf69338 100644 --- a/specification/Makefile +++ b/specification/Makefile @@ -32,7 +32,7 @@ ifneq (,$(strip $(VERY_STRICT))) ASCIIDOC := $(ASCIIDOC) --failure-level WARN endif -SPECREVISION = 1.0.28 +SPECREVISION = 1.0.29 REVISION_COMPONENTS = $(subst ., ,$(SPECREVISION)) MAJORMINORVER = $(word 1,$(REVISION_COMPONENTS)).$(word 2,$(REVISION_COMPONENTS)) @@ -384,26 +384,14 @@ BACKEND_ARGS=--backend html5 $(ASCIIDOCTOR_TARGETS): $(ECHO) "[asciidoctor] $(SPECSRC) -> $(call MAKE_RELATIVE,$@)" $(QUIET)$(MKDIR) "$(@D)" - $(QUIET)if [ $$(uname -s | cut -c 1-6) == "CYGWIN" ]; then \ - OUTSPEC_DOS=$$(cygpath -w $@) ;\ - SPECSRC_DOS=$$(cygpath -w $(SPECSRC)) ;\ - ATTRIBOPTS_DOS='$(ATTRIBOPTS)' ;\ - ADOCOPTS_DOS="--doctype book -a data-uri -r $$(cygpath -w $(CURDIR)/scripts/spec-macros.rb) $$ATTRIBOPTS_DOS" ;\ - BATCH_FILE=$$(cygpath -w $$(mktemp)).bat ;\ - echo $(ASCIIDOC) $$ADOCOPTS_DOS $(BACKEND_ARGS) --out-file $$OUTSPEC_DOS $$SPECSRC_DOS > $$BATCH_FILE ;\ - CMD /C $$BATCH_FILE ;\ - rm -f $$BATCH_FILE ;\ - else \ - $(ASCIIDOC) $(ADOCOPTS) $(BACKEND_ARGS) --out-file $@ $(SPECSRC) 2>&1 | tee $(LOGFILE) ;\ - if [ -s $(LOGFILE) ]; then \ + $(QUIET)$(ASCIIDOC) $(ADOCOPTS) $(BACKEND_ARGS) --out-file $@ $(SPECSRC) 2>&1 | tee $(LOGFILE) + $(QUIET)if [ -s $(LOGFILE) ]; then \ echo "Failure: $(LOGFILE) exists and is not empty!"; \ false; \ else \ rm $(LOGFILE); \ - fi; \ fi $(POSTPROCESS) -# TODO: Postprocess step(s) may have broken the Cygwin build. Not sure this matters anymore with WSL, though. ################################################ diff --git a/specification/registry/xr.xml b/specification/registry/xr.xml index 0fccc519..add5a2c7 100644 --- a/specification/registry/xr.xml +++ b/specification/registry/xr.xml @@ -62,6 +62,7 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + @@ -131,7 +132,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, 28) +#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 0, 29) typedef XrFlags64 XrPerformanceMetricsCounterFlagsMETA; + + typedef XrFlags64 XrPassthroughPreferenceFlagsMETA; + typedef XrFlags64 XrFoveationDynamicFlagsHTC; @@ -544,6 +548,9 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + @@ -1465,11 +1472,14 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrBlendFactorFB dstFactorAlpha + + typedef void *(*PFN_xrEglGetProcAddressMNDX)(const char *name); + XrStructureType type const void* next - PFNEGLGETPROCADDRESSPROC getProcAddress + PFN_xrEglGetProcAddressMNDX getProcAddress EGLDisplay display EGLConfig config EGLContext context @@ -2859,6 +2869,13 @@ maintained in the default branch of the Khronos OpenXR GitHub project. float floatValue + + + XrStructureType type + const void* next + XrPassthroughPreferenceFlagsMETA flags + + XrStructureType type @@ -4104,6 +4121,11 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + @@ -5589,6 +5611,13 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrPerformanceMetricsCounterMETA* counter + + + XrResult xrGetPassthroughPreferencesMETA + XrSession session + XrPassthroughPreferencesMETA* preferences + + XrResult xrApplyFoveationHTC @@ -6063,6 +6092,10 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + @@ -7720,7 +7753,7 @@ maintained in the default branch of the Khronos OpenXR GitHub project. - + @@ -9116,10 +9149,18 @@ maintained in the default branch of the Khronos OpenXR GitHub project. - + - - + + + + + + + + + + @@ -11343,6 +11384,188 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/specification/scripts/genRef.py b/specification/scripts/genRef.py index b5dfa189..5a72a6ac 100644 --- a/specification/scripts/genRef.py +++ b/specification/scripts/genRef.py @@ -75,10 +75,12 @@ def printCopyrightSourceComments(fp): Writes an asciidoc comment block, which copyrights the source file.""" + # REUSE-IgnoreStart print('// Copyright 2014-2023 The Khronos Group Inc.', file=fp) print('//', file=fp) # This works around constraints of the 'reuse' tool print('// SPDX' + '-License-Identifier: CC-BY-4.0', file=fp) + # REUSE-IgnoreEnd print('', file=fp) diff --git a/specification/scripts/genxr.py b/specification/scripts/genxr.py index 2ddbda1e..875de43a 100755 --- a/specification/scripts/genxr.py +++ b/specification/scripts/genxr.py @@ -105,6 +105,7 @@ def makeGenOpts(args): emitExtensionsPat = makeREstring(emitExtensions, allExtensions) featuresPat = makeREstring(features, allFeatures) + # REUSE-IgnoreStart # Copyright text prefixing all headers (list of strings). prefixStrings = [ '/*', @@ -115,6 +116,7 @@ def makeGenOpts(args): '*/', '' ] + # REUSE-IgnoreEnd # Text specific to OpenXR headers xrPrefixStrings = [ diff --git a/specification/scripts/spec-macros/extension.rb b/specification/scripts/spec-macros/extension.rb index 08f953ca..be76084c 100644 --- a/specification/scripts/spec-macros/extension.rb +++ b/specification/scripts/spec-macros/extension.rb @@ -270,13 +270,14 @@ class BasetypeInlineMacro < LinkInlineMacroBase named :basetype match /basetype:(\w+)/ - # def process parent, target, attributes - # if parent.document.attributes['cross-file-links'] - # return Inline.new(parent, :anchor, target, :type => :link, :target => (target + '.html')) - # else - # return Inline.new(parent, :anchor, '' + target + '', :type => :xref, :target => ('#' + target), :attributes => {'fragment' => target, 'refid' => target}) - # end - # end + def process parent, target, attributes + node = super parent, target, attributes + if parent.document.attributes['cross-file-links'] + node + else + create_inline parent, :quoted, %(#{node.convert}) + end + end def exists? target $apiNames.basetypes.has_key? target diff --git a/specification/scripts/validitygenerator.py b/specification/scripts/validitygenerator.py index 495ae026..b121f705 100644 --- a/specification/scripts/validitygenerator.py +++ b/specification/scripts/validitygenerator.py @@ -1024,6 +1024,8 @@ def makeStructureTypeValidity(self, structname): child_structs = self.keepOnlyRequired(self.struct_children.get(structname, []), self.registry.typedict) if child_structs: + if values: + print('The struct: {} has children, it may not have a "values" attribute itself.'.format(structname)) assert(not values) if len(child_structs) > 1: entry += 'one of the following XrStructureType values: ' diff --git a/specification/scripts/xrconventions.py b/specification/scripts/xrconventions.py index 6fe3d307..2d59c0c5 100644 --- a/specification/scripts/xrconventions.py +++ b/specification/scripts/xrconventions.py @@ -22,7 +22,7 @@ (?POpenGL(ES)?)| # OpenGL and OpenGLES as words (?P[0-9]D)| # Things like 2D are words (?P # Normal-ish words, which are.... - ([A-Z]([a-z]+([0-9](?!D))*)+)| # Capital letter followed by at least one lowercase letter, possibly ending in some digits as long as the digits aren't followed by "D" + ([A-Z]([a-z]+([0-9](?!D[A-Z]{1}))*)+)| # Capital letter followed by at least one lowercase letter, possibly ending in some digits as long as the digits aren't followed by a "D" then another word ([A-Z][A-Z0-9]+(?![a-z])) # Or, all-caps letter and digit mix starting with a letter, excluding the last capital before some lowercase )''', re.VERBOSE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f8af1a0d..b952079a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -305,12 +305,10 @@ function(compile_glsl run_target_name) endfunction() -if(WIN32) +# Not available in MinGW +if(MSVC) add_definitions(-DXR_USE_GRAPHICS_API_D3D11) - if(MSVC) - # Not available in MinGW right now - add_definitions(-DXR_USE_GRAPHICS_API_D3D12) - endif() + add_definitions(-DXR_USE_GRAPHICS_API_D3D12) endif() # Check for the existence of the secure_getenv or __secure_getenv commands @@ -408,16 +406,34 @@ set(GENERATED_OUTPUT) set(GENERATED_DEPENDS) run_xr_xml_generate(utility_source_generator.py xr_generated_dispatch_table.h) run_xr_xml_generate(utility_source_generator.py xr_generated_dispatch_table.c) -if(GENERATED_DEPENDS) - add_custom_target(xr_global_generated_files DEPENDS ${GENERATED_DEPENDS}) +set(COMMON_GENERATED_OUTPUT ${GENERATED_OUTPUT}) +set(COMMON_GENERATED_DEPENDS ${GENERATED_DEPENDS}) +unset(GENERATED_OUTPUT) +unset(GENERATED_DEPENDS) + +run_xr_xml_generate(utility_source_generator.py xr_generated_dispatch_table_core.h) +run_xr_xml_generate(utility_source_generator.py xr_generated_dispatch_table_core.c) +set(LOADER_GENERATED_OUTPUT ${GENERATED_OUTPUT}) +set(LOADER_GENERATED_DEPENDS ${GENERATED_DEPENDS}) +unset(GENERATED_OUTPUT) +unset(GENERATED_DEPENDS) + +if(LOADER_GENERATED_DEPENDS) + add_custom_target(xr_global_generated_files DEPENDS ${LOADER_GENERATED_DEPENDS}) else() add_custom_target(xr_global_generated_files) endif() set_target_properties(xr_global_generated_files PROPERTIES FOLDER ${CODEGEN_FOLDER}) -set(COMMON_GENERATED_OUTPUT ${GENERATED_OUTPUT}) -set(COMMON_GENERATED_DEPENDS ${GENERATED_DEPENDS}) +if(COMMON_GENERATED_DEPENDS) + add_custom_target(xr_common_generated_files DEPENDS ${COMMON_GENERATED_DEPENDS}) +else() + add_custom_target(xr_common_generated_files) +endif() + +set_target_properties(xr_common_generated_files PROPERTIES FOLDER ${CODEGEN_FOLDER}) + if(NOT MSVC) include(CheckCXXCompilerFlag) include(CheckCCompilerFlag) diff --git a/src/common/gfxwrapper_opengl.c b/src/common/gfxwrapper_opengl.c index 8b5c0899..413dc514 100644 --- a/src/common/gfxwrapper_opengl.c +++ b/src/common/gfxwrapper_opengl.c @@ -1,4 +1,5 @@ /* +Copyright (c) 2017-2023, The Khronos Group Inc. Copyright (c) 2016 Oculus VR, LLC. Portions of macOS, iOS, functionality copyright (c) 2016 The Brenwill Workshop Ltd. diff --git a/src/common/gfxwrapper_opengl.h b/src/common/gfxwrapper_opengl.h index a4c245d3..6d8e1518 100644 --- a/src/common/gfxwrapper_opengl.h +++ b/src/common/gfxwrapper_opengl.h @@ -1,35 +1,33 @@ +// Copyright (c) 2017-2023, The Khronos Group Inc. +// Copyright (c) 2016, Oculus VR, LLC. +// Portions of macOS, iOS, functionality copyright (c) 2016, The Brenwill Workshop Ltd. +// +// 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. + +/* REUSE-IgnoreStart */ +/* The following has copyright notices that duplicate the header above */ + /* ================================================================================================ -Description : Convenient wrapper for the OpenGL API. -Author : J.M.P. van Waveren -Date : 12/21/2014 -Language : C99 -Format : Real tabs with the tab size equal to 4 spaces. -Copyright : Copyright (c) 2016 Oculus VR, LLC. All Rights reserved. - : Portions copyright (c) 2016 The Brenwill Workshop Ltd. All Rights reserved. - - -LICENSE -======= - -Copyright (c) 2016 Oculus VR, LLC. -Portions of macOS, iOS, functionality copyright (c) 2016 The Brenwill Workshop Ltd. - -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 : Convenient wrapper for the OpenGL API. +Orig. Author : J.M.P. van Waveren +Orig. Date : 12/21/2014 +Language : C99 +Copyright : Copyright (c) 2016 Oculus VR, LLC. All Rights reserved. + : Portions copyright (c) 2016 The Brenwill Workshop Ltd. All Rights reserved. IMPLEMENTATION ============== diff --git a/src/common/platform_utils.hpp b/src/common/platform_utils.hpp index 219d1978..883baef8 100644 --- a/src/common/platform_utils.hpp +++ b/src/common/platform_utils.hpp @@ -37,6 +37,44 @@ #include "common_config.h" #endif // OPENXR_HAVE_COMMON_CONFIG +#if defined(__x86_64__) && defined(__ILP32__) +#define XR_ARCH_ABI "x32" +#elif defined(_M_X64) || defined(__x86_64__) +#define XR_ARCH_ABI "x86_64" +#elif defined(_M_IX86) || defined(__i386__) || defined(_X86_) +#define XR_ARCH_ABI "i686" +#elif (defined(__aarch64__) && defined(__LP64__)) || defined(_M_ARM64) +#define XR_ARCH_ABI "aarch64" +#elif (defined(__ARM_ARCH) && __ARM_ARCH >= 7 && (defined(__ARM_PCS_VFP) || defined(__ANDROID__))) || defined(_M_ARM) +#define XR_ARCH_ABI "armv7a-vfp" +#elif defined(__ARM_ARCH_5TE__) +#define XR_ARCH_ABI "armv5te" +#elif defined(__mips64) +#define XR_ARCH_ABI "mips64" +#elif defined(__mips) +#define XR_ARCH_ABI "mips" +#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define XR_ARCH_ABI "ppc64" +#elif defined(__powerpc__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define XR_ARCH_ABI "ppc64el" +#elif defined(__s390x__) || defined(__zarch__) +#define XR_ARCH_ABI "s390x" +#elif defined(__hppa__) +#define XR_ARCH_ABI "hppa" +#elif defined(__alpha__) +#define XR_ARCH_ABI "alpha" +#elif defined(__ia64__) || defined(_M_IA64) +#define XR_ARCH_ABI "ia64" +#elif defined(__m68k__) +#define XR_ARCH_ABI "m68k" +#elif defined(__riscv_xlen) && (__riscv_xlen == 64) +#define XR_ARCH_ABI "riscv64" +#elif defined(__sparc__) && defined(__arch64__) +#define XR_ARCH_ABI "sparc64" +#else +#error "No architecture string known!" +#endif + // Consumers of this file must ensure this function is implemented. For example, the loader will implement this function so that it // can route messages through the loader's logging system. void LogPlatformUtilsError(const std::string& message); @@ -47,6 +85,7 @@ void LogPlatformUtilsError(const std::string& message); #include #include #include +#include namespace detail { @@ -72,6 +111,31 @@ static inline char* ImplGetSecureEnv(const char* name) { } // namespace detail #endif // defined(XR_OS_LINUX) || defined(XR_OS_APPLE) + +#if defined(XR_OS_ANDROID) || defined(XR_OS_APPLE) + +#include + +namespace detail { + +static inline bool ImplTryRuntimeFilename(const char* rt_dir_prefix, uint16_t major_version, std::string& file_name) { + auto decorated_path = rt_dir_prefix + std::to_string(major_version) + "/active_runtime." XR_ARCH_ABI ".json"; + auto undecorated_path = rt_dir_prefix + std::to_string(major_version) + "/active_runtime.json"; + + struct stat buf {}; + if (0 == stat(decorated_path.c_str(), &buf)) { + file_name = decorated_path; + return true; + } + if (0 == stat(undecorated_path.c_str(), &buf)) { + file_name = undecorated_path; + return true; + } + return false; +} + +} // namespace detail +#endif // defined(XR_OS_ANDROID) || defined(XR_OS_APPLE) #if defined(XR_OS_LINUX) static inline std::string PlatformUtilsGetEnv(const char* name) { @@ -130,15 +194,8 @@ static inline bool PlatformUtilsSetEnv(const char* name, const char* value) { return (result == 0); } -// Prefix for the Apple global runtime JSON file name -static const std::string rt_dir_prefix = "/usr/local/share/openxr/"; -static const std::string rt_filename = "/active_runtime.json"; - static inline bool PlatformGetGlobalRuntimeFileName(uint16_t major_version, std::string& file_name) { - file_name = rt_dir_prefix; - file_name += std::to_string(major_version); - file_name += rt_filename; - return true; + return detail::ImplTryRuntimeFilename("/usr/local/share/openxr/", major_version, file_name); } #elif defined(XR_OS_WINDOWS) @@ -311,22 +368,19 @@ static inline bool PlatformUtilsSetEnv(const char* /* name */, const char* /* va return false; } -#include - // Intended to be only used as a fallback on Android, with a more open, "native" technique used in most cases static inline bool PlatformGetGlobalRuntimeFileName(uint16_t major_version, std::string& file_name) { // Prefix for the runtime JSON file name static const char* rt_dir_prefixes[] = {"/product", "/odm", "/oem", "/vendor", "/system"}; - static const std::string rt_filename = "/active_runtime.json"; + static const std::string subdir = "/etc/openxr/"; for (const auto prefix : rt_dir_prefixes) { - auto path = prefix + subdir + std::to_string(major_version) + rt_filename; - struct stat buf; - if (0 == stat(path.c_str(), &buf)) { - file_name = path; + const std::string rt_dir_prefix = prefix + subdir; + if (detail::ImplTryRuntimeFilename(rt_dir_prefix.c_str(), major_version, file_name)) { return true; } } + return false; } #else // Not Linux, Apple, nor Windows diff --git a/src/common/xr_dependencies.h b/src/common/xr_dependencies.h index 5c7bd047..6c9cf2d0 100644 --- a/src/common/xr_dependencies.h +++ b/src/common/xr_dependencies.h @@ -76,7 +76,10 @@ #include "wayland-client.h" #endif // XR_USE_PLATFORM_WAYLAND -#ifdef XR_USE_GRAPHICS_API_OPENGL +#ifdef XR_USE_PLATFORM_EGL +#include +#endif // XR_USE_PLATFORM_EGL + #if defined(XR_USE_PLATFORM_XLIB) || defined(XR_USE_PLATFORM_XCB) #ifdef Success #undef Success @@ -90,4 +93,3 @@ #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 5b0da645..ce65f8dd 100644 --- a/src/common/xr_linear.h +++ b/src/common/xr_linear.h @@ -1,5 +1,5 @@ -// Copyright (c) 2017 The Khronos Group Inc. -// Copyright (c) 2016 Oculus VR, LLC. +// Copyright (c) 2017-2023, The Khronos Group Inc. +// Copyright (c) 2016, Oculus VR, LLC. // // SPDX-License-Identifier: Apache-2.0 // @@ -23,15 +23,17 @@ #include +/* REUSE-IgnoreStart */ +/* The following has copyright notices that duplicate the header above */ + /* ================================================================================================ -Description : Vector, matrix and quaternion math. -Author : J.M.P. van Waveren -Date : 12/10/2016 -Language : C99 -Format : Indent 4 spaces - no tabs. -Copyright : Copyright (c) 2016 Oculus VR, LLC. All Rights reserved. +Description : Vector, matrix and quaternion math. +Orig. Author : J.M.P. van Waveren +Orig. Date : 12/10/2016 +Language : C99 +Copyright : Copyright (c) 2016 Oculus VR, LLC. All Rights reserved. DESCRIPTION @@ -145,6 +147,8 @@ inline static float XrRcpSqrt(const float x) { return rcp; } +inline static float XrVector2f_Length(const XrVector2f* v) { return sqrtf(v->x * v->x + v->y * v->y); } + inline static void XrVector3f_Set(XrVector3f* v, const float value) { v->x = value; v->y = value; diff --git a/src/conformance/conformance_cli/main.cpp b/src/conformance/conformance_cli/main.cpp index 5358c733..2b8dba84 100644 --- a/src/conformance/conformance_cli/main.cpp +++ b/src/conformance/conformance_cli/main.cpp @@ -14,9 +14,9 @@ // Favor the high performance NVIDIA or AMD GPUs extern "C" { // http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/OptimusRenderingPolicies.pdf -_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; +__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; // https://gpuopen.com/learn/amdpowerxpressrequesthighperformance/ -_declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; +__declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; } #endif // defined(_WIN32) diff --git a/src/conformance/conformance_layer/CMakeLists.txt b/src/conformance/conformance_layer/CMakeLists.txt index 01fa7e22..bf7c9b19 100644 --- a/src/conformance/conformance_layer/CMakeLists.txt +++ b/src/conformance/conformance_layer/CMakeLists.txt @@ -25,7 +25,6 @@ run_xr_xml_generate(conformance_layer_generator.py gen_dispatch.cpp run_xr_xml_generate(conformance_layer_generator.py gen_dispatch.h ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/template_gen_dispatch.h) - add_library(XrApiLayer_runtime_conformance MODULE ${LOCAL_SOURCE} ${LOCAL_HEADERS} @@ -43,7 +42,7 @@ source_group("Headers" FILES ${LOCAL_HEADERS}) add_dependencies(XrApiLayer_runtime_conformance generate_openxr_header - xr_global_generated_files + xr_common_generated_files ) target_include_directories(XrApiLayer_runtime_conformance @@ -55,15 +54,15 @@ target_include_directories(XrApiLayer_runtime_conformance PRIVATE ${PROJECT_BINARY_DIR}/include #for common_config.h: PRIVATE ${PROJECT_BINARY_DIR}/src +#for xr_generated_dispatch_table_all.h: + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../../api_layers ) target_link_libraries(XrApiLayer_runtime_conformance Threads::Threads) if(MSVC) - # Right now can't build this on MinGW because of directxcolors, etc. + # Right now can't build this on MinGW because of directxcolors, directxmath, etc. target_link_libraries(XrApiLayer_runtime_conformance d3d11 d3d12 d3dcompiler dxgi) -else() - target_compile_definitions(XrApiLayer_runtime_conformance PRIVATE MISSING_DIRECTX_COLORS) endif() # Flag generated files diff --git a/src/conformance/conformance_layer/D3D11GraphicsValidator.cpp b/src/conformance/conformance_layer/D3D11GraphicsValidator.cpp index ff1a26eb..131f8cb3 100644 --- a/src/conformance/conformance_layer/D3D11GraphicsValidator.cpp +++ b/src/conformance/conformance_layer/D3D11GraphicsValidator.cpp @@ -24,7 +24,6 @@ namespace Conformance { -#if !defined(MISSING_DIRECTX_COLORS) // Map type to typeless. const std::unordered_map g_typelessMap{ {DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_TYPELESS}, @@ -133,7 +132,6 @@ namespace Conformance DXGI_FORMAT_V408 = 132, */ }; -#endif struct D3D11GraphicsValidator : IGraphicsValidator { @@ -148,12 +146,8 @@ namespace Conformance void ValidateSwapchainImageStructs(ConformanceHooksBase* conformanceHooks, uint64_t swapchainFormat, uint32_t count, XrSwapchainImageBaseHeader* images) const override { -#if !defined(MISSING_DIRECTX_COLORS) const auto it = g_typelessMap.find((DXGI_FORMAT)swapchainFormat); const DXGI_FORMAT expectedTextureFormat = it == g_typelessMap.end() ? (DXGI_FORMAT)swapchainFormat : it->second; -#else - (void)swapchainFormat; -#endif const XrSwapchainImageD3D11KHR* const d3d11Images = reinterpret_cast(images); for (uint32_t i = 0; i < count; i++) { @@ -166,16 +160,12 @@ namespace Conformance D3D11_TEXTURE2D_DESC desc; d3d11Images[i].texture->GetDesc(&desc); -#if !defined(MISSING_DIRECTX_COLORS) if (desc.Format != expectedTextureFormat) { conformanceHooks->ConformanceFailure( XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, "xrEnumerateSwapchainImages", "xrEnumerateSwapchainImages failed: ID3D11Texture2D format is not expected format %d: Swapchain : %d", expectedTextureFormat, desc.Format); } -#else - (void)desc; -#endif // TODO: Confirm texture is for same device(context)? } diff --git a/src/conformance/conformance_layer/HandleState.h b/src/conformance/conformance_layer/HandleState.h index 2d774fdd..88dfd5a5 100644 --- a/src/conformance/conformance_layer/HandleState.h +++ b/src/conformance/conformance_layer/HandleState.h @@ -23,6 +23,7 @@ #include #include +#include #include struct ICustomHandleState diff --git a/src/conformance/conformance_test/test_Swapchains.cpp b/src/conformance/conformance_test/test_Swapchains.cpp index 6ce6484b..db0b5a93 100644 --- a/src/conformance/conformance_test/test_Swapchains.cpp +++ b/src/conformance/conformance_test/test_Swapchains.cpp @@ -31,6 +31,7 @@ #include +#include #include XRC_DISABLE_MSVC_WARNING(4505) // unreferenced local function has been removed @@ -310,35 +311,34 @@ namespace Conformance { std::vector> ret; const auto defaultCreateInfo = MakeDefaultSwapchainCreateInfo(imageFormat, tp); - { + + auto emplaceCaseWithDimensions = [&](uint32_t width, uint32_t height, const char* message) { auto createInfo = defaultCreateInfo; - // Smallest compressed texture size is 4x4, use 8x8 to allow for future formats - createInfo.width = 8; - createInfo.height = 8; - ret.emplace_back("Very small texture, but larger than minimum compressed texture size", createInfo); - } + if (width != createInfo.width || height != createInfo.height) { - for (const auto& viewConfigView : session.viewConfigurationViewVector) { - { - auto createInfo = defaultCreateInfo; - createInfo.width = viewConfigView.recommendedImageRectWidth; - createInfo.height = viewConfigView.recommendedImageRectHeight; - ret.emplace_back("Recommended image size for view", createInfo); - } - { - auto createInfo = defaultCreateInfo; - createInfo.width = viewConfigView.maxImageRectWidth; - createInfo.height = viewConfigView.maxImageRectHeight; - ret.emplace_back("Max image size for view", createInfo); + createInfo.width = width; + createInfo.height = height; + ret.emplace_back(message, createInfo); } + }; + + // Smallest compressed texture size is 4x4, use 8x8 to allow for future formats + emplaceCaseWithDimensions(8, 8, "Very small texture, but larger than minimum compressed texture size"); + + for (const auto& viewConfigView : session.viewConfigurationViewVector) { + emplaceCaseWithDimensions(viewConfigView.recommendedImageRectWidth, viewConfigView.recommendedImageRectHeight, + "Recommended image size for view"); + emplaceCaseWithDimensions(viewConfigView.maxImageRectWidth, viewConfigView.maxImageRectHeight, "Max image size for view"); if (!tp.compressedFormat) { - auto createInfo = defaultCreateInfo; - { + if (viewConfigView.recommendedSwapchainSampleCount != defaultCreateInfo.sampleCount) { + auto createInfo = defaultCreateInfo; createInfo.sampleCount = viewConfigView.recommendedSwapchainSampleCount; ret.emplace_back("Recommended sample count", createInfo); } - { + + if (viewConfigView.maxSwapchainSampleCount != defaultCreateInfo.sampleCount) { + auto createInfo = defaultCreateInfo; createInfo.sampleCount = viewConfigView.maxSwapchainSampleCount; ret.emplace_back("Max sample count", createInfo); } @@ -347,32 +347,42 @@ namespace Conformance for (const auto& cf : tp.createFlagsVector) { auto createInfo = defaultCreateInfo; - createInfo.createFlags = cf; - ret.emplace_back("Non-default create flags", createInfo); + if (cf != createInfo.createFlags) { + createInfo.createFlags = cf; + ret.emplace_back("Non-default create flags", createInfo); + } } for (const auto& sc : tp.sampleCountVector) { auto createInfo = defaultCreateInfo; - createInfo.sampleCount = sc; - ret.emplace_back("Non-default sample count", createInfo); + if (sc != createInfo.sampleCount) { + createInfo.sampleCount = sc; + ret.emplace_back("Non-default sample count", createInfo); + } } for (const auto& uf : tp.usageFlagsVector) { auto createInfo = defaultCreateInfo; - createInfo.usageFlags = (XrSwapchainUsageFlags)uf; - ret.emplace_back("Non-default usage flags", createInfo); + if (uf != createInfo.usageFlags) { + createInfo.usageFlags = (XrSwapchainUsageFlags)uf; + ret.emplace_back("Non-default usage flags", createInfo); + } } for (const auto& ac : tp.arrayCountVector) { auto createInfo = defaultCreateInfo; - createInfo.arraySize = ac; - ret.emplace_back("Non-default array size", createInfo); + if (ac != createInfo.arraySize) { + createInfo.arraySize = ac; + ret.emplace_back("Non-default array size", createInfo); + } } for (const auto& mc : tp.mipCountVector) { auto createInfo = defaultCreateInfo; - createInfo.mipCount = mc; - ret.emplace_back("Non-default mip count", createInfo); + if (mc != createInfo.mipCount) { + createInfo.mipCount = mc; + ret.emplace_back("Non-default mip count", createInfo); + } } return ret; diff --git a/src/conformance/conformance_test/test_XR_EXT_debug_utils.cpp b/src/conformance/conformance_test/test_XR_EXT_debug_utils.cpp index 8145d8a1..2b6fda21 100644 --- a/src/conformance/conformance_test/test_XR_EXT_debug_utils.cpp +++ b/src/conformance/conformance_test/test_XR_EXT_debug_utils.cpp @@ -1,4 +1,6 @@ -// Copyright (c) 2019-2023, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. +// Copyright (c) 2017-2019 Valve Corporation +// Copyright (c) 2017-2019 LunarG, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -18,11 +20,15 @@ #include "conformance_utils.h" #include "conformance_framework.h" #include "utilities/throw_helpers.h" +#include "hex_and_handles.h" #include +#include +#include #include #include +#include #include #include #include @@ -31,12 +37,12 @@ namespace Conformance { // It would be nice to have these functions as lambdas per test case or section but - // lambdas will not account for XRAPI_CALL calling conventions for all systems. + // lambdas will not account for XRAPI_ATTR, XRAPI_CALL calling conventions for all systems. static XRAPI_ATTR XrBool32 XRAPI_CALL myOutputDebugString(XrDebugUtilsMessageSeverityFlagsEXT, XrDebugUtilsMessageTypeFlagsEXT, const XrDebugUtilsMessengerCallbackDataEXT* callbackData, void* userData) { - REQUIRE(userData == NULL); + REQUIRE(userData == nullptr); WARN(callbackData->message); return XR_FALSE; }; @@ -44,7 +50,7 @@ namespace Conformance static XRAPI_ATTR XrBool32 XRAPI_CALL myDebugBreak(XrDebugUtilsMessageSeverityFlagsEXT, XrDebugUtilsMessageTypeFlagsEXT, const XrDebugUtilsMessengerCallbackDataEXT*, void* userData) { - REQUIRE(userData == NULL); + REQUIRE(userData == nullptr); FAIL(); return XR_FALSE; }; @@ -52,38 +58,172 @@ namespace Conformance static XRAPI_ATTR XrBool32 XRAPI_CALL myStdOutLogger(XrDebugUtilsMessageSeverityFlagsEXT, XrDebugUtilsMessageTypeFlagsEXT, const XrDebugUtilsMessengerCallbackDataEXT* callbackData, void* userData) { - REQUIRE(userData == NULL); + REQUIRE(userData == nullptr); INFO(callbackData->message); return XR_FALSE; }; - static XRAPI_ATTR XrBool32 XRAPI_CALL addToStringPairVector(XrDebugUtilsMessageSeverityFlagsEXT, XrDebugUtilsMessageTypeFlagsEXT, - const XrDebugUtilsMessengerCallbackDataEXT* callbackData, void* userData) + struct DebugUtilsCallbackInfo + { + XrDebugUtilsMessageSeverityFlagsEXT messageSeverity; + XrDebugUtilsMessageTypeFlagsEXT messageTypes; + XrDebugUtilsMessengerCallbackDataEXT callbackData; + + std::vector objects; + std::vector sessionLabels; + + // All of the debug utils structs contain strings which are not valid + // for us to reference after the callback function has returned. We will + // store a vector of strings that were used with each of our callbacks + // to avoid this problem. + std::vector> strings; + }; + + static XRAPI_ATTR XrBool32 XRAPI_CALL addToDebugUtilsCallbackInfoVector(XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, + XrDebugUtilsMessageTypeFlagsEXT messageTypes, + const XrDebugUtilsMessengerCallbackDataEXT* callbackData, + void* userData) { REQUIRE(userData != NULL); - auto pMessages = reinterpret_cast>*>(userData); + auto pMessages = reinterpret_cast*>(userData); + + DebugUtilsCallbackInfo callbackInfo; + callbackInfo.messageSeverity = messageSeverity; + callbackInfo.messageTypes = messageTypes; + callbackInfo.callbackData = *callbackData; + + if (callbackData->messageId != nullptr) { + auto tmp = std::make_shared(callbackData->messageId); + callbackInfo.strings.push_back(tmp); + callbackInfo.callbackData.messageId = tmp->c_str(); + } + + if (callbackData->functionName != nullptr) { + auto tmp = std::make_shared(callbackData->functionName); + callbackInfo.strings.push_back(tmp); + callbackInfo.callbackData.functionName = tmp->c_str(); + } + + if (callbackData->message != nullptr) { + auto tmp = std::make_shared(callbackData->message); + callbackInfo.strings.push_back(tmp); + callbackInfo.callbackData.message = tmp->c_str(); + } + + for (uint32_t i = 0; i < callbackData->objectCount; ++i) { + callbackInfo.objects.push_back(callbackData->objects[i]); + if (callbackData->objects[i].objectName != nullptr) { + auto tmp = std::make_shared(callbackData->objects[i].objectName); + callbackInfo.strings.push_back(tmp); + callbackInfo.objects[i].objectName = tmp->c_str(); + } + } + callbackInfo.callbackData.objects = callbackInfo.objects.data(); + + for (uint32_t i = 0; i < callbackData->sessionLabelCount; ++i) { + callbackInfo.sessionLabels.push_back(callbackData->sessionLabels[i]); + if (callbackData->sessionLabels[i].labelName != nullptr) { + auto tmp = std::make_shared(callbackData->sessionLabels[i].labelName); + callbackInfo.strings.push_back(tmp); + callbackInfo.sessionLabels[i].labelName = tmp->c_str(); + } + } + callbackInfo.callbackData.sessionLabels = callbackInfo.sessionLabels.data(); - std::string functionName = (callbackData->functionName != nullptr ? callbackData->functionName : ""); - std::string message = (callbackData->message != nullptr ? callbackData->message : ""); - std::pair pair = std::make_pair(std::move(functionName), std::move(message)); - pMessages->push_back(std::move(pair)); + pMessages->push_back(std::move(callbackInfo)); return XR_FALSE; }; - static XRAPI_ATTR XrBool32 XRAPI_CALL createInstanceCallback(XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, - XrDebugUtilsMessageTypeFlagsEXT /* messageTypes */, - const XrDebugUtilsMessengerCallbackDataEXT* callbackData, void* userData) + static bool debugMessageExists(const std::vector& callbackInfos, + XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, XrDebugUtilsMessageTypeFlagsEXT messageTypes, + const XrDebugUtilsMessengerCallbackDataEXT* callbackData) { - REQUIRE(userData == nullptr); - if ((messageSeverity & XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0) { - FAIL_CHECK("Conformance layer error: " << callbackData->functionName << ": " << callbackData->message); - } - else { - WARN("Conformance layer warning: " << callbackData->functionName << ": " << callbackData->message); + auto callbackDataMatches = [](const XrDebugUtilsMessengerCallbackDataEXT* a, + const XrDebugUtilsMessengerCallbackDataEXT* b) -> bool { + REQUIRE(a->type == XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT); + REQUIRE(b->type == XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT); + + // We are not validating next chains match, but that should be ok. + + if ((a->messageId == nullptr) != (b->messageId == nullptr)) { + return false; + } + if ((a->messageId != nullptr) && (b->messageId != nullptr)) { + if (strcmp(a->messageId, b->messageId) != 0) { + return false; + } + } + + if ((a->functionName == nullptr) != (b->functionName == nullptr)) { + return false; + } + if ((a->functionName != nullptr) && (b->functionName != nullptr)) { + if (strcmp(a->functionName, b->functionName) != 0) { + return false; + } + } + + if ((a->message == nullptr) != (b->message == nullptr)) { + return false; + } + if ((a->message != nullptr) && (b->message != nullptr)) { + if (strcmp(a->message, b->message) != 0) { + return false; + } + } + + if (a->objectCount != b->objectCount) { + return false; + } + for (uint32_t i = 0; i < a->objectCount; ++i) { + REQUIRE(a->objects[i].type == XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT); + REQUIRE(b->objects[i].type == XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT); + + if (a->objects[i].objectType != b->objects[i].objectType) { + return false; + } + if (a->objects[i].objectHandle != b->objects[i].objectHandle) { + return false; + } + if ((a->objects[i].objectName == nullptr) != (b->objects[i].objectName == nullptr)) { + return false; + } + if ((a->objects[i].objectName != nullptr) && (b->objects[i].objectName != nullptr)) { + if (strcmp(a->objects[i].objectName, b->objects[i].objectName) != 0) { + return false; + } + } + } + + if (a->sessionLabelCount != b->sessionLabelCount) { + return false; + } + for (uint32_t i = 0; i < a->sessionLabelCount; ++i) { + REQUIRE(a->sessionLabels[i].type == XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT); + REQUIRE(b->sessionLabels[i].type == XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT); + + if ((a->sessionLabels[i].labelName == nullptr) != (b->sessionLabels[i].labelName == nullptr)) { + return false; + } + if ((a->sessionLabels[i].labelName != nullptr) && (b->sessionLabels[i].labelName != nullptr)) { + if (strcmp(a->sessionLabels[i].labelName, b->sessionLabels[i].labelName) != 0) { + return false; + } + } + } + + return true; + }; + + for (const auto& callbackInfo : callbackInfos) { + if (callbackInfo.messageSeverity == messageSeverity && callbackInfo.messageTypes == messageTypes && + callbackDataMatches(&callbackInfo.callbackData, callbackData)) { + return true; + } } - return XR_TRUE; - }; + return false; + } TEST_CASE("XR_EXT_debug_utils", "") { @@ -100,51 +240,6 @@ namespace Conformance SKIP(XR_EXT_DEBUG_UTILS_EXTENSION_NAME " not supported"); } - SECTION("xrSubmitDebugUtilsMessageEXT") - { - std::vector> messages; - - auto testMessage = std::make_pair("worker", "testing!"); - - auto worker = [&](XrInstance instance) -> void { - auto pfnSubmitDebugUtilsMessageEXT = - GetInstanceExtensionFunction(instance, "xrSubmitDebugUtilsMessageEXT"); - - XrDebugUtilsMessengerCallbackDataEXT callbackData{XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; - callbackData.functionName = testMessage.first.c_str(); - callbackData.message = testMessage.second.c_str(); - REQUIRE_RESULT(XR_SUCCESS, pfnSubmitDebugUtilsMessageEXT(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, - XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callbackData)); - }; - - AutoBasicInstance instance({XR_EXT_DEBUG_UTILS_EXTENSION_NAME}); - - // Must call extension functions through a function pointer: - auto pfnCreateDebugUtilsMessengerEXT = - GetInstanceExtensionFunction(instance, "xrCreateDebugUtilsMessengerEXT"); - - XrDebugUtilsMessengerCreateInfoEXT callback = { - XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, // type - NULL, // next - XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | // messageSeverities - XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | - XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, - XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | // messageTypes - XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT | - XR_DEBUG_UTILS_MESSAGE_TYPE_CONFORMANCE_BIT_EXT, - addToStringPairVector, // userCallback - reinterpret_cast(&messages) // userData - }; - XrDebugUtilsMessengerEXT messenger = XR_NULL_HANDLE; - REQUIRE_RESULT(XR_SUCCESS, pfnCreateDebugUtilsMessengerEXT(instance, &callback, &messenger)); - - worker(instance); - - REQUIRE(messages.size() > 0); - - REQUIRE(messages.end() != std::find(messages.begin(), messages.end(), testMessage)); - } - SECTION("xrCreateInstance debug utils not enabled") { auto enabledApiLayers = StringVec(globalData.enabledAPILayerNames); @@ -173,7 +268,7 @@ namespace Conformance ValidateInstanceExtensionFunctionNotSupported(instance, "xrCreateDebugUtilsMessengerEXT"); } - SECTION("xrCreateInstance XrDebugUtilsMessengerCreateInfoEXT") + SECTION("Create/Destroy with xrCreateInstance/xrDestroyInstance") { // To capture events that occur while creating or destroying an instance an application can link // an XrDebugUtilsMessengerCreateInfoEXT structure to the next element of the XrInstanceCreateInfo @@ -182,15 +277,19 @@ namespace Conformance // is not passed as an option, but we have an explicit test for this behavior too. auto enabledApiLayers = StringVec(globalData.enabledAPILayerNames); + // Enable only the required platform extensions by default auto enabledExtensions = StringVec(globalData.requiredPlatformInstanceExtensions); + std::vector callbackInfo; + XrDebugUtilsMessengerCreateInfoEXT debugInfo{XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; debugInfo.messageSeverities = XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - debugInfo.messageTypes = XR_DEBUG_UTILS_MESSAGE_TYPE_CONFORMANCE_BIT_EXT; - debugInfo.userCallback = createInstanceCallback; - debugInfo.userData = nullptr; + debugInfo.messageTypes = XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + debugInfo.userCallback = addToDebugUtilsCallbackInfoVector; + debugInfo.userData = reinterpret_cast(&callbackInfo); XrInstance instance{XR_NULL_HANDLE}; CleanupInstanceOnScopeExit cleanup(instance); @@ -223,19 +322,661 @@ namespace Conformance GetInstanceExtensionFunction(instance, "xrCreateDebugUtilsMessengerEXT"); REQUIRE(pfnCreateDebugUtilsMessengerEXT != nullptr); } + { + // Get a function pointer to the submit function to test + PFN_xrSubmitDebugUtilsMessageEXT pfn_submit_dmsg; + REQUIRE_RESULT(XR_SUCCESS, xrGetInstanceProcAddr(instance, "xrSubmitDebugUtilsMessageEXT", + reinterpret_cast(&pfn_submit_dmsg))); + REQUIRE(pfn_submit_dmsg != nullptr); + + XrDebugUtilsMessengerCallbackDataEXT callback_data{XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; + callback_data.messageId = "General Error"; + callback_data.functionName = "MyTestFunctionName"; + callback_data.message = "General Error"; + + // Test the various items + { + callback_data.messageId = "General Error"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Validation Warning"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Performance Info"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "General Verbose"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + } + } REQUIRE_RESULT(XR_SUCCESS, xrDestroyInstance(instance)); instance = XR_NULL_HANDLE; } + SECTION("Create/Destroy with explicit call (xrCreateDebugUtilsMessengerEXT/xrDestroyDebugUtilsMessengerEXT)") + { + AutoBasicInstance instance({XR_EXT_DEBUG_UTILS_EXTENSION_NAME}); + + // Get a function pointer to the various debug utils functions to test + auto pfn_create_debug_utils_messager_ext = + GetInstanceExtensionFunction(instance, "xrCreateDebugUtilsMessengerEXT"); + auto pfn_destroy_debug_utils_messager_ext = + GetInstanceExtensionFunction(instance, "xrDestroyDebugUtilsMessengerEXT"); + auto pfn_submit_dmsg = GetInstanceExtensionFunction(instance, "xrSubmitDebugUtilsMessageEXT"); + + // Create the debug utils messenger + std::vector callbackInfo; + 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; + dbg_msg_ci.messageTypes = XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + dbg_msg_ci.userCallback = addToDebugUtilsCallbackInfoVector; + dbg_msg_ci.userData = reinterpret_cast(&callbackInfo); + + XrDebugUtilsMessengerEXT debug_utils_messenger = XR_NULL_HANDLE; + REQUIRE_RESULT(XR_SUCCESS, pfn_create_debug_utils_messager_ext(instance, &dbg_msg_ci, &debug_utils_messenger)); + + XrDebugUtilsMessengerCallbackDataEXT callback_data{XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; + callback_data.messageId = "General Error"; + callback_data.functionName = "MyTestFunctionName"; + callback_data.message = "General Error"; + + // Test the various items + { + callback_data.messageId = "General Error"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Validation Warning"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Performance Info"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "General Verbose"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + } + + // Destroy what we created + REQUIRE_RESULT(XR_SUCCESS, pfn_destroy_debug_utils_messager_ext(debug_utils_messenger)); + } + + SECTION("Make sure appropriate messages only received when registered") + { + AutoBasicInstance instance({XR_EXT_DEBUG_UTILS_EXTENSION_NAME}); + + // Get a function pointer to the various debug utils functions to test + auto pfn_create_debug_utils_messager_ext = + GetInstanceExtensionFunction(instance, "xrCreateDebugUtilsMessengerEXT"); + auto pfn_destroy_debug_utils_messager_ext = + GetInstanceExtensionFunction(instance, "xrDestroyDebugUtilsMessengerEXT"); + auto pfn_submit_dmsg = GetInstanceExtensionFunction(instance, "xrSubmitDebugUtilsMessageEXT"); + + SECTION("Create the debug utils messenger, but only to receive general error messages") + { + // Create the debug utils messenger, but only to receive general error messages + std::vector callbackInfo; + XrDebugUtilsMessengerCreateInfoEXT dbg_msg_ci = {XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; + dbg_msg_ci.messageSeverities = XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + dbg_msg_ci.messageTypes = XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT; + dbg_msg_ci.userCallback = addToDebugUtilsCallbackInfoVector; + dbg_msg_ci.userData = reinterpret_cast(&callbackInfo); + + XrDebugUtilsMessengerEXT debug_utils_messenger = XR_NULL_HANDLE; + REQUIRE_RESULT(XR_SUCCESS, pfn_create_debug_utils_messager_ext(instance, &dbg_msg_ci, &debug_utils_messenger)); + + XrDebugUtilsMessengerCallbackDataEXT callback_data{XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; + callback_data.messageId = "General Error"; + callback_data.functionName = "MyTestFunctionName"; + callback_data.message = "General Error"; + + // Test the various items + { + callback_data.messageId = "General Error"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Validation Warning"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Performance Info"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "General Verbose"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + } + + // Destroy what we created + REQUIRE_RESULT(XR_SUCCESS, pfn_destroy_debug_utils_messager_ext(debug_utils_messenger)); + } + + SECTION("Create the debug utils messenger, but only to receive validation warning messages") + { + // Create the debug utils messenger, but only to receive validation warning messages + std::vector callbackInfo; + XrDebugUtilsMessengerCreateInfoEXT dbg_msg_ci = {XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; + dbg_msg_ci.messageSeverities = XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT; + dbg_msg_ci.messageTypes = XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; + dbg_msg_ci.userCallback = addToDebugUtilsCallbackInfoVector; + dbg_msg_ci.userData = reinterpret_cast(&callbackInfo); + + XrDebugUtilsMessengerEXT debug_utils_messenger = XR_NULL_HANDLE; + REQUIRE_RESULT(XR_SUCCESS, pfn_create_debug_utils_messager_ext(instance, &dbg_msg_ci, &debug_utils_messenger)); + + XrDebugUtilsMessengerCallbackDataEXT callback_data{XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; + callback_data.messageId = "General Error"; + callback_data.functionName = "MyTestFunctionName"; + callback_data.message = "General Error"; + + // Test the various items + { + callback_data.messageId = "General Error"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Validation Warning"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Performance Info"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "General Verbose"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + } + + // Destroy what we created + REQUIRE_RESULT(XR_SUCCESS, pfn_destroy_debug_utils_messager_ext(debug_utils_messenger)); + } + + SECTION("Create the debug utils messenger, but only to receive performance verbose messages") + { + // Create the debug utils messenger, but only to receive performance verbose messages + std::vector callbackInfo; + XrDebugUtilsMessengerCreateInfoEXT dbg_msg_ci = {XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; + dbg_msg_ci.messageSeverities = XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT; + dbg_msg_ci.messageTypes = XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + dbg_msg_ci.userCallback = addToDebugUtilsCallbackInfoVector; + dbg_msg_ci.userData = reinterpret_cast(&callbackInfo); + + XrDebugUtilsMessengerEXT debug_utils_messenger = XR_NULL_HANDLE; + REQUIRE_RESULT(XR_SUCCESS, pfn_create_debug_utils_messager_ext(instance, &dbg_msg_ci, &debug_utils_messenger)); + + XrDebugUtilsMessengerCallbackDataEXT callback_data{XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; + callback_data.messageId = "General Error"; + callback_data.functionName = "MyTestFunctionName"; + callback_data.message = "General Error"; + + // Test the various items + { + callback_data.messageId = "General Error"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Validation Warning"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Performance Info"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "General Verbose"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Performance Verbose"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + } + + // Destroy what we created + REQUIRE_RESULT(XR_SUCCESS, pfn_destroy_debug_utils_messager_ext(debug_utils_messenger)); + } + + SECTION("Create the debug utils messenger, but only to info validation messages") + { + // Create the debug utils messenger, but only to receive validation info messages + std::vector callbackInfo; + XrDebugUtilsMessengerCreateInfoEXT dbg_msg_ci = {XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; + dbg_msg_ci.messageSeverities = XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT; + dbg_msg_ci.messageTypes = XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; + dbg_msg_ci.userCallback = addToDebugUtilsCallbackInfoVector; + dbg_msg_ci.userData = reinterpret_cast(&callbackInfo); + + XrDebugUtilsMessengerEXT debug_utils_messenger = XR_NULL_HANDLE; + REQUIRE_RESULT(XR_SUCCESS, pfn_create_debug_utils_messager_ext(instance, &dbg_msg_ci, &debug_utils_messenger)); + + XrDebugUtilsMessengerCallbackDataEXT callback_data{XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; + callback_data.messageId = "General Error"; + callback_data.functionName = "MyTestFunctionName"; + callback_data.message = "General Error"; + + // Test the various items + { + callback_data.messageId = "General Error"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Validation Warning"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Performance Info"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "General Verbose"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + REQUIRE(!debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data)); + } + { + callback_data.messageId = "Performance Verbose"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, &callback_data)); + } + + // Destroy what we created + REQUIRE_RESULT(XR_SUCCESS, pfn_destroy_debug_utils_messager_ext(debug_utils_messenger)); + } + } + + SECTION("Test Objects") + { + AutoBasicInstance instance({XR_EXT_DEBUG_UTILS_EXTENSION_NAME}); + AutoBasicSession session(AutoBasicSession::createSession | AutoBasicSession::createSpaces | AutoBasicSession::createSwapchains, + instance); + + // Get a function pointer to the various debug utils functions to test + auto pfn_create_debug_utils_messager_ext = + GetInstanceExtensionFunction(instance, "xrCreateDebugUtilsMessengerEXT"); + auto pfn_destroy_debug_utils_messager_ext = + GetInstanceExtensionFunction(instance, "xrDestroyDebugUtilsMessengerEXT"); + auto pfn_submit_dmsg = GetInstanceExtensionFunction(instance, "xrSubmitDebugUtilsMessageEXT"); + + // Create the debug utils messenger, but only to receive validation warning messages + std::vector callbackInfo; + XrDebugUtilsMessengerCreateInfoEXT dbg_msg_ci = {XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; + dbg_msg_ci.messageSeverities = XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT; + dbg_msg_ci.messageTypes = XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + dbg_msg_ci.userCallback = addToDebugUtilsCallbackInfoVector; + dbg_msg_ci.userData = reinterpret_cast(&callbackInfo); + XrDebugUtilsMessengerEXT debug_utils_messenger = XR_NULL_HANDLE; + REQUIRE_RESULT(XR_SUCCESS, pfn_create_debug_utils_messager_ext(instance, &dbg_msg_ci, &debug_utils_messenger)); + + XrDebugUtilsMessengerCallbackDataEXT callback_data{XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; + callback_data.messageId = "General Error"; + callback_data.functionName = "MyTestFunctionName"; + callback_data.message = "General Error"; + + std::array objects; + objects.fill({XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT}); + objects[0].objectType = XR_OBJECT_TYPE_INSTANCE; + objects[0].objectHandle = MakeHandleGeneric(instance.GetInstance()); + objects[0].objectName = nullptr; + objects[1].objectType = XR_OBJECT_TYPE_SESSION; + objects[1].objectHandle = MakeHandleGeneric(session.GetSession()); + objects[1].objectName = nullptr; + objects[2].objectType = XR_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT; + objects[2].objectHandle = MakeHandleGeneric(debug_utils_messenger); + objects[2].objectName = nullptr; + callback_data.objects = objects.data(); + callback_data.objectCount = static_cast(objects.size()); + + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + + // Destroy what we created + REQUIRE_RESULT(XR_SUCCESS, pfn_destroy_debug_utils_messager_ext(debug_utils_messenger)); + } + + SECTION("Test object names") + { + auto findMessageByMessageId = [](const std::vector& callbackInfos, + const char* messageId) -> const DebugUtilsCallbackInfo& { + { + size_t messageMatchCount = 0; + for (const auto& callbackInfo : callbackInfos) { + if (strcmp(callbackInfo.callbackData.messageId, messageId) == 0) { + messageMatchCount++; + } + } + REQUIRE(messageMatchCount == 1); + } + auto it = std::find_if(callbackInfos.begin(), callbackInfos.end(), [messageId](const auto& callbackInfo) { + return strcmp(callbackInfo.callbackData.messageId, messageId) == 0; + }); + REQUIRE(it != callbackInfos.end()); + return *it; + }; + + AutoBasicInstance instance({XR_EXT_DEBUG_UTILS_EXTENSION_NAME}); + + auto pfn_create_debug_utils_messager_ext = + GetInstanceExtensionFunction(instance, "xrCreateDebugUtilsMessengerEXT"); + auto pfn_destroy_debug_utils_messager_ext = + GetInstanceExtensionFunction(instance, "xrDestroyDebugUtilsMessengerEXT"); + auto pfn_submit_dmsg = GetInstanceExtensionFunction(instance, "xrSubmitDebugUtilsMessageEXT"); + auto pfn_set_obj_name = + GetInstanceExtensionFunction(instance, "xrSetDebugUtilsObjectNameEXT"); + auto pfn_begin_debug_utils_label_region_ext = GetInstanceExtensionFunction( + instance, "xrSessionBeginDebugUtilsLabelRegionEXT"); + auto pfn_end_debug_utils_label_region_ext = + GetInstanceExtensionFunction(instance, "xrSessionEndDebugUtilsLabelRegionEXT"); + auto pfn_insert_debug_utils_label_ext = + GetInstanceExtensionFunction(instance, "xrSessionInsertDebugUtilsLabelEXT"); + + // Create the debug utils messenger, but only to receive validation warning messages + std::vector callbackInfo; + XrDebugUtilsMessengerCreateInfoEXT dbg_msg_ci = {XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; + dbg_msg_ci.messageSeverities = XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT; + dbg_msg_ci.messageTypes = XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + dbg_msg_ci.userCallback = addToDebugUtilsCallbackInfoVector; + dbg_msg_ci.userData = reinterpret_cast(&callbackInfo); + XrDebugUtilsMessengerEXT debug_utils_messenger = XR_NULL_HANDLE; + REQUIRE_RESULT(XR_SUCCESS, pfn_create_debug_utils_messager_ext(instance, &dbg_msg_ci, &debug_utils_messenger)); + + XrDebugUtilsObjectNameInfoEXT object{XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT}; + object.objectType = XR_OBJECT_TYPE_INSTANCE; + object.objectHandle = MakeHandleGeneric(instance.GetInstance()); + object.objectName = "My Instance Obj"; + REQUIRE_RESULT(XR_SUCCESS, pfn_set_obj_name(instance, &object)); + + // TODO: validate objectName works (in a separate test case) + + { + XrDebugUtilsMessengerCallbackDataEXT callback_data{XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; + callback_data.messageId = "General Error"; + callback_data.functionName = "MyTestFunctionName"; + callback_data.message = "General Error"; + callback_data.objectCount = 1; + callback_data.objects = &object; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + REQUIRE(debugMessageExists(callbackInfo, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + } + + { + static const char first_individual_label_name[] = "First individual label"; + static const char second_individual_label_name[] = "Second individual label"; + static const char third_individual_label_name[] = "Third individual label"; + static const char first_label_region_name[] = "First Label Region"; + static const char second_label_region_name[] = "Second Label Region"; + + AutoBasicSession session( + AutoBasicSession::createSession | AutoBasicSession::createSpaces | AutoBasicSession::createSwapchains, instance); + FrameIterator frameIterator(&session); + + auto timeout = (globalData.options.debugMode ? 3600s : 10s); + CAPTURE(timeout); + + // Create a label struct for initial testing + XrDebugUtilsLabelEXT first_label = {XR_TYPE_DEBUG_UTILS_LABEL_EXT}; + first_label.labelName = first_individual_label_name; + + // TODO: Invalid parameters might be better as a separate test case + SECTION("Invalid parameters") + { + // Try invalid session on each of the label functions + REQUIRE_RESULT(XR_ERROR_HANDLE_INVALID, pfn_begin_debug_utils_label_region_ext(XR_NULL_HANDLE, &first_label)); + REQUIRE_RESULT(XR_ERROR_HANDLE_INVALID, pfn_end_debug_utils_label_region_ext(XR_NULL_HANDLE)); + REQUIRE_RESULT(XR_ERROR_HANDLE_INVALID, pfn_insert_debug_utils_label_ext(XR_NULL_HANDLE, &first_label)); + + // Try with nullptr for the label + REQUIRE_RESULT(XR_ERROR_VALIDATION_FAILURE, pfn_begin_debug_utils_label_region_ext(session, nullptr)); + REQUIRE_RESULT(XR_ERROR_VALIDATION_FAILURE, pfn_insert_debug_utils_label_ext(session, nullptr)); + } + + // Set it up to put in the session and instance to any debug utils messages + XrDebugUtilsMessengerCallbackDataEXT callback_data{XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; + callback_data.messageId = "General Error"; + callback_data.functionName = "MyTestFunctionName"; + callback_data.message = "General Error"; + std::array objects; + objects.fill({XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT}); + objects[0].objectType = XR_OBJECT_TYPE_INSTANCE; + objects[0].objectHandle = MakeHandleGeneric(instance.GetInstance()); + objects[0].objectName = nullptr; + objects[1].objectType = XR_OBJECT_TYPE_SESSION; + objects[1].objectHandle = MakeHandleGeneric(session.GetSession()); + objects[1].objectName = nullptr; + callback_data.objectCount = static_cast(objects.size()); + callback_data.objects = objects.data(); + + // Start an individual label + REQUIRE_RESULT(XR_SUCCESS, pfn_insert_debug_utils_label_ext(session, &first_label)); + + // Trigger a message and make sure we see "First individual label" + { + callback_data.messageId = "First Individual Label"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + + const auto& cb = findMessageByMessageId(callbackInfo, callback_data.messageId); + REQUIRE(cb.callbackData.sessionLabelCount == 1); + REQUIRE_THAT(cb.callbackData.sessionLabels[0].labelName, Catch::Matchers::Equals(first_individual_label_name)); + } + + // Begin a label region + first_label.labelName = first_label_region_name; + REQUIRE_RESULT(XR_SUCCESS, pfn_begin_debug_utils_label_region_ext(session, &first_label)); + + // Trigger a message and make sure we see "Label Region" and not "First individual label" + { + callback_data.messageId = "First Label Region"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + const auto& cb = findMessageByMessageId(callbackInfo, callback_data.messageId); + REQUIRE(cb.callbackData.sessionLabelCount == 1); + REQUIRE_THAT(cb.callbackData.sessionLabels[0].labelName, Catch::Matchers::Equals(first_label_region_name)); + } + + // Begin the session now. + { + FrameIterator::RunResult runResult = frameIterator.RunToSessionState(XR_SESSION_STATE_READY, timeout); + REQUIRE(runResult == FrameIterator::RunResult::Success); + + XrSessionBeginInfo session_begin_info = {XR_TYPE_SESSION_BEGIN_INFO}; + session_begin_info.primaryViewConfigurationType = GetGlobalData().GetOptions().viewConfigurationValue; + REQUIRE_RESULT(XR_SUCCESS, xrBeginSession(session, &session_begin_info)); + } + + XrDebugUtilsLabelEXT individual_label{XR_TYPE_DEBUG_UTILS_LABEL_EXT}; + individual_label.labelName = second_individual_label_name; + REQUIRE_RESULT(XR_SUCCESS, pfn_insert_debug_utils_label_ext(session, &individual_label)); + + // Trigger a message and make sure we see "Second individual" and "First Label Region" and not "First + // individual label" + { + callback_data.messageId = "Second Individual and First Region"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + const auto& cb = findMessageByMessageId(callbackInfo, callback_data.messageId); + // From: https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#session-labels + // The labels listed inside sessionLabels are organized in time order, with the most recently + // generated label appearing first, and the oldest label appearing last. + REQUIRE(cb.callbackData.sessionLabelCount == 2); + REQUIRE_THAT(cb.callbackData.sessionLabels[0].labelName, Catch::Matchers::Equals(second_individual_label_name)); + REQUIRE_THAT(cb.callbackData.sessionLabels[1].labelName, Catch::Matchers::Equals(first_label_region_name)); + } + + individual_label.labelName = third_individual_label_name; + REQUIRE_RESULT(XR_SUCCESS, pfn_insert_debug_utils_label_ext(session, &individual_label)); + + // Trigger a message and make sure we see "Third individual" and "First Label Region" and not "First + // individual label" or "Second individual label" + { + callback_data.messageId = "Third Individual and First Region"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + const auto& cb = findMessageByMessageId(callbackInfo, callback_data.messageId); + REQUIRE(cb.callbackData.sessionLabelCount == 2); + REQUIRE_THAT(cb.callbackData.sessionLabels[0].labelName, Catch::Matchers::Equals(third_individual_label_name)); + REQUIRE_THAT(cb.callbackData.sessionLabels[1].labelName, Catch::Matchers::Equals(first_label_region_name)); + } + + // Begin a label region + { + XrDebugUtilsLabelEXT second_label_region = {XR_TYPE_DEBUG_UTILS_LABEL_EXT}; + second_label_region.labelName = second_label_region_name; + REQUIRE_RESULT(XR_SUCCESS, pfn_begin_debug_utils_label_region_ext(session, &second_label_region)); + } + + // Trigger a message and make sure we see "Second Label Region" and "First Label Region" + { + callback_data.messageId = "Second and First Label Regions"; + pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data); + const auto& cb = findMessageByMessageId(callbackInfo, callback_data.messageId); + REQUIRE(cb.callbackData.sessionLabelCount == 2); + REQUIRE_THAT(cb.callbackData.sessionLabels[0].labelName, Catch::Matchers::Equals(second_label_region_name)); + REQUIRE_THAT(cb.callbackData.sessionLabels[1].labelName, Catch::Matchers::Equals(first_label_region_name)); + } + + // End the last (most recent) label region + { + REQUIRE_RESULT(XR_SUCCESS, pfn_end_debug_utils_label_region_ext(session)); + // TODO: need a test for end a label region that has not been started + } + + // Trigger a message and make sure we see "First Label Region" + { + callback_data.messageId = "First Label Region 2"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + const auto& cb = findMessageByMessageId(callbackInfo, callback_data.messageId); + REQUIRE(cb.callbackData.sessionLabelCount == 1); + REQUIRE_THAT(cb.callbackData.sessionLabels[0].labelName, Catch::Matchers::Equals(first_label_region_name)); + } + + // Now clean-up (the session) + { + REQUIRE_RESULT(XR_SUCCESS, xrRequestExitSession(session)); + + FrameIterator::RunResult runResult = frameIterator.RunToSessionState(XR_SESSION_STATE_STOPPING, timeout); + REQUIRE(runResult == FrameIterator::RunResult::Success); + + REQUIRE_RESULT(XR_SUCCESS, xrEndSession(session)); + } + + // End the last label region + { + REQUIRE_RESULT(XR_SUCCESS, pfn_end_debug_utils_label_region_ext(session)); + } + + // Trigger a message and make sure we see no labels + { + callback_data.messageId = "No Labels"; + REQUIRE_RESULT(XR_SUCCESS, pfn_submit_dmsg(instance, XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, &callback_data)); + const auto& cb = findMessageByMessageId(callbackInfo, callback_data.messageId); + REQUIRE(cb.callbackData.sessionLabelCount == 0); + } + + session.Shutdown(); + } + + // Destroy what we created + REQUIRE_RESULT(XR_SUCCESS, pfn_destroy_debug_utils_messager_ext(debug_utils_messenger)); + } + // https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_debug_utils // The OpenXR spec provides some examples of how to use the extension; they are not full // examples but let's make sure that something equivalent to them works. // Example 1 / multiple callbacks +#define CHK_XR(expr) XRC_CHECK_THROW_XRCMD(expr) + SECTION("Examples") { -#define CHK_XR(expr) XRC_CHECK_THROW_XRCMD(expr) SECTION("Example 1: Multiple callbacks") { AutoBasicInstance instance({XR_EXT_DEBUG_UTILS_EXTENSION_NAME}); @@ -411,8 +1152,8 @@ namespace Conformance // (in this case it's the "Session Active" label) pfnSessionEndDebugUtilsLabelRegionEXT(session); } -#undef CHK_XR } +#undef CHK_XR } } // namespace Conformance diff --git a/src/conformance/conformance_test/test_XR_EXT_hand_tracking.cpp b/src/conformance/conformance_test/test_XR_EXT_hand_tracking.cpp index ad2e8e72..e37130fa 100644 --- a/src/conformance/conformance_test/test_XR_EXT_hand_tracking.cpp +++ b/src/conformance/conformance_test/test_XR_EXT_hand_tracking.cpp @@ -36,7 +36,7 @@ namespace Conformance MakeSystemPropertiesBoolChecker(XrSystemHandTrackingPropertiesEXT{XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT}, &XrSystemHandTrackingPropertiesEXT::supportsHandTracking); - TEST_CASE("XR_EXT_hand_tracking", "") + TEST_CASE("XR_EXT_hand_tracking-create-destroy", "") { GlobalData& globalData = GetGlobalData(); if (!globalData.IsInstanceExtensionSupported(XR_EXT_HAND_TRACKING_EXTENSION_NAME)) { @@ -81,41 +81,54 @@ namespace Conformance createInfo.hand = (i == 0 ? XR_HAND_LEFT_EXT : XR_HAND_RIGHT_EXT); REQUIRE(XR_ERROR_FEATURE_UNSUPPORTED == xrCreateHandTrackerEXT(session, &createInfo, &tracker)); } - - // This runtime does support hand tracking, but this headset does not - // support hand tracking, which is fine. - SKIP("System does not support hand tracking"); } - - std::array handTracker; - for (size_t i = 0; i < HAND_COUNT; ++i) { - XrHandTrackerCreateInfoEXT createInfo{XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT}; - createInfo.handJointSet = XR_HAND_JOINT_SET_DEFAULT_EXT; - createInfo.hand = (i == 0 ? XR_HAND_LEFT_EXT : XR_HAND_RIGHT_EXT); - REQUIRE(XR_SUCCESS == xrCreateHandTrackerEXT(session, &createInfo, &handTracker[i])); - REQUIRE(XR_SUCCESS == xrDestroyHandTrackerEXT(handTracker[i])); + else { + std::array handTracker; + for (size_t i = 0; i < HAND_COUNT; ++i) { + XrHandTrackerCreateInfoEXT createInfo{XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT}; + createInfo.handJointSet = XR_HAND_JOINT_SET_DEFAULT_EXT; + createInfo.hand = (i == 0 ? XR_HAND_LEFT_EXT : XR_HAND_RIGHT_EXT); + REQUIRE(XR_SUCCESS == xrCreateHandTrackerEXT(session, &createInfo, &handTracker[i])); + REQUIRE(XR_SUCCESS == xrDestroyHandTrackerEXT(handTracker[i])); + } } } + } - SECTION("Query joint locations") - { - AutoBasicInstance instance({XR_EXT_HAND_TRACKING_EXTENSION_NAME}, AutoBasicInstance::createSystemId); + TEST_CASE("XR_EXT_hand_tracking-simple-queries") + { + GlobalData& globalData = GetGlobalData(); + if (!globalData.IsInstanceExtensionSupported(XR_EXT_HAND_TRACKING_EXTENSION_NAME)) { + SKIP(XR_EXT_HAND_TRACKING_EXTENSION_NAME " not supported"); + } - auto xrCreateHandTrackerEXT = GetInstanceExtensionFunction(instance, "xrCreateHandTrackerEXT"); - auto xrDestroyHandTrackerEXT = GetInstanceExtensionFunction(instance, "xrDestroyHandTrackerEXT"); - auto xrLocateHandJointsEXT = GetInstanceExtensionFunction(instance, "xrLocateHandJointsEXT"); + AutoBasicInstance instance({XR_EXT_HAND_TRACKING_EXTENSION_NAME}, AutoBasicInstance::createSystemId); - XrSystemId systemId = instance.systemId; - if (!SystemSupportsHandTracking(instance, systemId)) { - // This runtime does support hand tracking, but this headset does not - // support hand tracking, which is fine. - SKIP("System does not support hand tracking"); - } + auto xrCreateHandTrackerEXT = GetInstanceExtensionFunction(instance, "xrCreateHandTrackerEXT"); + auto xrDestroyHandTrackerEXT = GetInstanceExtensionFunction(instance, "xrDestroyHandTrackerEXT"); + auto xrLocateHandJointsEXT = GetInstanceExtensionFunction(instance, "xrLocateHandJointsEXT"); - AutoBasicSession session(AutoBasicSession::beginSession | AutoBasicSession::createActions | AutoBasicSession::createSpaces | - AutoBasicSession::createSwapchains, - instance); + XrSystemId systemId = instance.systemId; + if (!SystemSupportsHandTracking(instance, systemId)) { + // This runtime does support hand tracking, but this headset does not + // support hand tracking, which is fine. + SKIP("System does not support hand tracking"); + } + + AutoBasicSession session(AutoBasicSession::beginSession | AutoBasicSession::createActions | AutoBasicSession::createSpaces | + AutoBasicSession::createSwapchains, + instance); + std::array handTracker; + for (size_t i = 0; i < HAND_COUNT; ++i) { + XrHandTrackerCreateInfoEXT createInfo{XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT}; + createInfo.handJointSet = XR_HAND_JOINT_SET_DEFAULT_EXT; + createInfo.hand = (i == 0 ? XR_HAND_LEFT_EXT : XR_HAND_RIGHT_EXT); + REQUIRE(XR_SUCCESS == xrCreateHandTrackerEXT(session, &createInfo, &handTracker[i])); + } + + SECTION("Query joint locations") + { XrSpace localSpace = XR_NULL_HANDLE; XrReferenceSpaceCreateInfo localSpaceCreateInfo{XR_TYPE_REFERENCE_SPACE_CREATE_INFO}; @@ -123,14 +136,6 @@ namespace Conformance localSpaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL; REQUIRE_RESULT(xrCreateReferenceSpace(session, &localSpaceCreateInfo, &localSpace), XR_SUCCESS); - std::array handTracker; - for (size_t i = 0; i < HAND_COUNT; ++i) { - XrHandTrackerCreateInfoEXT createInfo{XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT}; - createInfo.handJointSet = XR_HAND_JOINT_SET_DEFAULT_EXT; - createInfo.hand = (i == 0 ? XR_HAND_LEFT_EXT : XR_HAND_RIGHT_EXT); - REQUIRE(XR_SUCCESS == xrCreateHandTrackerEXT(session, &createInfo, &handTracker[i])); - } - // Wait until the runtime is ready for us to begin a session auto timeout = (GetGlobalData().options.debugMode ? 3600s : 10s); FrameIterator frameIterator(&session); @@ -190,29 +195,10 @@ namespace Conformance } } } - - for (size_t i = 0; i < HAND_COUNT; ++i) { - REQUIRE(XR_SUCCESS == xrDestroyHandTrackerEXT(handTracker[i])); - } } SECTION("Query invalid joint sets") { - AutoBasicInstance instance({XR_EXT_HAND_TRACKING_EXTENSION_NAME}, AutoBasicInstance::createSystemId); - - auto xrCreateHandTrackerEXT = GetInstanceExtensionFunction(instance, "xrCreateHandTrackerEXT"); - auto xrDestroyHandTrackerEXT = GetInstanceExtensionFunction(instance, "xrDestroyHandTrackerEXT"); - auto xrLocateHandJointsEXT = GetInstanceExtensionFunction(instance, "xrLocateHandJointsEXT"); - - XrSystemId systemId = instance.systemId; - if (!SystemSupportsHandTracking(instance, systemId)) { - // This runtime does support hand tracking, but this headset does not - // support hand tracking, which is fine. - SKIP("System does not support hand tracking"); - } - - AutoBasicSession session(AutoBasicSession::beginSession, instance); - XrSpace localSpace = XR_NULL_HANDLE; XrReferenceSpaceCreateInfo localSpaceCreateInfo{XR_TYPE_REFERENCE_SPACE_CREATE_INFO}; @@ -220,14 +206,6 @@ namespace Conformance localSpaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL; REQUIRE_RESULT(xrCreateReferenceSpace(session, &localSpaceCreateInfo, &localSpace), XR_SUCCESS); - std::array handTracker; - for (size_t i = 0; i < HAND_COUNT; ++i) { - XrHandTrackerCreateInfoEXT createInfo{XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT}; - createInfo.handJointSet = XR_HAND_JOINT_SET_DEFAULT_EXT; - createInfo.hand = (i == 0 ? XR_HAND_LEFT_EXT : XR_HAND_RIGHT_EXT); - REQUIRE(XR_SUCCESS == xrCreateHandTrackerEXT(session, &createInfo, &handTracker[i])); - } - // Wait until the runtime is ready for us to begin a session auto timeout = (GetGlobalData().options.debugMode ? 3600s : 10s); FrameIterator frameIterator(&session); @@ -271,10 +249,10 @@ namespace Conformance locateInfo.time = frameIterator.frameState.predictedDisplayTime; REQUIRE(XR_ERROR_VALIDATION_FAILURE == xrLocateHandJointsEXT(handTracker[hand], &locateInfo, &locations)); } + } - for (size_t i = 0; i < HAND_COUNT; ++i) { - REQUIRE(XR_SUCCESS == xrDestroyHandTrackerEXT(handTracker[i])); - } + for (size_t i = 0; i < HAND_COUNT; ++i) { + REQUIRE(XR_SUCCESS == xrDestroyHandTrackerEXT(handTracker[i])); } } diff --git a/src/conformance/conformance_test/test_XR_EXT_palm_pose.cpp b/src/conformance/conformance_test/test_XR_EXT_palm_pose.cpp index 5391e7fd..3d2cb6c5 100644 --- a/src/conformance/conformance_test/test_XR_EXT_palm_pose.cpp +++ b/src/conformance/conformance_test/test_XR_EXT_palm_pose.cpp @@ -46,7 +46,7 @@ namespace Conformance constexpr XrVector3f Up{0, 1, 0}; // Purpose: Ensure that the action space for palm can be used for placing a hand representation. - TEST_CASE("XR_EXT_palm_pose", "[scenario][interactive][no_auto]") + TEST_CASE("XR_EXT_palm_pose", "[XR_EXT_palm_pose][scenario][interactive][no_auto]") { GlobalData& globalData = GetGlobalData(); if (!globalData.IsInstanceExtensionSupported(XR_EXT_PALM_POSE_EXTENSION_NAME)) { @@ -408,4 +408,157 @@ namespace Conformance RenderLoop(compositionHelper.GetSession(), update).Loop(); } + + TEST_CASE("XR_EXT_palm_pose-noninteractive", "[XR_EXT_palm_pose]") + { + GlobalData& globalData = GetGlobalData(); + if (!globalData.IsInstanceExtensionSupported(XR_EXT_PALM_POSE_EXTENSION_NAME)) { + SKIP(); + } + + AutoBasicInstance instance({XR_EXT_PALM_POSE_EXTENSION_NAME}); + + // Set up the actions. + const std::array subactionPaths{StringToPath(instance, "/user/hand/left"), StringToPath(instance, "/user/hand/right")}; + + XrActionSet actionSet; + XrAction gripPoseAction, aimPoseAction, handModelPoseAction; + { + XrActionSetCreateInfo actionSetInfo{XR_TYPE_ACTION_SET_CREATE_INFO}; + strcpy(actionSetInfo.actionSetName, "conformance_test"); + strcpy(actionSetInfo.localizedActionSetName, "Conformance Test"); + XRC_CHECK_THROW_XRCMD(xrCreateActionSet(instance, &actionSetInfo, &actionSet)); + + XrActionCreateInfo actionInfo{XR_TYPE_ACTION_CREATE_INFO}; + actionInfo.actionType = XR_ACTION_TYPE_POSE_INPUT; + actionInfo.subactionPaths = subactionPaths.data(); + actionInfo.countSubactionPaths = (uint32_t)subactionPaths.size(); + + strcpy(actionInfo.actionName, "grip_pose"); + strcpy(actionInfo.localizedActionName, "grip pose"); + actionInfo.subactionPaths = subactionPaths.data(); + actionInfo.countSubactionPaths = (uint32_t)subactionPaths.size(); + XRC_CHECK_THROW_XRCMD(xrCreateAction(actionSet, &actionInfo, &gripPoseAction)); + + strcpy(actionInfo.actionName, "aim_pose"); + strcpy(actionInfo.localizedActionName, "aim pose"); + actionInfo.subactionPaths = subactionPaths.data(); + actionInfo.countSubactionPaths = (uint32_t)subactionPaths.size(); + XRC_CHECK_THROW_XRCMD(xrCreateAction(actionSet, &actionInfo, &aimPoseAction)); + + strcpy(actionInfo.actionName, "palm_pose"); + strcpy(actionInfo.localizedActionName, "palm pose"); + actionInfo.subactionPaths = subactionPaths.data(); + actionInfo.countSubactionPaths = (uint32_t)subactionPaths.size(); + XRC_CHECK_THROW_XRCMD(xrCreateAction(actionSet, &actionInfo, &handModelPoseAction)); + } + + const std::vector bindings = { + {gripPoseAction, StringToPath(instance, "/user/hand/left/input/grip/pose")}, + {gripPoseAction, StringToPath(instance, "/user/hand/right/input/grip/pose")}, + {aimPoseAction, StringToPath(instance, "/user/hand/left/input/aim/pose")}, + {aimPoseAction, StringToPath(instance, "/user/hand/right/input/aim/pose")}, + {handModelPoseAction, StringToPath(instance, "/user/hand/left/input/palm_ext/pose")}, + {handModelPoseAction, StringToPath(instance, "/user/hand/right/input/palm_ext/pose")}, + }; + + XrInteractionProfileSuggestedBinding suggestedBindings{XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING}; + suggestedBindings.interactionProfile = StringToPath(instance, "/interaction_profiles/khr/simple_controller"); + suggestedBindings.suggestedBindings = bindings.data(); + suggestedBindings.countSuggestedBindings = (uint32_t)bindings.size(); + XRC_CHECK_THROW_XRCMD(xrSuggestInteractionProfileBindings(instance, &suggestedBindings)); + + AutoBasicSession session(AutoBasicSession::beginSession | AutoBasicSession::createActions | AutoBasicSession::createSpaces | + AutoBasicSession::createSwapchains, + instance); + + // how long the test should wait for the app to get focus: 10 seconds in release, infinite in debug builds. + auto timeout = (GetGlobalData().options.debugMode ? 3600s : 10s); + CAPTURE(timeout); + + // Get frames iterating to the point of app focused state. This will draw frames along the way. + FrameIterator frameIterator(&session); + FrameIterator::RunResult runResult = frameIterator.RunToSessionState(XR_SESSION_STATE_FOCUSED, timeout); + REQUIRE(runResult == FrameIterator::RunResult::Success); + + XrSessionActionSetsAttachInfo attachInfo{XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO}; + attachInfo.actionSets = &actionSet; + attachInfo.countActionSets = 1; + XRC_CHECK_THROW_XRCMD(xrAttachSessionActionSets(session, &attachInfo)); + + XrActionsSyncInfo syncInfo{XR_TYPE_ACTIONS_SYNC_INFO}; + XrActiveActionSet activeActionSet{actionSet}; + syncInfo.activeActionSets = &activeActionSet; + syncInfo.countActiveActionSets = 1; + + REQUIRE_RESULT(xrSyncActions(session, &syncInfo), XR_SUCCESS); + + // Set up the spaces. + std::array oculusBaseControllerSpaces; + + std::array gripSpaces; + std::array aimSpaces; + std::array handSpaces; + + XrSpace localSpace{XR_NULL_HANDLE}; + XrReferenceSpaceCreateInfo createSpaceInfo{XR_TYPE_REFERENCE_SPACE_CREATE_INFO}; + createSpaceInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL; + createSpaceInfo.poseInReferenceSpace = XrPosefCPP(); + REQUIRE_RESULT(xrCreateReferenceSpace(session, &createSpaceInfo, &localSpace), XR_SUCCESS); + + for (int i = 0; i < 2; ++i) { + XrActionSpaceCreateInfo spaceCreateInfo{XR_TYPE_ACTION_SPACE_CREATE_INFO}; + spaceCreateInfo.subactionPath = subactionPaths[i]; + spaceCreateInfo.action = aimPoseAction; + spaceCreateInfo.poseInActionSpace = {{0.f, 0.f, 0.f, 1.f}, {0.f, 0.f, 0.55f}}; + XRC_CHECK_THROW_XRCMD(xrCreateActionSpace(session, &spaceCreateInfo, &oculusBaseControllerSpaces[i])); + } + + for (int i = 0; i < 2; ++i) { + XrActionSpaceCreateInfo spaceCreateInfo{XR_TYPE_ACTION_SPACE_CREATE_INFO}; + spaceCreateInfo.subactionPath = subactionPaths[i]; + spaceCreateInfo.action = gripPoseAction; + spaceCreateInfo.poseInActionSpace = XrPosefCPP(); + XRC_CHECK_THROW_XRCMD(xrCreateActionSpace(session, &spaceCreateInfo, &gripSpaces[i])); + } + + for (int i = 0; i < 2; ++i) { + XrActionSpaceCreateInfo spaceCreateInfo{XR_TYPE_ACTION_SPACE_CREATE_INFO}; + spaceCreateInfo.subactionPath = subactionPaths[i]; + spaceCreateInfo.action = aimPoseAction; + spaceCreateInfo.poseInActionSpace = XrPosefCPP(); + XRC_CHECK_THROW_XRCMD(xrCreateActionSpace(session, &spaceCreateInfo, &aimSpaces[i])); + } + + for (int i = 0; i < 2; ++i) { + XrActionSpaceCreateInfo spaceCreateInfo{XR_TYPE_ACTION_SPACE_CREATE_INFO}; + spaceCreateInfo.subactionPath = subactionPaths[i]; + spaceCreateInfo.action = handModelPoseAction; + spaceCreateInfo.poseInActionSpace = XrPosefCPP(); + XRC_CHECK_THROW_XRCMD(xrCreateActionSpace(session, &spaceCreateInfo, &handSpaces[i])); + } + + for (int i = 0; i < 2; ++i) { + CAPTURE(i == 0 ? "Left hand" : "Right hand"); + { + XrSpaceLocation gripSpaceLocation{XR_TYPE_SPACE_LOCATION}; + XRC_CHECK_THROW_XRCMD(xrLocateSpace(gripSpaces[i], oculusBaseControllerSpaces[i], + frameIterator.frameState.predictedDisplayTime, &gripSpaceLocation)); + // Not going to check the result here - controller might not even be active... + } + { + XrSpaceLocation aimSpaceLocation{XR_TYPE_SPACE_LOCATION}; + XRC_CHECK_THROW_XRCMD(xrLocateSpace(aimSpaces[i], oculusBaseControllerSpaces[i], + frameIterator.frameState.predictedDisplayTime, &aimSpaceLocation)); + // Not going to check the result here - controller might not even be active... + } + { + XrSpaceLocation palmSpaceLocation{XR_TYPE_SPACE_LOCATION}; + XRC_CHECK_THROW_XRCMD(xrLocateSpace(handSpaces[i], oculusBaseControllerSpaces[i], + frameIterator.frameState.predictedDisplayTime, &palmSpaceLocation)); + // Not going to check the result here - controller might not even be active... + } + } + } + } // namespace Conformance diff --git a/src/conformance/conformance_test/test_XR_MSFT_controller_model.cpp b/src/conformance/conformance_test/test_XR_MSFT_controller_model.cpp new file mode 100644 index 00000000..ce6833fc --- /dev/null +++ b/src/conformance/conformance_test/test_XR_MSFT_controller_model.cpp @@ -0,0 +1,273 @@ +// Copyright (c) 2019-2023, The Khronos Group Inc. +// +// SPDX-License-Identifier: Apache-2.0 + +#include "action_utils.h" +#include "composition_utils.h" +#include "conformance_framework.h" +#include "conformance_utils.h" +#include "report.h" +#include "two_call.h" +#include "two_call_struct_metadata.h" +#include "two_call_struct_tests.h" + +#include "common/hex_and_handles.h" +#include "utilities/utils.h" + +#include +#include + +#include +#include +#include +#include +#include + +namespace Conformance +{ + struct ExtensionDataForXR_MSFT_controller_model + { + XrInstance instance; + PFN_xrGetControllerModelKeyMSFT xrGetControllerModelKeyMSFT_; + PFN_xrGetControllerModelPropertiesMSFT xrGetControllerModelPropertiesMSFT_; + PFN_xrGetControllerModelStateMSFT xrGetControllerModelStateMSFT_; + PFN_xrLoadControllerModelMSFT xrLoadControllerModelMSFT_; + + ExtensionDataForXR_MSFT_controller_model(XrInstance instance_) + : instance(instance_) + , xrGetControllerModelKeyMSFT_( + GetInstanceExtensionFunction(instance, "xrGetControllerModelKeyMSFT")) + , xrGetControllerModelPropertiesMSFT_(GetInstanceExtensionFunction( + instance, "xrGetControllerModelPropertiesMSFT")) + , xrGetControllerModelStateMSFT_( + GetInstanceExtensionFunction(instance, "xrGetControllerModelStateMSFT")) + , xrLoadControllerModelMSFT_( + GetInstanceExtensionFunction(instance, "xrLoadControllerModelMSFT")) + { + } + + void CheckInvalidModelKey(XrSession session, XrControllerModelKeyMSFT modelKey) const + { + INFO("Known-invalid model key: " << Uint64ToHexString(modelKey)); + uint32_t countOutput = 0; + CHECK(XR_ERROR_CONTROLLER_MODEL_KEY_INVALID_MSFT == xrLoadControllerModelMSFT_(session, modelKey, 0, &countOutput, NULL)); + + XrControllerModelPropertiesMSFT modelProperties{XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT}; + CHECK(XR_ERROR_CONTROLLER_MODEL_KEY_INVALID_MSFT == xrGetControllerModelPropertiesMSFT_(session, modelKey, &modelProperties)); + + XrControllerModelStateMSFT modelState{XR_TYPE_CONTROLLER_MODEL_STATE_MSFT}; + CHECK(XR_ERROR_CONTROLLER_MODEL_KEY_INVALID_MSFT == xrGetControllerModelStateMSFT_(session, modelKey, &modelState)); + } + + void CheckValidModelKeys(XrSession session, const std::vector& modelKeys) + { + + // Check two call struct for controller model properties and states, + // plus regular two-call for the model itself + auto modelPropertiesTwoCallData = getTwoCallStructData(); + auto modelStateTwoCallData = getTwoCallStructData(); + for (auto modelKey : modelKeys) { + INFO("Model key: " << Uint64ToHexString(modelKey)); + CheckTwoCallStructConformance(modelPropertiesTwoCallData, {XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT}, + "xrGetControllerModelPropertiesMSFT", false, + [&](XrControllerModelPropertiesMSFT* properties) { + return xrGetControllerModelPropertiesMSFT_(session, modelKey, properties); + }); + + CheckTwoCallStructConformance( + modelStateTwoCallData, {XR_TYPE_CONTROLLER_MODEL_STATE_MSFT}, "xrGetControllerModelStateMSFT", false, + [&](XrControllerModelStateMSFT* state) { return xrGetControllerModelStateMSFT_(session, modelKey, state); }); + CHECK_TWO_CALL(uint8_t, {}, xrLoadControllerModelMSFT_, session, modelKey); + } + + // Try inventing some model keys that will be invalid. + + for (auto modelKey : modelKeys) { + XrControllerModelKeyMSFT fakeModelKey = modelKey + 1234; + if (std::find(modelKeys.begin(), modelKeys.end(), fakeModelKey) == modelKeys.end()) { + // We invented an invalid key + INFO("Invented model key: " << Uint64ToHexString(fakeModelKey)); + CheckInvalidModelKey(session, fakeModelKey); + } + } + } + }; + + TEST_CASE("XR_MSFT_controller_model-simple", "") + { + GlobalData& globalData = GetGlobalData(); + + if (!globalData.IsInstanceExtensionSupported(XR_MSFT_CONTROLLER_MODEL_EXTENSION_NAME)) { + SKIP(XR_MSFT_CONTROLLER_MODEL_EXTENSION_NAME " not supported"); + } + + AutoBasicInstance instance({"XR_MSFT_controller_model"}); + AutoBasicSession session(AutoBasicSession::OptionFlags::createSession, instance); + ExtensionDataForXR_MSFT_controller_model ext(instance); + ext.CheckInvalidModelKey(session, XR_NULL_CONTROLLER_MODEL_KEY_MSFT); + } + + TEST_CASE("XR_MSFT_controller_model", "") + { + GlobalData& globalData = GetGlobalData(); + + if (!globalData.IsInstanceExtensionSupported(XR_MSFT_CONTROLLER_MODEL_EXTENSION_NAME)) { + SKIP(XR_MSFT_CONTROLLER_MODEL_EXTENSION_NAME " not supported"); + } + + CompositionHelper compositionHelper("XR_MSFT_controller_model", {"XR_MSFT_controller_model"}); + XrInstance instance = compositionHelper.GetInstance(); + + ExtensionDataForXR_MSFT_controller_model ext(instance); + + ActionLayerManager actionLayerManager(compositionHelper); + XrPath simpleKHR = StringToPath(instance, "/interaction_profiles/microsoft/motion_controller"); + XrPath leftHandPath{StringToPath(instance, "/user/hand/left")}; + std::shared_ptr leftHandInputDevice = + CreateTestDevice(&actionLayerManager, &compositionHelper.GetInteractionManager(), instance, compositionHelper.GetSession(), + simpleKHR, leftHandPath, cWMRControllerIPData); + + XrPath rightHandPath{StringToPath(instance, "/user/hand/right")}; + std::shared_ptr rightHandInputDevice = + CreateTestDevice(&actionLayerManager, &compositionHelper.GetInteractionManager(), instance, compositionHelper.GetSession(), + simpleKHR, rightHandPath, cWMRControllerIPData); + + const std::vector subactionPaths{leftHandPath, rightHandPath}; + + XrActionSet actionSet; + XrAction gripPoseAction; + { + XrActionSetCreateInfo actionSetInfo{XR_TYPE_ACTION_SET_CREATE_INFO}; + strcpy(actionSetInfo.actionSetName, "interaction_test"); + strcpy(actionSetInfo.localizedActionSetName, "Interaction Test"); + REQUIRE_RESULT_UNQUALIFIED_SUCCESS(xrCreateActionSet(instance, &actionSetInfo, &actionSet)); + + XrActionCreateInfo actionInfo{XR_TYPE_ACTION_CREATE_INFO}; + actionInfo.subactionPaths = subactionPaths.data(); + actionInfo.countSubactionPaths = (uint32_t)subactionPaths.size(); + actionInfo.actionType = XR_ACTION_TYPE_POSE_INPUT; + strcpy(actionInfo.actionName, "grip_pose"); + strcpy(actionInfo.localizedActionName, "Grip pose"); + actionInfo.subactionPaths = subactionPaths.data(); + actionInfo.countSubactionPaths = (uint32_t)subactionPaths.size(); + REQUIRE_RESULT_UNQUALIFIED_SUCCESS(xrCreateAction(actionSet, &actionInfo, &gripPoseAction)); + } + + compositionHelper.BeginSession(); + actionLayerManager.WaitForSessionFocusWithMessage(); + + compositionHelper.GetInteractionManager().AddActionSet(actionSet); + compositionHelper.GetInteractionManager().AddActionBindings( + StringToPath(instance, "/interaction_profiles/microsoft/motion_controller"), + {{{gripPoseAction, StringToPath(instance, "/user/hand/left/input/grip")}, + {gripPoseAction, StringToPath(instance, "/user/hand/right/input/grip")}}}); + compositionHelper.GetInteractionManager().AttachActionSets(); + + XrActionsSyncInfo syncInfo{XR_TYPE_ACTIONS_SYNC_INFO}; + XrActiveActionSet activeActionSet{actionSet}; + syncInfo.activeActionSets = &activeActionSet; + syncInfo.countActiveActionSets = 1; + + XrActionSpaceCreateInfo actionSpaceCreateInfo{XR_TYPE_ACTION_SPACE_CREATE_INFO}; + actionSpaceCreateInfo.poseInActionSpace = XrPosef{Quat::Identity, {0, 0, 0}}; + + std::vector gripSpaces; + for (std::shared_ptr controller : {leftHandInputDevice, rightHandInputDevice}) { + actionSpaceCreateInfo.subactionPath = leftHandInputDevice->TopLevelPath(); + actionSpaceCreateInfo.action = gripPoseAction; + XrSpace gripSpace; + XRC_CHECK_THROW_XRCMD(xrCreateActionSpace(compositionHelper.GetSession(), &actionSpaceCreateInfo, &gripSpace)); + gripSpaces.push_back(gripSpace); + } + + actionLayerManager.SyncActionsUntilFocusWithMessage(syncInfo); + + XrSession session = compositionHelper.GetSession(); + + std::vector modelKeys; + std::map pathsAndKeys; + // std::vector> pathsAndKeys; + + bool gotAllKeys = WaitUntilPredicateWithTimeout( + [&]() { + actionLayerManager.IterateFrame(); + + xrSyncActions(compositionHelper.GetSession(), &syncInfo); + + for (XrPath subactionPath : subactionPaths) { + if (pathsAndKeys.count(subactionPath)) { + continue; + } + XrControllerModelKeyStateMSFT modelKeyState{XR_TYPE_CONTROLLER_MODEL_KEY_STATE_MSFT}; + CHECK_RESULT_UNQUALIFIED_SUCCESS(ext.xrGetControllerModelKeyMSFT_(session, subactionPath, &modelKeyState)); + if (modelKeyState.modelKey != XR_NULL_CONTROLLER_MODEL_KEY_MSFT) { + // we got one + modelKeys.emplace_back(modelKeyState.modelKey); + pathsAndKeys.emplace(subactionPath, modelKeyState.modelKey); + // pathsAndKeys.emplace_back(subactionPath, modelKeyState.modelKey); + } + else { + } + } + + return (pathsAndKeys.size() == subactionPaths.size()); + }, + 20s, kActionWaitDelay); + + if (pathsAndKeys.empty()) { + WARN("Cannot do further testing on XR_MSFT_controller_model: no bound subaction paths have controller model keys"); + return; + } + else if (!gotAllKeys) { + WARN("Only some bound subaction paths have controller model keys"); + } + + // Check two call struct for controller model properties and states, + // plus regular two-call for the model itself + auto modelPropertiesTwoCallData = getTwoCallStructData(); + auto modelStateTwoCallData = getTwoCallStructData(); + for (auto modelKey : modelKeys) { + INFO("Model key: " << Uint64ToHexString(modelKey)); + CheckTwoCallStructConformance(modelPropertiesTwoCallData, {XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT}, + "xrGetControllerModelPropertiesMSFT", false, [&](XrControllerModelPropertiesMSFT* properties) { + return ext.xrGetControllerModelPropertiesMSFT_(session, modelKey, properties); + }); + + CheckTwoCallStructConformance( + modelStateTwoCallData, {XR_TYPE_CONTROLLER_MODEL_STATE_MSFT}, "xrGetControllerModelStateMSFT", false, + [&](XrControllerModelStateMSFT* state) { return ext.xrGetControllerModelStateMSFT_(session, modelKey, state); }); + CHECK_TWO_CALL(uint8_t, {}, ext.xrLoadControllerModelMSFT_, session, modelKey); + + CheckTwoCallStructConformance(modelPropertiesTwoCallData, {XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT}, + "xrGetControllerModelPropertiesMSFT", false, [&](XrControllerModelPropertiesMSFT* properties) { + return ext.xrGetControllerModelPropertiesMSFT_(session, modelKey, properties); + }); + + XrControllerModelPropertiesMSFT modelProperties{XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT}; + REQUIRE_RESULT_UNQUALIFIED_SUCCESS(ext.xrGetControllerModelPropertiesMSFT_(session, modelKey, &modelProperties)); + std::vector nodeBuffer(modelProperties.nodeCountOutput); + modelProperties.nodeCapacityInput = (uint32_t)nodeBuffer.size(); + modelProperties.nodeProperties = nodeBuffer.data(); + REQUIRE_RESULT_UNQUALIFIED_SUCCESS(ext.xrGetControllerModelPropertiesMSFT_(session, modelKey, &modelProperties)); + XrControllerModelStateMSFT modelState{XR_TYPE_CONTROLLER_MODEL_STATE_MSFT}; + REQUIRE_RESULT_UNQUALIFIED_SUCCESS(ext.xrGetControllerModelStateMSFT_(session, modelKey, &modelState)); + uint32_t modelBufferSize; + REQUIRE_RESULT_UNQUALIFIED_SUCCESS(ext.xrLoadControllerModelMSFT_(session, modelKey, 0, &modelBufferSize, nullptr)); + std::vector modelBuffer(modelBufferSize); + REQUIRE_RESULT_UNQUALIFIED_SUCCESS( + ext.xrLoadControllerModelMSFT_(session, modelKey, modelBufferSize, &modelBufferSize, modelBuffer.data())); + //! @todo Check that the model is valid, that it contains the nodes mentioned in the properties, and that the properties list is the same length as the state list + } + + // Try inventing some model keys that will be invalid. + + for (auto modelKey : modelKeys) { + XrControllerModelKeyMSFT fakeModelKey = modelKey + 1234; + if (std::find(modelKeys.begin(), modelKeys.end(), fakeModelKey) == modelKeys.end()) { + // We invented an invalid key + INFO("Invented model key: " << Uint64ToHexString(fakeModelKey)); + ext.CheckInvalidModelKey(session, fakeModelKey); + } + } + } +} // namespace Conformance diff --git a/src/conformance/framework/CMakeLists.txt b/src/conformance/framework/CMakeLists.txt index 2281d7c8..44ca88f6 100644 --- a/src/conformance/framework/CMakeLists.txt +++ b/src/conformance/framework/CMakeLists.txt @@ -81,11 +81,8 @@ if(WIN32) target_compile_options(conformance_framework PUBLIC /Zc:wchar_t /Zc:forScope /W4 /WX /wd4996) - # Right now can't build this on MinGW because of directxcolors, etc. + # Right now can't build this on MinGW because of directxcolors, directxmath, etc. target_link_libraries(conformance_framework PUBLIC d3d11 d3d12 d3dcompiler dxgi) - else() - target_compile_definitions(conformance_framework - PUBLIC MISSING_DIRECTX_COLORS) endif() endif() diff --git a/src/conformance/framework/action_utils.cpp b/src/conformance/framework/action_utils.cpp index 8d210d0a..fddbb4d5 100644 --- a/src/conformance/framework/action_utils.cpp +++ b/src/conformance/framework/action_utils.cpp @@ -82,7 +82,6 @@ namespace Conformance const std::string message = "Waiting for " + hand + " controller to " + (expectLocatability ? "gain" : "lose") + " tracking..."; bool success = WaitWithMessage(message.c_str(), [&]() { - GetRenderLoop().IterateFrame(); REQUIRE_RESULT(xrLocateSpace(space, localSpace, GetRenderLoop().GetLastPredictedDisplayTime(), location), XR_SUCCESS); constexpr XrSpaceLocationFlags LocatableFlags = XR_SPACE_LOCATION_ORIENTATION_VALID_BIT | XR_SPACE_LOCATION_POSITION_VALID_BIT; diff --git a/src/conformance/framework/graphics_plugin_d3d11.cpp b/src/conformance/framework/graphics_plugin_d3d11.cpp index 6b2ac971..a2dee28e 100644 --- a/src/conformance/framework/graphics_plugin_d3d11.cpp +++ b/src/conformance/framework/graphics_plugin_d3d11.cpp @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#if defined(XR_USE_GRAPHICS_API_D3D11) && !defined(MISSING_DIRECTX_COLORS) +#if defined(XR_USE_GRAPHICS_API_D3D11) #include "graphics_plugin.h" #include "common/xr_linear.h" diff --git a/src/conformance/framework/graphics_plugin_d3d12.cpp b/src/conformance/framework/graphics_plugin_d3d12.cpp index e24c89c8..cd7b438d 100644 --- a/src/conformance/framework/graphics_plugin_d3d12.cpp +++ b/src/conformance/framework/graphics_plugin_d3d12.cpp @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#if defined(XR_USE_GRAPHICS_API_D3D12) && !defined(MISSING_DIRECTX_COLORS) +#if defined(XR_USE_GRAPHICS_API_D3D12) #include "graphics_plugin.h" #include "common/xr_linear.h" diff --git a/src/conformance/framework/graphics_plugin_opengl.cpp b/src/conformance/framework/graphics_plugin_opengl.cpp index 5bdc4881..3ce587ab 100644 --- a/src/conformance/framework/graphics_plugin_opengl.cpp +++ b/src/conformance/framework/graphics_plugin_opengl.cpp @@ -23,6 +23,7 @@ #include "report.h" #include "swapchain_image_data.h" #include "utilities/Geometry.h" +#include "utilities/swapchain_format_data.h" #include "utilities/swapchain_parameters.h" #include "utilities/throw_helpers.h" #include "xr_dependencies.h" @@ -37,8 +38,6 @@ #include "gfxwrapper_opengl.h" -// clang-format off - // Note: mapping of OpenXR usage flags to OpenGL // // XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT: can be bound to a framebuffer as color @@ -53,227 +52,94 @@ // Note: no GL formats are "mutableFormats" in the sense of SwapchainCreateTestParameters as this is intended for TYPELESS, // however, some are "supportsMutableFormat" -// For now don't test XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT on GL since the semantics are unclear and some runtimes don't support this flag. -#define XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT 0 - -#define XRC_ALL_CREATE_FLAGS \ -{ \ - 0, XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT, XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT, XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT | XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT \ -} - -// the app might request any combination of flags -#define XRC_COLOR_UA_COPY_SAMPLED_MUTABLE_USAGE_FLAGS \ -{ \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ -} -#define XRC_COLOR_UA_SAMPLED_MUTABLE_USAGE_FLAGS \ -{ \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ -} -#define XRC_COLOR_COPY_SAMPLED_USAGE_FLAGS \ -{ \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ -} -#define XRC_COLOR_COPY_SAMPLED_MUTABLE_USAGE_FLAGS \ -{ \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ -} -#define XRC_COLOR_SAMPLED_USAGE_FLAGS \ -{ \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, \ - XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ -} -#define XRC_DEPTH_COPY_SAMPLED_USAGE_FLAGS \ -{ \ - XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, \ - XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, \ - XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT, \ - XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, \ - XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ -} -#define XRC_DEPTH_SAMPLED_USAGE_FLAGS \ -{ \ - XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, \ - XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ -} - -#define XRC_COMPRESSED_SAMPLED_MUTABLE_USAGE_FLAGS \ -{ \ - XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ - XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ - XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, \ -} -#define XRC_COMPRESSED_SAMPLED_USAGE_FLAGS \ -{ \ - XR_SWAPCHAIN_USAGE_SAMPLED_BIT, \ -} - -#define ADD_GL_COLOR_UA_COPY_SAMPLED_MUTABLE_FORMAT2(FORMAT, NAME) \ -{ \ - {FORMAT}, \ - { \ - NAME, IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, FORMAT, XRC_COLOR_UA_COPY_SAMPLED_MUTABLE_USAGE_FLAGS, XRC_ALL_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ -} -#define ADD_GL_COLOR_UA_COPY_SAMPLED_MUTABLE_FORMAT(X) ADD_GL_COLOR_UA_COPY_SAMPLED_MUTABLE_FORMAT2(X, #X) - -#define ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT2(FORMAT, NAME) \ -{ \ - {FORMAT}, \ - { \ - NAME, IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, FORMAT, XRC_COLOR_UA_SAMPLED_MUTABLE_USAGE_FLAGS, XRC_ALL_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ -} -#define ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(X) ADD_GL_COLOR_UA_COPY_SAMPLED_MUTABLE_FORMAT2(X, #X) - -#define ADD_GL_COLOR_COPY_SAMPLED_FORMAT2(FORMAT, NAME) \ -{ \ - {FORMAT}, \ - { \ - NAME, IMMUTABLE, NO_MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, FORMAT, XRC_COLOR_COPY_SAMPLED_USAGE_FLAGS, XRC_ALL_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ -} -#define ADD_GL_COLOR_COPY_SAMPLED_FORMAT(X) ADD_GL_COLOR_COPY_SAMPLED_FORMAT2(X, #X) - -#define ADD_GL_COLOR_COPY_SAMPLED_MUTABLE_FORMAT2(FORMAT, NAME) \ -{ \ - {FORMAT}, \ - { \ - NAME, IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, FORMAT, XRC_COLOR_COPY_SAMPLED_MUTABLE_USAGE_FLAGS, XRC_ALL_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ -} -#define ADD_GL_COLOR_COPY_SAMPLED_MUTABLE_FORMAT(X) ADD_GL_COLOR_COPY_SAMPLED_MUTABLE_FORMAT2(X, #X) - -#define ADD_GL_COLOR_SAMPLED_FORMAT2(FORMAT, NAME) \ -{ \ - {FORMAT}, \ - { \ - NAME, IMMUTABLE, NO_MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, FORMAT, XRC_COLOR_SAMPLED_USAGE_FLAGS, XRC_ALL_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ -} -#define ADD_GL_COLOR_SAMPLED_FORMAT(X) ADD_GL_COLOR_SAMPLED_FORMAT2(X, #X) - -#define ADD_GL_DEPTH_COPY_SAMPLED_FORMAT2(FORMAT, NAME) \ -{ \ - {FORMAT}, \ - { \ - NAME, IMMUTABLE, NO_MUT_SUPPORT, NON_COLOR, UNCOMPRESSED, RENDERING_SUPPORT, FORMAT, XRC_DEPTH_COPY_SAMPLED_USAGE_FLAGS, XRC_ALL_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ -} -#define ADD_GL_DEPTH_COPY_SAMPLED_FORMAT(X) ADD_GL_DEPTH_COPY_SAMPLED_FORMAT2(X, #X) - -#define ADD_GL_DEPTH_SAMPLED_FORMAT2(FORMAT, NAME) \ -{ \ - {FORMAT}, \ - { \ - NAME, IMMUTABLE, NO_MUT_SUPPORT, NON_COLOR, UNCOMPRESSED, RENDERING_SUPPORT, FORMAT, XRC_DEPTH_SAMPLED_USAGE_FLAGS, XRC_ALL_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ -} -#define ADD_GL_DEPTH_SAMPLED_FORMAT(X) ADD_GL_DEPTH_SAMPLED_FORMAT2(X, #X) - -#define ADD_GL_COMPRESSED_SAMPLED_MUTABLE_FORMAT2(FORMAT, NAME) \ -{ \ - {FORMAT}, \ - { \ - NAME, IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, FORMAT, XRC_COMPRESSED_SAMPLED_MUTABLE_USAGE_FLAGS, XRC_ALL_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ -} -#define ADD_GL_COMPRESSED_SAMPLED_MUTABLE_FORMAT(X) ADD_GL_COMPRESSED_SAMPLED_MUTABLE_FORMAT2(X, #X) - -#define ADD_GL_COMPRESSED_SAMPLED_FORMAT2(FORMAT, NAME) \ -{ \ - {FORMAT}, \ - { \ - NAME, IMMUTABLE, NO_MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, FORMAT, XRC_COMPRESSED_SAMPLED_USAGE_FLAGS, XRC_ALL_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ -} -#define ADD_GL_COMPRESSED_SAMPLED_FORMAT(X) ADD_GL_COMPRESSED_SAMPLED_FORMAT2(X, #X) - -// clang-format on - namespace Conformance { + + // Only texture formats which are in OpenGL core and which are either color or depth renderable or + // of a specific compressed format are listed below. Runtimes can support additional formats, but those + // will not get tested. + // + // For now don't test XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT on GL since the semantics are unclear and some runtimes don't support this flag. + // TODO in the future remove this workaround? +#define WORKAROUND NotMutable() + static const SwapchainFormatDataMap& GetSwapchainFormatData() + { + static SwapchainFormatDataMap map{ + XRC_SWAPCHAIN_FORMAT(GL_RGBA8).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGBA16).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGB10_A2).WORKAROUND.ToPair(), + + XRC_SWAPCHAIN_FORMAT(GL_R8).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_R16).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RG8).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RG16).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGB10_A2UI).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_R16F).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RG16F).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGB16F).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGBA16F).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_R32F).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RG32F).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGBA32F).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_R11F_G11F_B10F).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_R8I).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_R8UI).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_R16I).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_R16UI).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_R32I).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_R32UI).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RG8I).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RG8UI).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RG16I).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RG16UI).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RG32I).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RG32UI).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGBA8I).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGBA8UI).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGBA16I).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGBA16UI).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGBA32I).WORKAROUND.ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGBA32UI).WORKAROUND.ToPair(), + + XRC_SWAPCHAIN_FORMAT(GL_RGBA4).WORKAROUND.NotMutable().NoUnorderedAccess().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_RGB5_A1).WORKAROUND.NotMutable().NoUnorderedAccess().ToPair(), + + XRC_SWAPCHAIN_FORMAT(GL_SRGB8).WORKAROUND.NoUnorderedAccess().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_SRGB8_ALPHA8).WORKAROUND.NoUnorderedAccess().ToPair(), + + XRC_SWAPCHAIN_FORMAT(GL_RGB565).WORKAROUND.NotMutable().NoUnorderedAccess().ToPair(), + + XRC_SWAPCHAIN_FORMAT(GL_DEPTH_COMPONENT16).WORKAROUND.Depth().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_DEPTH_COMPONENT24).WORKAROUND.Depth().ToPair(), + + XRC_SWAPCHAIN_FORMAT(GL_DEPTH_COMPONENT32F).WORKAROUND.Depth().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_DEPTH24_STENCIL8).WORKAROUND.DepthStencil().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_DEPTH32F_STENCIL8).WORKAROUND.DepthStencil().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_STENCIL_INDEX8).WORKAROUND.Stencil().ToPair(), + + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RED_RGTC1).WORKAROUND.Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SIGNED_RED_RGTC1).WORKAROUND.Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RG_RGTC2).WORKAROUND.Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SIGNED_RG_RGTC2).WORKAROUND.Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_BPTC_UNORM).WORKAROUND.Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM).WORKAROUND.Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT).WORKAROUND.Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT).WORKAROUND.Compressed().ToPair(), + + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGB8_ETC2).WORKAROUND.Compressed().NotMutable().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ETC2).WORKAROUND.Compressed().NotMutable().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2).WORKAROUND.Compressed().NotMutable().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2).WORKAROUND.Compressed().NotMutable().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA8_ETC2_EAC).WORKAROUND.Compressed().NotMutable().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC).WORKAROUND.Compressed().NotMutable().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_R11_EAC).WORKAROUND.Compressed().NotMutable().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SIGNED_R11_EAC).WORKAROUND.Compressed().NotMutable().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RG11_EAC).WORKAROUND.Compressed().NotMutable().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SIGNED_RG11_EAC).WORKAROUND.Compressed().NotMutable().ToPair(), + }; + return map; + } + std::string glResultString(GLenum err) { switch (err) { @@ -979,129 +845,20 @@ namespace Conformance deleteGLContext(); } - // Only texture formats which are in OpenGL core and which are either color or depth renderable or - // of a specific compressed format are listed below. Runtimes can support additional formats, but those - // will not get tested. - typedef std::map SwapchainTestMap; - SwapchainTestMap openGLSwapchainTestMap{ - ADD_GL_COLOR_UA_COPY_SAMPLED_MUTABLE_FORMAT(GL_RGBA8), - ADD_GL_COLOR_UA_COPY_SAMPLED_MUTABLE_FORMAT(GL_RGBA16), - ADD_GL_COLOR_UA_COPY_SAMPLED_MUTABLE_FORMAT(GL_RGB10_A2), - - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_R8), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_R16), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RG8), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RG16), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RGB10_A2UI), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_R16F), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RG16F), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RGB16F), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RGBA16F), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_R32F), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RG32F), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RGBA32F), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_R11F_G11F_B10F), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_R8I), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_R8UI), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_R16I), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_R16UI), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_R32I), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_R32UI), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RG8I), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RG8UI), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RG16I), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RG16UI), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RG32I), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RG32UI), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RGBA8I), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RGBA8UI), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RGBA16I), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RGBA16UI), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RGBA32I), - ADD_GL_COLOR_UA_SAMPLED_MUTABLE_FORMAT(GL_RGBA32UI), - - ADD_GL_COLOR_COPY_SAMPLED_FORMAT(GL_RGBA4), - ADD_GL_COLOR_COPY_SAMPLED_FORMAT(GL_RGB5_A1), - - ADD_GL_COLOR_COPY_SAMPLED_MUTABLE_FORMAT(GL_SRGB8), - ADD_GL_COLOR_COPY_SAMPLED_MUTABLE_FORMAT(GL_SRGB8_ALPHA8), - - ADD_GL_COLOR_SAMPLED_FORMAT(GL_RGB565), - - ADD_GL_DEPTH_COPY_SAMPLED_FORMAT(GL_DEPTH_COMPONENT16), - ADD_GL_DEPTH_COPY_SAMPLED_FORMAT(GL_DEPTH_COMPONENT24), - - ADD_GL_DEPTH_SAMPLED_FORMAT(GL_DEPTH_COMPONENT32F), - ADD_GL_DEPTH_SAMPLED_FORMAT(GL_DEPTH24_STENCIL8), - ADD_GL_DEPTH_SAMPLED_FORMAT(GL_DEPTH32F_STENCIL8), - ADD_GL_DEPTH_SAMPLED_FORMAT(GL_STENCIL_INDEX8), - - ADD_GL_COMPRESSED_SAMPLED_MUTABLE_FORMAT(GL_COMPRESSED_RED_RGTC1), - ADD_GL_COMPRESSED_SAMPLED_MUTABLE_FORMAT(GL_COMPRESSED_SIGNED_RED_RGTC1), - ADD_GL_COMPRESSED_SAMPLED_MUTABLE_FORMAT(GL_COMPRESSED_RG_RGTC2), - ADD_GL_COMPRESSED_SAMPLED_MUTABLE_FORMAT(GL_COMPRESSED_SIGNED_RG_RGTC2), - ADD_GL_COMPRESSED_SAMPLED_MUTABLE_FORMAT(GL_COMPRESSED_RGBA_BPTC_UNORM), - ADD_GL_COMPRESSED_SAMPLED_MUTABLE_FORMAT(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM), - ADD_GL_COMPRESSED_SAMPLED_MUTABLE_FORMAT(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT), - ADD_GL_COMPRESSED_SAMPLED_MUTABLE_FORMAT(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT), - - ADD_GL_COMPRESSED_SAMPLED_FORMAT(GL_COMPRESSED_RGB8_ETC2), - ADD_GL_COMPRESSED_SAMPLED_FORMAT(GL_COMPRESSED_SRGB8_ETC2), - ADD_GL_COMPRESSED_SAMPLED_FORMAT(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2), - ADD_GL_COMPRESSED_SAMPLED_FORMAT(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2), - ADD_GL_COMPRESSED_SAMPLED_FORMAT(GL_COMPRESSED_RGBA8_ETC2_EAC), - ADD_GL_COMPRESSED_SAMPLED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC), - ADD_GL_COMPRESSED_SAMPLED_FORMAT(GL_COMPRESSED_R11_EAC), - ADD_GL_COMPRESSED_SAMPLED_FORMAT(GL_COMPRESSED_SIGNED_R11_EAC), - ADD_GL_COMPRESSED_SAMPLED_FORMAT(GL_COMPRESSED_RG11_EAC), - ADD_GL_COMPRESSED_SAMPLED_FORMAT(GL_COMPRESSED_SIGNED_RG11_EAC), - }; - std::string OpenGLGraphicsPlugin::GetImageFormatName(int64_t imageFormat) const { - SwapchainTestMap::const_iterator it = openGLSwapchainTestMap.find(imageFormat); - - if (it != openGLSwapchainTestMap.end()) { - return it->second.imageFormatName; - } - - return std::string("unknown"); + return ::Conformance::GetImageFormatName(GetSwapchainFormatData(), imageFormat); } bool OpenGLGraphicsPlugin::IsImageFormatKnown(int64_t imageFormat) const { - SwapchainTestMap::const_iterator it = openGLSwapchainTestMap.find(imageFormat); - - return (it != openGLSwapchainTestMap.end()); + return ::Conformance::IsImageFormatKnown(GetSwapchainFormatData(), imageFormat); } bool OpenGLGraphicsPlugin::GetSwapchainCreateTestParameters(XrInstance /*instance*/, XrSession /*session*/, XrSystemId /*systemId*/, int64_t imageFormat, SwapchainCreateTestParameters* swapchainTestParameters) { - // Swapchain image format support by the runtime is specified by the xrEnumerateSwapchainFormats function. - // Runtimes should support R8G8B8A8 and R8G8B8A8 sRGB formats if possible. - - SwapchainTestMap::iterator it = openGLSwapchainTestMap.find(imageFormat); - - // Verify that the image format is known. If it's not known then this test needs to be - // updated to recognize new OpenGL formats. - CAPTURE(imageFormat); - CHECK_MSG(it != openGLSwapchainTestMap.end(), "Unknown OpenGL image format."); - if (it == openGLSwapchainTestMap.end()) { - return false; - } - - // We may now proceed with creating swapchains with the format. - SwapchainCreateTestParameters& tp = it->second; - tp.arrayCountVector = {1, 2}; - if (!tp.compressedFormat) { - tp.mipCountVector = {1, 2}; - } - else { - tp.mipCountVector = {1}; - } - - *swapchainTestParameters = tp; + *swapchainTestParameters = ::Conformance::GetSwapchainCreateTestParameters(GetSwapchainFormatData(), imageFormat); return true; } @@ -1189,8 +946,9 @@ namespace Conformance int64_t OpenGLGraphicsPlugin::SelectDepthSwapchainFormat(const int64_t* imageFormatArray, size_t count) const { // List of supported depth swapchain formats. - const std::array f{GL_DEPTH24_STENCIL8, GL_DEPTH32F_STENCIL8, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32F, - GL_DEPTH_COMPONENT16}; + const std::array f{ + GL_DEPTH24_STENCIL8, GL_DEPTH32F_STENCIL8, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT16, + }; const int64_t* formatArrayEnd = imageFormatArray + count; auto it = std::find_first_of(imageFormatArray, formatArrayEnd, f.begin(), f.end()); diff --git a/src/conformance/framework/graphics_plugin_opengles.cpp b/src/conformance/framework/graphics_plugin_opengles.cpp index e6800012..5632dd29 100644 --- a/src/conformance/framework/graphics_plugin_opengles.cpp +++ b/src/conformance/framework/graphics_plugin_opengles.cpp @@ -25,6 +25,7 @@ #include "report.h" #include "swapchain_image_data.h" #include "utilities/Geometry.h" +#include "utilities/swapchain_format_data.h" #include "utilities/swapchain_parameters.h" #include "utilities/throw_helpers.h" #include "xr_dependencies.h" @@ -581,251 +582,355 @@ namespace Conformance return std::make_shared(platformPlugin); } - // Shorthand constants for usage below. - static const uint64_t XRC_COLOR_TEXTURE_USAGE = (XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT); - - static const uint64_t XRC_COLOR_TEXTURE_USAGE_MUTABLE = (XRC_COLOR_TEXTURE_USAGE | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT); - - static const uint64_t XRC_COLOR_TEXTURE_USAGE_COMPRESSED = - (XR_SWAPCHAIN_USAGE_SAMPLED_BIT); // Compressed textures can't be rendered to, so no XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT. - - static const uint64_t XRC_DEPTH_TEXTURE_USAGE = (XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT); - -#define XRC_COLOR_CREATE_FLAGS \ - { \ - 0, XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT, XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT \ - } - -#define XRC_DEPTH_CREATE_FLAGS \ - { \ - 0, XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT, XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT \ - } + // For now don't test XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT on GL since the semantics are unclear and some runtimes don't support this flag. + // TODO in the future remove this workaround? +#define WORKAROUND NotMutable() + typedef std::map SwapchainTestMap; -// one for texture formats which are not known to the GL.h (where a more modern header would be needed): -#define ADD_GL_COLOR_FORMAT2(X, Y) \ - { \ - {X}, \ - { \ - Y, IMMUTABLE, NO_MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, X, \ - {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ - } -#define ADD_GL_COLOR_FORMAT(X) ADD_GL_COLOR_FORMAT2(X, #X) - -#define ADD_GL_COLOR_COMPRESSED_FORMAT2(X, Y) \ - { \ - {X}, \ - { \ - Y, IMMUTABLE, NO_MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, X, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, \ - XRC_COLOR_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ - } -#define ADD_GL_COLOR_COMPRESSED_FORMAT(X) ADD_GL_COLOR_COMPRESSED_FORMAT2(X, #X) - -#define ADD_GL_DEPTH_FORMAT2(X, Y) \ - { \ - {X}, \ - { \ - Y, IMMUTABLE, NO_MUT_SUPPORT, NON_COLOR, UNCOMPRESSED, RENDERING_SUPPORT, X, {XRC_DEPTH_TEXTURE_USAGE}, \ - XRC_DEPTH_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ + static const SwapchainFormatDataMap& GetSwapchainFormatData() + { + static SwapchainFormatDataMap map{ + + // + // 8 bits per component + // + XRC_SWAPCHAIN_FORMAT(GL_R8).WORKAROUND.ToPair(), // 1-component, 8-bit unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_RG8).WORKAROUND.ToPair(), // 2-component, 8-bit unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_RGB8).WORKAROUND.ToPair(), // 3-component, 8-bit unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_RGBA8).WORKAROUND.ToPair(), // 4-component, 8-bit unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_R8_SNORM).WORKAROUND.ToPair(), // 1-component, 8-bit signed normalized + XRC_SWAPCHAIN_FORMAT(GL_RG8_SNORM).WORKAROUND.ToPair(), // 2-component, 8-bit signed normalized + XRC_SWAPCHAIN_FORMAT(GL_RGB8_SNORM).WORKAROUND.ToPair(), // 3-component, 8-bit signed normalized + XRC_SWAPCHAIN_FORMAT(GL_RGBA8_SNORM).WORKAROUND.ToPair(), // 4-component, 8-bit signed normalized + XRC_SWAPCHAIN_FORMAT(GL_R8UI).WORKAROUND.ToPair(), // 1-component, 8-bit unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_RG8UI).WORKAROUND.ToPair(), // 2-component, 8-bit unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_RGB8UI).WORKAROUND.ToPair(), // 3-component, 8-bit unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_RGBA8UI).WORKAROUND.ToPair(), // 4-component, 8-bit unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_R8I).WORKAROUND.ToPair(), // 1-component, 8-bit signed integer + XRC_SWAPCHAIN_FORMAT(GL_RG8I).WORKAROUND.ToPair(), // 2-component, 8-bit signed integer + XRC_SWAPCHAIN_FORMAT(GL_RGB8I).WORKAROUND.ToPair(), // 3-component, 8-bit signed integer + XRC_SWAPCHAIN_FORMAT(GL_RGBA8I).WORKAROUND.ToPair(), // 4-component, 8-bit signed integer + XRC_SWAPCHAIN_FORMAT(GL_SR8).WORKAROUND.ToPair(), // 1-component, 8-bit sRGB + XRC_SWAPCHAIN_FORMAT(GL_SRG8).WORKAROUND.ToPair(), // 2-component, 8-bit sRGB + XRC_SWAPCHAIN_FORMAT(GL_SRGB8).WORKAROUND.ToPair(), // 3-component, 8-bit sRGB + XRC_SWAPCHAIN_FORMAT(GL_SRGB8_ALPHA8).WORKAROUND.ToPair(), // 4-component, 8-bit sRGB + + // + // 16 bits per component + // + XRC_SWAPCHAIN_FORMAT(GL_R16).WORKAROUND.ToPair(), // 1-component, 16-bit unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_RG16).WORKAROUND.ToPair(), // 2-component, 16-bit unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_RGB16).WORKAROUND.ToPair(), // 3-component, 16-bit unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_RGBA16).WORKAROUND.ToPair(), // 4-component, 16-bit unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_R16_SNORM).WORKAROUND.ToPair(), // 1-component, 16-bit signed normalized + XRC_SWAPCHAIN_FORMAT(GL_RG16_SNORM).WORKAROUND.ToPair(), // 2-component, 16-bit signed normalized + XRC_SWAPCHAIN_FORMAT(GL_RGB16_SNORM).WORKAROUND.ToPair(), // 3-component, 16-bit signed normalized + XRC_SWAPCHAIN_FORMAT(GL_RGBA16_SNORM).WORKAROUND.ToPair(), // 4-component, 16-bit signed normalized + XRC_SWAPCHAIN_FORMAT(GL_R16UI).WORKAROUND.ToPair(), // 1-component, 16-bit unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_RG16UI).WORKAROUND.ToPair(), // 2-component, 16-bit unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_RGB16UI).WORKAROUND.ToPair(), // 3-component, 16-bit unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_RGBA16UI).WORKAROUND.ToPair(), // 4-component, 16-bit unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_R16I).WORKAROUND.ToPair(), // 1-component, 16-bit signed integer + XRC_SWAPCHAIN_FORMAT(GL_RG16I).WORKAROUND.ToPair(), // 2-component, 16-bit signed integer + XRC_SWAPCHAIN_FORMAT(GL_RGB16I).WORKAROUND.ToPair(), // 3-component, 16-bit signed integer + XRC_SWAPCHAIN_FORMAT(GL_RGBA16I).WORKAROUND.ToPair(), // 4-component, 16-bit signed integer + XRC_SWAPCHAIN_FORMAT(GL_R16F).WORKAROUND.ToPair(), // 1-component, 16-bit floating-point + XRC_SWAPCHAIN_FORMAT(GL_RG16F).WORKAROUND.ToPair(), // 2-component, 16-bit floating-point + XRC_SWAPCHAIN_FORMAT(GL_RGB16F).WORKAROUND.ToPair(), // 3-component, 16-bit floating-point + XRC_SWAPCHAIN_FORMAT(GL_RGBA16F).WORKAROUND.ToPair(), // 4-component, 16-bit floating-point + + // + // 32 bits per component + // + XRC_SWAPCHAIN_FORMAT(GL_R32UI).WORKAROUND.ToPair(), // 1-component, 32-bit unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_RG32UI).WORKAROUND.ToPair(), // 2-component, 32-bit unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_RGB32UI).WORKAROUND.ToPair(), // 3-component, 32-bit unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_RGBA32UI).WORKAROUND.ToPair(), // 4-component, 32-bit unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_R32I).WORKAROUND.ToPair(), // 1-component, 32-bit signed integer + XRC_SWAPCHAIN_FORMAT(GL_RG32I).WORKAROUND.ToPair(), // 2-component, 32-bit signed integer + XRC_SWAPCHAIN_FORMAT(GL_RGB32I).WORKAROUND.ToPair(), // 3-component, 32-bit signed integer + XRC_SWAPCHAIN_FORMAT(GL_RGBA32I).WORKAROUND.ToPair(), // 4-component, 32-bit signed integer + XRC_SWAPCHAIN_FORMAT(GL_R32F).WORKAROUND.ToPair(), // 1-component, 32-bit floating-point + XRC_SWAPCHAIN_FORMAT(GL_RG32F).WORKAROUND.ToPair(), // 2-component, 32-bit floating-point + XRC_SWAPCHAIN_FORMAT(GL_RGB32F).WORKAROUND.ToPair(), // 3-component, 32-bit floating-point + XRC_SWAPCHAIN_FORMAT(GL_RGBA32F).WORKAROUND.ToPair(), // 4-component, 32-bit floating-point + + // + // Packed + // + XRC_SWAPCHAIN_FORMAT(GL_RGB5).WORKAROUND.ToPair(), // 3-component 5:5:5, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_RGB565).WORKAROUND.ToPair(), // 3-component 5:6:5, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_RGB10).WORKAROUND.ToPair(), // 3-component 10:10:10, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_RGBA4).WORKAROUND.ToPair(), // 4-component 4:4:4:4, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_RGB5_A1).WORKAROUND.ToPair(), // 4-component 5:5:5:1, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_RGB10_A2).WORKAROUND.ToPair(), // 4-component 10:10:10:2, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_RGB10_A2UI).WORKAROUND.ToPair(), // 4-component 10:10:10:2, unsigned integer + XRC_SWAPCHAIN_FORMAT(GL_R11F_G11F_B10F).WORKAROUND.ToPair(), // 3-component 11:11:10, floating-point + XRC_SWAPCHAIN_FORMAT(GL_RGB9_E5).WORKAROUND.ToPair(), // 3-component/exp 9:9:9/5, floating-point + + // + // S3TC/DXT/BC + // + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) + .Compressed() + .NotMutable() + .ToPair(), // line through 3D space, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) + .Compressed() + .NotMutable() + .ToPair(), // line through 3D space plus 1-bit alpha, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) + .Compressed() + .NotMutable() + .ToPair(), // line through 3D space plus line through 1D space, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) + .Compressed() + .NotMutable() + .ToPair(), // line through 3D space plus 4-bit alpha, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT) + .Compressed() + .NotMutable() + .ToPair(), // line through 3D space, 4x4 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT) + .Compressed() + .NotMutable() + .ToPair(), // line through 3D space plus 1-bit alpha, 4x4 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT) + .Compressed() + .NotMutable() + .ToPair(), // line through 3D space plus line through 1D space, 4x4 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) + .Compressed() + .NotMutable() + .ToPair(), // line through 3D space plus 4-bit alpha, 4x4 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_LUMINANCE_LATC1_EXT) + .Compressed() + .NotMutable() + .ToPair(), // line through 1D space, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT) + .Compressed() + .NotMutable() + .ToPair(), // two lines through 1D space, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT) + .Compressed() + .NotMutable() + .ToPair(), // line through 1D space, 4x4 blocks, signed normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT) + .Compressed() + .NotMutable() + .ToPair(), // two lines through 1D space, 4x4 blocks, signed normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RED_RGTC1) + .Compressed() + .NotMutable() + .ToPair(), // line through 1D space, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RG_RGTC2) + .Compressed() + .NotMutable() + .ToPair(), // two lines through 1D space, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SIGNED_RED_RGTC1) + .Compressed() + .NotMutable() + .ToPair(), // line through 1D space, 4x4 blocks, signed normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SIGNED_RG_RGTC2) + .Compressed() + .NotMutable() + .ToPair(), // two lines through 1D space, 4x4 blocks, signed normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) + .Compressed() + .NotMutable() + .ToPair(), // 3-component, 4x4 blocks, unsigned floating-point + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT) + .Compressed() + .NotMutable() + .ToPair(), // 3-component, 4x4 blocks, signed floating-point + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_BPTC_UNORM) + .Compressed() + .NotMutable() + .ToPair(), // 4-component, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM).Compressed().NotMutable().ToPair(), // 4-component, 4x4 blocks, sRGB + + // + // ETC + // + XRC_SWAPCHAIN_FORMAT(GL_ETC1_RGB8_OES).Compressed().NotMutable().ToPair(), // 3-component ETC1, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGB8_ETC2) + .Compressed() + .NotMutable() + .ToPair(), // 3-component ETC2, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ETC2 with 1-bit alpha, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA8_ETC2_EAC) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ETC2, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ETC2).Compressed().NotMutable().ToPair(), // 3-component ETC2, 4x4 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ETC2 with 1-bit alpha, 4x4 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ETC2, 4x4 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_R11_EAC) + .Compressed() + .NotMutable() + .ToPair(), // 1-component ETC, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RG11_EAC) + .Compressed() + .NotMutable() + .ToPair(), // 2-component ETC, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SIGNED_R11_EAC) + .Compressed() + .NotMutable() + .ToPair(), // 1-component ETC, 4x4 blocks, signed normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SIGNED_RG11_EAC) + .Compressed() + .NotMutable() + .ToPair(), // 2-component ETC, 4x4 blocks, signed normalized + + // + // ASTC + // + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_4x4_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 4x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_5x4_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 5x4 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_5x5_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 5x5 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_6x5_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 6x5 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_6x6_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 6x6 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_8x5_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 8x5 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_8x6_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 8x6 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_8x8_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 8x8 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_10x5_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 10x5 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_10x6_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 10x6 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_10x8_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 10x8 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_10x10_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 10x10 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_12x10_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 12x10 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_RGBA_ASTC_12x12_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 12x12 blocks, unsigned normalized + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 4x4 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 5x4 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 5x5 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 6x5 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 6x6 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 8x5 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 8x6 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 8x8 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 10x5 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 10x6 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 10x8 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 10x10 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 12x10 blocks, sRGB + XRC_SWAPCHAIN_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) + .Compressed() + .NotMutable() + .ToPair(), // 4-component ASTC, 12x12 blocks, sRGB + + // + // Depth/stencil + // + XRC_SWAPCHAIN_FORMAT(GL_DEPTH_COMPONENT16).WORKAROUND.Depth().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_DEPTH_COMPONENT24).WORKAROUND.Depth().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_DEPTH_COMPONENT32F).WORKAROUND.Depth().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_DEPTH_COMPONENT32F_NV).WORKAROUND.Depth().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_STENCIL_INDEX8).WORKAROUND.Stencil().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_DEPTH24_STENCIL8).WORKAROUND.DepthStencil().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_DEPTH32F_STENCIL8).WORKAROUND.DepthStencil().ToPair(), + XRC_SWAPCHAIN_FORMAT(GL_DEPTH32F_STENCIL8_NV).WORKAROUND.DepthStencil().ToPair(), + }; + return map; } -#define ADD_GL_DEPTH_FORMAT(X) ADD_GL_DEPTH_FORMAT2(X, #X) - - typedef std::map SwapchainTestMap; - SwapchainTestMap openGLESSwapchainTestMap{ - //{ {type}, { name, false (typeless), color, type, flags, flagV, arrayV, sampleV, mipV} }, - - // - // 8 bits per component - // - ADD_GL_COLOR_FORMAT(GL_R8), // 1-component, 8-bit unsigned normalized - ADD_GL_COLOR_FORMAT(GL_RG8), // 2-component, 8-bit unsigned normalized - ADD_GL_COLOR_FORMAT(GL_RGB8), // 3-component, 8-bit unsigned normalized - ADD_GL_COLOR_FORMAT(GL_RGBA8), // 4-component, 8-bit unsigned normalized - ADD_GL_COLOR_FORMAT(GL_R8_SNORM), // 1-component, 8-bit signed normalized - ADD_GL_COLOR_FORMAT(GL_RG8_SNORM), // 2-component, 8-bit signed normalized - ADD_GL_COLOR_FORMAT(GL_RGB8_SNORM), // 3-component, 8-bit signed normalized - ADD_GL_COLOR_FORMAT(GL_RGBA8_SNORM), // 4-component, 8-bit signed normalized - ADD_GL_COLOR_FORMAT(GL_R8UI), // 1-component, 8-bit unsigned integer - ADD_GL_COLOR_FORMAT(GL_RG8UI), // 2-component, 8-bit unsigned integer - ADD_GL_COLOR_FORMAT(GL_RGB8UI), // 3-component, 8-bit unsigned integer - ADD_GL_COLOR_FORMAT(GL_RGBA8UI), // 4-component, 8-bit unsigned integer - ADD_GL_COLOR_FORMAT(GL_R8I), // 1-component, 8-bit signed integer - ADD_GL_COLOR_FORMAT(GL_RG8I), // 2-component, 8-bit signed integer - ADD_GL_COLOR_FORMAT(GL_RGB8I), // 3-component, 8-bit signed integer - ADD_GL_COLOR_FORMAT(GL_RGBA8I), // 4-component, 8-bit signed integer - ADD_GL_COLOR_FORMAT(GL_SR8), // 1-component, 8-bit sRGB - ADD_GL_COLOR_FORMAT(GL_SRG8), // 2-component, 8-bit sRGB - ADD_GL_COLOR_FORMAT(GL_SRGB8), // 3-component, 8-bit sRGB - ADD_GL_COLOR_FORMAT(GL_SRGB8_ALPHA8), // 4-component, 8-bit sRGB - - // - // 16 bits per component - // - ADD_GL_COLOR_FORMAT(GL_R16), // 1-component, 16-bit unsigned normalized - ADD_GL_COLOR_FORMAT(GL_RG16), // 2-component, 16-bit unsigned normalized - ADD_GL_COLOR_FORMAT(GL_RGB16), // 3-component, 16-bit unsigned normalized - ADD_GL_COLOR_FORMAT(GL_RGBA16), // 4-component, 16-bit unsigned normalized - ADD_GL_COLOR_FORMAT(GL_R16_SNORM), // 1-component, 16-bit signed normalized - ADD_GL_COLOR_FORMAT(GL_RG16_SNORM), // 2-component, 16-bit signed normalized - ADD_GL_COLOR_FORMAT(GL_RGB16_SNORM), // 3-component, 16-bit signed normalized - ADD_GL_COLOR_FORMAT(GL_RGBA16_SNORM), // 4-component, 16-bit signed normalized - ADD_GL_COLOR_FORMAT(GL_R16UI), // 1-component, 16-bit unsigned integer - ADD_GL_COLOR_FORMAT(GL_RG16UI), // 2-component, 16-bit unsigned integer - ADD_GL_COLOR_FORMAT(GL_RGB16UI), // 3-component, 16-bit unsigned integer - ADD_GL_COLOR_FORMAT(GL_RGBA16UI), // 4-component, 16-bit unsigned integer - ADD_GL_COLOR_FORMAT(GL_R16I), // 1-component, 16-bit signed integer - ADD_GL_COLOR_FORMAT(GL_RG16I), // 2-component, 16-bit signed integer - ADD_GL_COLOR_FORMAT(GL_RGB16I), // 3-component, 16-bit signed integer - ADD_GL_COLOR_FORMAT(GL_RGBA16I), // 4-component, 16-bit signed integer - ADD_GL_COLOR_FORMAT(GL_R16F), // 1-component, 16-bit floating-point - ADD_GL_COLOR_FORMAT(GL_RG16F), // 2-component, 16-bit floating-point - ADD_GL_COLOR_FORMAT(GL_RGB16F), // 3-component, 16-bit floating-point - ADD_GL_COLOR_FORMAT(GL_RGBA16F), // 4-component, 16-bit floating-point - - // - // 32 bits per component - // - ADD_GL_COLOR_FORMAT(GL_R32UI), // 1-component, 32-bit unsigned integer - ADD_GL_COLOR_FORMAT(GL_RG32UI), // 2-component, 32-bit unsigned integer - ADD_GL_COLOR_FORMAT(GL_RGB32UI), // 3-component, 32-bit unsigned integer - ADD_GL_COLOR_FORMAT(GL_RGBA32UI), // 4-component, 32-bit unsigned integer - ADD_GL_COLOR_FORMAT(GL_R32I), // 1-component, 32-bit signed integer - ADD_GL_COLOR_FORMAT(GL_RG32I), // 2-component, 32-bit signed integer - ADD_GL_COLOR_FORMAT(GL_RGB32I), // 3-component, 32-bit signed integer - ADD_GL_COLOR_FORMAT(GL_RGBA32I), // 4-component, 32-bit signed integer - ADD_GL_COLOR_FORMAT(GL_R32F), // 1-component, 32-bit floating-point - ADD_GL_COLOR_FORMAT(GL_RG32F), // 2-component, 32-bit floating-point - ADD_GL_COLOR_FORMAT(GL_RGB32F), // 3-component, 32-bit floating-point - ADD_GL_COLOR_FORMAT(GL_RGBA32F), // 4-component, 32-bit floating-point - - // - // Packed - // - ADD_GL_COLOR_FORMAT(GL_RGB5), // 3-component 5:5:5, unsigned normalized - ADD_GL_COLOR_FORMAT(GL_RGB565), // 3-component 5:6:5, unsigned normalized - ADD_GL_COLOR_FORMAT(GL_RGB10), // 3-component 10:10:10, unsigned normalized - ADD_GL_COLOR_FORMAT(GL_RGBA4), // 4-component 4:4:4:4, unsigned normalized - ADD_GL_COLOR_FORMAT(GL_RGB5_A1), // 4-component 5:5:5:1, unsigned normalized - ADD_GL_COLOR_FORMAT(GL_RGB10_A2), // 4-component 10:10:10:2, unsigned normalized - ADD_GL_COLOR_FORMAT(GL_RGB10_A2UI), // 4-component 10:10:10:2, unsigned integer - ADD_GL_COLOR_FORMAT(GL_R11F_G11F_B10F), // 3-component 11:11:10, floating-point - ADD_GL_COLOR_FORMAT(GL_RGB9_E5), // 3-component/exp 9:9:9/5, floating-point - - // - // S3TC/DXT/BC - // - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGB_S3TC_DXT1_EXT), // line through 3D space, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT( - GL_COMPRESSED_RGBA_S3TC_DXT1_EXT), // line through 3D space plus 1-bit alpha, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT( - GL_COMPRESSED_RGBA_S3TC_DXT5_EXT), // line through 3D space plus line through 1D space, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT( - GL_COMPRESSED_RGBA_S3TC_DXT3_EXT), // line through 3D space plus 4-bit alpha, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT), // line through 3D space, 4x4 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT), // line through 3D space plus 1-bit alpha, 4x4 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT( - GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT), // line through 3D space plus line through 1D space, 4x4 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT), // line through 3D space plus 4-bit alpha, 4x4 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_LUMINANCE_LATC1_EXT), // line through 1D space, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT( - GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT), // two lines through 1D space, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT), // line through 1D space, 4x4 blocks, signed normalized - ADD_GL_COLOR_COMPRESSED_FORMAT( - GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT), // two lines through 1D space, 4x4 blocks, signed normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RED_RGTC1), // line through 1D space, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RG_RGTC2), // two lines through 1D space, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SIGNED_RED_RGTC1), // line through 1D space, 4x4 blocks, signed normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SIGNED_RG_RGTC2), // two lines through 1D space, 4x4 blocks, signed normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT), // 3-component, 4x4 blocks, unsigned floating-point - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT), // 3-component, 4x4 blocks, signed floating-point - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_BPTC_UNORM), // 4-component, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM), // 4-component, 4x4 blocks, sRGB - - // - // ETC - // - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_ETC1_RGB8_OES), // 3-component ETC1, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGB8_ETC2), // 3-component ETC2, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT( - GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2), // 4-component ETC2 with 1-bit alpha, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA8_ETC2_EAC), // 4-component ETC2, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ETC2), // 3-component ETC2, 4x4 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT( - GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2), // 4-component ETC2 with 1-bit alpha, 4x4 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC), // 4-component ETC2, 4x4 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_R11_EAC), // 1-component ETC, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RG11_EAC), // 2-component ETC, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SIGNED_R11_EAC), // 1-component ETC, 4x4 blocks, signed normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SIGNED_RG11_EAC), // 2-component ETC, 4x4 blocks, signed normalized - - // - // ASTC - // - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_4x4_KHR), // 4-component ASTC, 4x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_5x4_KHR), // 4-component ASTC, 5x4 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_5x5_KHR), // 4-component ASTC, 5x5 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_6x5_KHR), // 4-component ASTC, 6x5 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_6x6_KHR), // 4-component ASTC, 6x6 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_8x5_KHR), // 4-component ASTC, 8x5 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_8x6_KHR), // 4-component ASTC, 8x6 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_8x8_KHR), // 4-component ASTC, 8x8 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_10x5_KHR), // 4-component ASTC, 10x5 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_10x6_KHR), // 4-component ASTC, 10x6 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_10x8_KHR), // 4-component ASTC, 10x8 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_10x10_KHR), // 4-component ASTC, 10x10 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_12x10_KHR), // 4-component ASTC, 12x10 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_RGBA_ASTC_12x12_KHR), // 4-component ASTC, 12x12 blocks, unsigned normalized - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR), // 4-component ASTC, 4x4 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR), // 4-component ASTC, 5x4 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR), // 4-component ASTC, 5x5 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR), // 4-component ASTC, 6x5 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR), // 4-component ASTC, 6x6 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR), // 4-component ASTC, 8x5 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR), // 4-component ASTC, 8x6 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR), // 4-component ASTC, 8x8 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR), // 4-component ASTC, 10x5 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR), // 4-component ASTC, 10x6 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR), // 4-component ASTC, 10x8 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR), // 4-component ASTC, 10x10 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR), // 4-component ASTC, 12x10 blocks, sRGB - ADD_GL_COLOR_COMPRESSED_FORMAT(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR), // 4-component ASTC, 12x12 blocks, sRGB - - // - // Depth/stencil - // - ADD_GL_DEPTH_FORMAT(GL_DEPTH_COMPONENT16), ADD_GL_DEPTH_FORMAT(GL_DEPTH_COMPONENT24), ADD_GL_DEPTH_FORMAT(GL_DEPTH_COMPONENT32F), - ADD_GL_DEPTH_FORMAT(GL_DEPTH_COMPONENT32F_NV), ADD_GL_DEPTH_FORMAT(GL_STENCIL_INDEX8), ADD_GL_DEPTH_FORMAT(GL_DEPTH24_STENCIL8), - ADD_GL_DEPTH_FORMAT(GL_DEPTH32F_STENCIL8), ADD_GL_DEPTH_FORMAT(GL_DEPTH32F_STENCIL8_NV)}; -#undef ADD_GL_COLOR_FORMAT -#undef ADD_GL_COLOR_FORMAT2 -#undef ADD_GL_DEPTH_FORMAT -#undef ADD_GL_DEPTH_FORMAT2 // Returns a name for an image format. std::string OpenGLESGraphicsPlugin::GetImageFormatName(int64_t imageFormat) const { - SwapchainTestMap::const_iterator it = openGLESSwapchainTestMap.find(imageFormat); - - if (it != openGLESSwapchainTestMap.end()) { - return it->second.imageFormatName; - } - - return std::string("unknown"); + return ::Conformance::GetImageFormatName(GetSwapchainFormatData(), imageFormat); } bool OpenGLESGraphicsPlugin::IsImageFormatKnown(int64_t imageFormat) const { - SwapchainTestMap::const_iterator it = openGLESSwapchainTestMap.find(imageFormat); - - return (it != openGLESSwapchainTestMap.end()); + return ::Conformance::IsImageFormatKnown(GetSwapchainFormatData(), imageFormat); } // Retrieves SwapchainCreateTestParameters for the caller, handling plaform-specific functionality @@ -838,29 +943,7 @@ namespace Conformance // Swapchain image format support by the runtime is specified by the xrEnumerateSwapchainFormats function. // Runtimes should support R8G8B8A8 and R8G8B8A8 sRGB formats if possible. - SwapchainTestMap::iterator it = openGLESSwapchainTestMap.find(imageFormat); - - // Verify that the image format is known. If it's not known then this test needs to be - // updated to recognize new OpenGL formats. - CAPTURE(imageFormat); - CHECK_MSG(it != openGLESSwapchainTestMap.end(), "Unknown OpenGLES image format."); - if (it == openGLESSwapchainTestMap.end()) { - return false; - } - - CAPTURE(it->second.imageFormatName); - - // We may now proceed with creating swapchains with the format. - SwapchainCreateTestParameters& tp = it->second; - tp.arrayCountVector = {1, 2}; - if (!tp.compressedFormat) { - tp.mipCountVector = {1, 2}; - } - else { - tp.mipCountVector = {1}; - } - - *swapchainTestParameters = tp; + *swapchainTestParameters = ::Conformance::GetSwapchainCreateTestParameters(GetSwapchainFormatData(), imageFormat); return true; } @@ -926,7 +1009,18 @@ namespace Conformance int64_t OpenGLESGraphicsPlugin::SelectColorSwapchainFormat(const int64_t* imageFormatArray, size_t count) const { // List of supported color swapchain formats. - const std::array f{GL_RGBA8, GL_SRGB8_ALPHA8}; + // The order of this list does not effect the priority of selecting formats, the runtime list defines that. + const std::array f{ + GL_RGB10_A2, + GL_RGBA16, + GL_RGBA16F, + GL_RGBA32F, + + // The two below should only be used as a fallback, as they are linear color formats without enough bits for color + // depth, thus leading to banding. + GL_RGBA8, + GL_SRGB8_ALPHA8, + }; const int64_t* formatArrayEnd = imageFormatArray + count; auto it = std::find_first_of(imageFormatArray, formatArrayEnd, f.begin(), f.end()); @@ -942,7 +1036,12 @@ namespace Conformance int64_t OpenGLESGraphicsPlugin::SelectDepthSwapchainFormat(const int64_t* imageFormatArray, size_t count) const { // List of supported depth swapchain formats. - const std::array f{GL_DEPTH24_STENCIL8, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32F}; + const std::array f{ + GL_DEPTH24_STENCIL8, + GL_DEPTH_COMPONENT24, + GL_DEPTH_COMPONENT16, + GL_DEPTH_COMPONENT32F, + }; const int64_t* formatArrayEnd = imageFormatArray + count; auto it = std::find_first_of(imageFormatArray, formatArrayEnd, f.begin(), f.end()); diff --git a/src/conformance/framework/graphics_plugin_vulkan.cpp b/src/conformance/framework/graphics_plugin_vulkan.cpp index 92ca5ddc..4db260a5 100644 --- a/src/conformance/framework/graphics_plugin_vulkan.cpp +++ b/src/conformance/framework/graphics_plugin_vulkan.cpp @@ -14,17 +14,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "graphics_plugin.h" - #ifdef XR_USE_GRAPHICS_API_VULKAN #include "RGBAImage.h" #include "common/hex_and_handles.h" #include "common/xr_linear.h" +#include "graphics_plugin.h" #include "graphics_plugin_impl_helpers.h" #include "report.h" #include "swapchain_image_data.h" #include "utilities/Geometry.h" +#include "utilities/swapchain_format_data.h" #include "utilities/swapchain_parameters.h" #include "utilities/throw_helpers.h" #include "utilities/vulkan_utils.h" @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -175,12 +176,14 @@ namespace Conformance VulkanSwapchainImageData::Reset(); } - void BindRenderTarget(uint32_t index, uint32_t arraySlice, const VkRect2D& renderArea, VkRenderPassBeginInfo* renderPassBeginInfo) + void BindRenderTarget(uint32_t index, uint32_t arraySlice, const VkRect2D& renderArea, VkImageAspectFlags secondAttachmentAspect, + VkRenderPassBeginInfo* renderPassBeginInfo) { RenderTarget& rt = m_slices[arraySlice].m_renderTarget[index]; RenderPass& rp = m_slices[arraySlice].m_rp; if (rt.fb == VK_NULL_HANDLE) { - rt.Create(m_namer, m_vkDevice, GetTypedImage(index).image, GetDepthImageForColorIndex(index).image, arraySlice, m_size, rp); + rt.Create(m_namer, m_vkDevice, GetTypedImage(index).image, GetDepthImageForColorIndex(index).image, secondAttachmentAspect, + arraySlice, m_size, rp); } renderPassBeginInfo->renderPass = rp.pass; renderPassBeginInfo->framebuffer = rt.fb; @@ -206,6 +209,11 @@ namespace Conformance SwapchainImageDataBase::Reset(); } + int64_t GetDepthFormat() const + { + return m_depthFormat; + } + protected: const XrSwapchainImageVulkanKHR& GetFallbackDepthSwapchainImage(uint32_t i) override { @@ -285,6 +293,10 @@ namespace Conformance hWnd = nullptr; UnregisterClassW(L"conformance_test", hInst); } + if (hUser32Dll) { + ::FreeLibrary(hUser32Dll); + hUser32Dll = nullptr; + } #endif m_vkDevice = nullptr; @@ -299,6 +311,7 @@ namespace Conformance #if defined(VK_USE_PLATFORM_WIN32_KHR) HINSTANCE hInst{NULL}; HWND hWnd{NULL}; + HINSTANCE hUser32Dll{NULL}; #endif const VkExtent2D size{640, 480}; VkInstance m_vkInstance{VK_NULL_HANDLE}; @@ -328,8 +341,13 @@ namespace Conformance // adjust the window size and show at InitDevice time #if defined(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) - // Make sure we're 1:1 for HMD pixels - SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + typedef DPI_AWARENESS_CONTEXT(WINAPI * PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); + hUser32Dll = ::LoadLibraryA("user32.dll"); + if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = + reinterpret_cast(::GetProcAddress(hUser32Dll, "SetThreadDpiAwarenessContext"))) { + // Make sure we're 1:1 for HMD pixels + SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + } #endif RECT rect{0, 0, (LONG)size.width, (LONG)size.height}; AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, false); @@ -619,6 +637,9 @@ namespace Conformance void RenderView(const XrCompositionLayerProjectionView& layerView, const XrSwapchainImageBaseHeader* colorSwapchainImage, const RenderParams& params) override; + /// Get data on a known swapchain format + const SwapchainFormatData& FindFormatData(int64_t format) const; + #if defined(USE_CHECKPOINTS) void Checkpoint(std::string msg) { @@ -1348,288 +1369,182 @@ namespace Conformance return nullptr; } - // Shorthand constants for usage below. - static const uint64_t XRC_COLOR_TEXTURE_USAGE = (XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT); - - static const uint64_t XRC_COLOR_TEXTURE_USAGE_MUTABLE = (XRC_COLOR_TEXTURE_USAGE | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT); - - static const uint64_t XRC_COLOR_TEXTURE_USAGE_COMPRESSED = - (XR_SWAPCHAIN_USAGE_SAMPLED_BIT); // Compressed textures can't be rendered to, so no XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT. - - static const uint64_t XRC_DEPTH_TEXTURE_USAGE = (XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT); - -#define XRC_COLOR_CREATE_FLAGS \ - { \ - 0, XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT, XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT \ - } + static const SwapchainFormatDataMap& GetSwapchainFormatData() + { -#define XRC_DEPTH_CREATE_FLAGS \ - { \ - 0, XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT, XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT \ + // Add SwapchainCreateTestParameters for other Vulkan formats if they are supported by a runtime + static SwapchainFormatDataMap map{{ + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8B8A8_UNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8B8A8_SRGB).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_B8G8R8A8_UNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_B8G8R8A8_SRGB).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8B8_UNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8B8_SRGB).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_B8G8R8_UNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_B8G8R8_SRGB).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8_UNORM).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8_UNORM).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8_SNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8_SNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8B8_SNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8B8A8_SNORM).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8_UINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8_UINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8B8_UINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8B8A8_UINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8_SINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8_SINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8B8_SINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8_UNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8G8B8A8_SINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R8_SRGB).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16_UNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16_UNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16B16_UNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16B16A16_UNORM).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16_SNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16_SNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16B16_SNORM).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16B16A16_SNORM).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16_UINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16_UINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16B16_UINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16B16A16_UINT).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16_SINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16_SINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16B16_SINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16B16A16_SINT).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16_SFLOAT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16_SFLOAT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16B16_SFLOAT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16B16A16_SFLOAT).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R32_SINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R32G32_SINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R32G32B32_SINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R32G32B32A32_SINT).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R32_UINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R32G32_UINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R32G32B32_UINT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R32G32B32A32_UINT).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R32_SFLOAT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R32G32_SFLOAT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R32G32B32_SFLOAT).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R32G32B32A32_SFLOAT).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R5G5B5A1_UNORM_PACK16).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R5G6B5_UNORM_PACK16).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_A2B10G10R10_UNORM_PACK32).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R4G4B4A4_UNORM_PACK16).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_A1R5G5B5_UNORM_PACK16).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_A2R10G10B10_UNORM_PACK32).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_A2R10G10B10_UINT_PACK32).ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_A2B10G10R10_UNORM_PACK32).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_A2B10G10R10_UINT_PACK32).ToPair(), + // Runtimes with D3D11 back-ends map VK_FORMAT_B10G11R11_UFLOAT_PACK32 to DXGI_FORMAT_R11G11B10_FLOAT and that format doesn't have a TYPELESS equivalent. + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_B10G11R11_UFLOAT_PACK32).NotMutable().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_R16G16B16A16_SFLOAT).ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_D16_UNORM).Depth().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_D24_UNORM_S8_UINT).DepthStencil().ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_X8_D24_UNORM_PACK32).Depth().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_S8_UINT).Stencil().ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_D32_SFLOAT).Depth().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_D32_SFLOAT_S8_UINT).DepthStencil().ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK).Compressed().ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_EAC_R11_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_EAC_R11G11_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_EAC_R11_SNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_EAC_R11G11_SNORM_BLOCK).Compressed().ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_4x4_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_5x4_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_5x5_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_6x5_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_6x6_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_8x5_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_8x6_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_8x8_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_10x5_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_10x6_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_10x8_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_10x10_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_12x10_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_12x12_UNORM_BLOCK).Compressed().ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_4x4_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_5x4_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_5x5_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_6x5_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_6x6_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_8x5_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_8x6_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_8x8_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_10x5_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_10x6_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_10x8_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_10x10_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_12x10_SRGB_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_ASTC_12x12_SRGB_BLOCK).Compressed().ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_BC1_RGBA_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_BC1_RGBA_SRGB_BLOCK).Compressed().ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_BC2_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_BC2_SRGB_BLOCK).Compressed().ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_BC3_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_BC3_SRGB_BLOCK).Compressed().ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_BC6H_UFLOAT_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_BC6H_SFLOAT_BLOCK).Compressed().ToPair(), + + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_BC7_UNORM_BLOCK).Compressed().ToPair(), + XRC_SWAPCHAIN_FORMAT(VK_FORMAT_BC7_SRGB_BLOCK).Compressed().ToPair(), + }}; + return map; } -#define ADD_VK_COLOR_FORMAT2(X, Y) \ - { \ - {X}, \ - { \ - Y, IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, X, \ - {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ - } -#define ADD_VK_COLOR_FORMAT(X) ADD_VK_COLOR_FORMAT2(X, #X) - -#define ADD_VK_COLOR_IMMUTABLE_FORMAT2(X, Y) \ - { \ - {X}, \ - { \ - Y, IMMUTABLE, NO_MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, X, {XRC_COLOR_TEXTURE_USAGE}, XRC_COLOR_CREATE_FLAGS, \ - {}, {}, \ - { \ - } \ - } \ - } -#define ADD_VK_COLOR_IMMUTABLE_FORMAT(X) ADD_VK_COLOR_IMMUTABLE_FORMAT2(X, #X) - -#define ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT2(X, Y) \ - { \ - {X}, \ - { \ - Y, IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, X, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, \ - XRC_COLOR_CREATE_FLAGS, {}, {}, \ - { \ - } \ - } \ - } -#define ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(X) ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT2(X, #X) - -#define ADD_VK_DEPTH_FORMAT2(X, Y) \ - { \ - {X}, \ - { \ - Y, IMMUTABLE, MUT_SUPPORT, NON_COLOR, UNCOMPRESSED, RENDERING_SUPPORT, X, {XRC_DEPTH_TEXTURE_USAGE}, XRC_DEPTH_CREATE_FLAGS, \ - {}, {}, \ - { \ - } \ - } \ - } -#define ADD_VK_DEPTH_FORMAT(X) ADD_VK_DEPTH_FORMAT2(X, #X) - - // clang-format off - // Add SwapchainCreateTestParameters for other Vulkan formats if they are supported by a runtime - typedef std::map SwapchainTestMap; - SwapchainTestMap vkSwapchainTestMap{ - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8B8A8_UNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8B8A8_SRGB), - ADD_VK_COLOR_FORMAT(VK_FORMAT_B8G8R8A8_UNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_B8G8R8A8_SRGB), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8B8_UNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8B8_SRGB), - ADD_VK_COLOR_FORMAT(VK_FORMAT_B8G8R8_UNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_B8G8R8_SRGB), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8_UNORM), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8_UNORM), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8_SNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8_SNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8B8_SNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8B8A8_SNORM), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8_UINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8_UINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8B8_UINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8B8A8_UINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8_SINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8_SINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8B8_SINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8_UNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8G8B8A8_SINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R8_SRGB), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16_UNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16_UNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16B16_UNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16B16A16_UNORM), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16_SNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16_SNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16B16_SNORM), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16B16A16_SNORM), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16_UINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16_UINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16B16_UINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16B16A16_UINT), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16_SINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16_SINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16B16_SINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16B16A16_SINT), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16_SFLOAT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16_SFLOAT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16B16_SFLOAT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16B16A16_SFLOAT), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R32_SINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R32G32_SINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R32G32B32_SINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R32G32B32A32_SINT), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R32_UINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R32G32_UINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R32G32B32_UINT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R32G32B32A32_UINT), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R32_SFLOAT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R32G32_SFLOAT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R32G32B32_SFLOAT), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R32G32B32A32_SFLOAT), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R5G5B5A1_UNORM_PACK16), - ADD_VK_COLOR_FORMAT(VK_FORMAT_R5G6B5_UNORM_PACK16), - ADD_VK_COLOR_FORMAT(VK_FORMAT_A2B10G10R10_UNORM_PACK32), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R4G4B4A4_UNORM_PACK16), - ADD_VK_COLOR_FORMAT(VK_FORMAT_A1R5G5B5_UNORM_PACK16), - ADD_VK_COLOR_FORMAT(VK_FORMAT_A2R10G10B10_UNORM_PACK32), - ADD_VK_COLOR_FORMAT(VK_FORMAT_A2R10G10B10_UINT_PACK32), - ADD_VK_COLOR_FORMAT(VK_FORMAT_A2B10G10R10_UNORM_PACK32), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_A2B10G10R10_UINT_PACK32), - // Runtimes with D3D11 back-ends map VK_FORMAT_B10G11R11_UFLOAT_PACK32 to DXGI_FORMAT_R11G11B10_FLOAT and that format doesn't have a TYPELESS equivalent. - //ADD_VK_COLOR_FORMAT(VK_FORMAT_B10G11R11_UFLOAT_PACK32), - ADD_VK_COLOR_IMMUTABLE_FORMAT(VK_FORMAT_B10G11R11_UFLOAT_PACK32), - ADD_VK_COLOR_FORMAT(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32), - - ADD_VK_COLOR_FORMAT(VK_FORMAT_R16G16B16A16_SFLOAT), - - ADD_VK_DEPTH_FORMAT(VK_FORMAT_D16_UNORM), - ADD_VK_DEPTH_FORMAT(VK_FORMAT_D24_UNORM_S8_UINT), - - ADD_VK_DEPTH_FORMAT(VK_FORMAT_X8_D24_UNORM_PACK32), - ADD_VK_DEPTH_FORMAT(VK_FORMAT_S8_UINT), - - ADD_VK_DEPTH_FORMAT(VK_FORMAT_D32_SFLOAT), - ADD_VK_DEPTH_FORMAT(VK_FORMAT_D32_SFLOAT_S8_UINT), - - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK), - - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_EAC_R11_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_EAC_R11G11_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_EAC_R11_SNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_EAC_R11G11_SNORM_BLOCK), - - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_4x4_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_5x4_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_5x5_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_6x5_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_6x6_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_8x5_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_8x6_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_8x8_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_10x5_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_10x6_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_10x8_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_10x10_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_12x10_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_12x12_UNORM_BLOCK), - - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_4x4_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_5x4_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_5x5_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_6x5_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_6x6_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_8x5_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_8x6_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_8x8_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_10x5_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_10x6_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_10x8_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_10x10_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_12x10_SRGB_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_ASTC_12x12_SRGB_BLOCK), - - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_BC1_RGBA_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_BC1_RGBA_SRGB_BLOCK), - - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_BC2_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_BC2_SRGB_BLOCK), - - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_BC3_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_BC3_SRGB_BLOCK), - - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_BC6H_UFLOAT_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_BC6H_SFLOAT_BLOCK), - - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_BC7_UNORM_BLOCK), - ADD_VK_COLOR_COMPRESSED_UNRENDERABLE_FORMAT(VK_FORMAT_BC7_SRGB_BLOCK), - }; - // clang-format on - std::string VulkanGraphicsPlugin::GetImageFormatName(int64_t imageFormat) const { - SwapchainTestMap::const_iterator it = vkSwapchainTestMap.find(imageFormat); - - if (it != vkSwapchainTestMap.end()) { - return it->second.imageFormatName; - } - - return std::string("unknown"); + return ::Conformance::GetImageFormatName(GetSwapchainFormatData(), imageFormat); } bool VulkanGraphicsPlugin::IsImageFormatKnown(int64_t imageFormat) const { - SwapchainTestMap::const_iterator it = vkSwapchainTestMap.find(imageFormat); - - return (it != vkSwapchainTestMap.end()); + return ::Conformance::IsImageFormatKnown(GetSwapchainFormatData(), imageFormat); } bool VulkanGraphicsPlugin::GetSwapchainCreateTestParameters(XrInstance /*instance*/, XrSession /*session*/, XrSystemId /*systemId*/, int64_t imageFormat, SwapchainCreateTestParameters* swapchainTestParameters) { - // Swapchain image format support by the runtime is specified by the xrEnumerateSwapchainFormats function. - // Runtimes should support R8G8B8A8 and R8G8B8A8 sRGB formats if possible. - - SwapchainTestMap::iterator it = vkSwapchainTestMap.find(imageFormat); - - // Verify that the image format is known. If it's not known then this test needs to be - // updated to recognize new DXGI formats. - CAPTURE(imageFormat); - XRC_CHECK_THROW_MSG(it != vkSwapchainTestMap.end(), "Unknown Vulkan image format."); - if (it == vkSwapchainTestMap.end()) { - return false; - } - - // Verify that imageFormat is not a typeless type. Only regular types are allowed to - // be returned by the runtime for enumerated image formats. Note Vulkan doesn't really - // have a "typeless" format to worry about so this should never be hit. - CAPTURE(it->second.imageFormatName); - XRC_CHECK_THROW_MSG(!it->second.mutableFormat, "Typeless Vulkan image formats must not be enumerated by runtimes."); - if (it->second.mutableFormat) { - return false; - } - - // We may now proceed with creating swapchains with the format. - SwapchainCreateTestParameters& tp = it->second; - tp.arrayCountVector = {1, 2}; - if (tp.colorFormat && !tp.compressedFormat) { - tp.mipCountVector = {1, 2}; - } - else { - tp.mipCountVector = {1}; - } - - *swapchainTestParameters = tp; + *swapchainTestParameters = ::Conformance::GetSwapchainCreateTestParameters(GetSwapchainFormatData(), imageFormat); return true; } @@ -1692,10 +1607,10 @@ namespace Conformance const std::array f{VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; - const int64_t* formatArrayEnd = formatArray + count; - auto it = std::find_first_of(formatArray, formatArrayEnd, f.begin(), f.end()); + span formatArraySpan{formatArray, count}; + auto it = std::find_first_of(formatArraySpan.begin(), formatArraySpan.end(), f.begin(), f.end()); - if (it == formatArrayEnd) { + if (it == formatArraySpan.end()) { assert(false); // Assert instead of throw as we need to switch to the big table which can't fail. return formatArray[0]; } @@ -1710,10 +1625,10 @@ namespace Conformance const std::array f{VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM, VK_FORMAT_D32_SFLOAT_S8_UINT}; - const int64_t* formatArrayEnd = formatArray + count; - auto it = std::find_first_of(formatArray, formatArrayEnd, f.begin(), f.end()); + span formatArraySpan{formatArray, count}; + auto it = std::find_first_of(formatArraySpan.begin(), formatArraySpan.end(), f.begin(), f.end()); - if (it == formatArrayEnd) { + if (it == formatArraySpan.end()) { assert(false); // Assert instead of throw as we need to switch to the big table which can't fail. return formatArray[0]; } @@ -1892,6 +1807,45 @@ namespace Conformance vkCmdSetScissor(m_cmdBuffer.buf, 0, 1, &rect); } + /// Compute image layout for the "second image" format (depth and/or stencil) + static inline VkImageLayout ComputeLayout(const SwapchainFormatData& secondFormatData) + { + // can't use VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL / + // VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL + // because they're Vulkan 1.2 + if (secondFormatData.GetDepthFormat() || secondFormatData.GetStencilFormat()) { + return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + } + if (secondFormatData.GetColorFormat()) { + return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + } + throw std::runtime_error("No idea what layout to use for depth/stencil image"); + } + + /// Compute image aspect flags for the "second image" format (depth and/or stencil) + static inline VkImageAspectFlags ComputeAspectFlags(const SwapchainFormatData& secondFormatData) + { + VkImageAspectFlags secondAttachmentAspect = 0; + if (secondFormatData.GetDepthFormat()) { + secondAttachmentAspect |= VK_IMAGE_ASPECT_DEPTH_BIT; + } + if (secondFormatData.GetStencilFormat()) { + secondAttachmentAspect |= VK_IMAGE_ASPECT_STENCIL_BIT; + } + if (secondFormatData.GetColorFormat()) { + throw std::logic_error("this is just for the second image"); + } + return secondAttachmentAspect; + } + + const SwapchainFormatData& VulkanGraphicsPlugin::FindFormatData(int64_t format) const + { + auto& vkFormatMap = GetSwapchainFormatData(); + auto it = vkFormatMap.find(format); + assert(it != vkFormatMap.end()); + return it->second; + } + void VulkanGraphicsPlugin::ClearImageSlice(const XrSwapchainImageBaseHeader* colorSwapchainImage, uint32_t imageArrayIndex, XrColor4f bgColor) { @@ -1906,13 +1860,20 @@ namespace Conformance VkRect2D renderArea = {{0, 0}, {swapchainData->Width(), swapchainData->Height()}}; SetViewportAndScissor(renderArea); + // may be depth, stencil, or both + int64_t secondImageFormat = swapchainData->GetDepthFormat(); + const SwapchainFormatData& secondFormatData = FindFormatData(secondImageFormat); + + VkImageAspectFlags secondAttachmentAspect = ComputeAspectFlags(secondFormatData); + // Bind eye render target VkRenderPassBeginInfo renderPassBeginInfo{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO}; - swapchainData->BindRenderTarget(imageIndex, imageArrayIndex, renderArea, &renderPassBeginInfo); + swapchainData->BindRenderTarget(imageIndex, imageArrayIndex, renderArea, secondAttachmentAspect, &renderPassBeginInfo); if (!swapchainData->DepthSwapchainEnabled()) { - // Ensure depth is in the right layout - swapchainData->TransitionLayout(imageIndex, &m_cmdBuffer, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + // Ensure self-made fallback depth is in the right layout + VkImageLayout layout = ComputeLayout(secondFormatData); + swapchainData->TransitionLayout(imageIndex, &m_cmdBuffer, layout); } vkCmdBeginRenderPass(m_cmdBuffer.buf, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); @@ -1929,7 +1890,7 @@ namespace Conformance clearValues[1].depthStencil.stencil = 0; std::array clearAttachments{{ {VK_IMAGE_ASPECT_COLOR_BIT, 0, clearValues[0]}, - {VK_IMAGE_ASPECT_DEPTH_BIT, 0, clearValues[1]}, + {secondAttachmentAspect, 0, clearValues[1]}, }}; // imageArrayIndex already included in the VkImageView VkClearRect clearRect{renderArea, 0, 1}; @@ -1968,13 +1929,18 @@ namespace Conformance VkRect2D renderArea = {{r.offset.x, r.offset.y}, {uint32_t(r.extent.width), uint32_t(r.extent.height)}}; SetViewportAndScissor(renderArea); + // may be depth, stencil, or both + int64_t secondImageFormat = swapchainData->GetDepthFormat(); + const SwapchainFormatData& secondFormatData = FindFormatData(secondImageFormat); + VkImageAspectFlags secondAttachmentAspect = ComputeAspectFlags(secondFormatData); + // Just bind the eye render target, ClearImageSlice will have cleared it. VkRenderPassBeginInfo renderPassBeginInfo{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO}; // aka slice auto imageArrayIndex = layerView.subImage.imageArrayIndex; - swapchainData->BindRenderTarget(imageIndex, imageArrayIndex, renderArea, &renderPassBeginInfo); + swapchainData->BindRenderTarget(imageIndex, imageArrayIndex, renderArea, secondAttachmentAspect, &renderPassBeginInfo); vkCmdBeginRenderPass(m_cmdBuffer.buf, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); diff --git a/src/conformance/framework/two_call_struct_metadata.h b/src/conformance/framework/two_call_struct_metadata.h index 9d929ec2..f256ebf4 100644 --- a/src/conformance/framework/two_call_struct_metadata.h +++ b/src/conformance/framework/two_call_struct_metadata.h @@ -14,14 +14,38 @@ namespace Conformance static inline auto getTwoCallStructData(const XrVisibilityMaskKHR&) { - XrVisibilityMaskKHR visibilityMask{XR_TYPE_VISIBILITY_MASK_KHR}; - return TwoCallStruct(visibilityMask, - CapacityInputCountOutput(NAME_AND_MEMPTR(XrVisibilityMaskKHR::indexCapacityInput), - NAME_AND_MEMPTR(XrVisibilityMaskKHR::indexCountOutput)) - .Array(NAME_AND_MEMPTR(XrVisibilityMaskKHR::indices)), - CapacityInputCountOutput(NAME_AND_MEMPTR(XrVisibilityMaskKHR::vertexCapacityInput), - NAME_AND_MEMPTR(XrVisibilityMaskKHR::vertexCountOutput)) - .Array(NAME_AND_MEMPTR(XrVisibilityMaskKHR::vertices))); + static const XrVisibilityMaskKHR visibilityMask{XR_TYPE_VISIBILITY_MASK_KHR}; + static const auto data = TwoCallStruct(visibilityMask, + CapacityInputCountOutput(NAME_AND_MEMPTR(XrVisibilityMaskKHR::indexCapacityInput), + NAME_AND_MEMPTR(XrVisibilityMaskKHR::indexCountOutput)) + .Array(NAME_AND_MEMPTR(XrVisibilityMaskKHR::indices)), + CapacityInputCountOutput(NAME_AND_MEMPTR(XrVisibilityMaskKHR::vertexCapacityInput), + NAME_AND_MEMPTR(XrVisibilityMaskKHR::vertexCountOutput)) + .Array(NAME_AND_MEMPTR(XrVisibilityMaskKHR::vertices))); + return data; + } + + /// Get the two-call-struct metadata for XrControllerModelPropertiesMSFT + static inline auto getTwoCallStructData(const XrControllerModelPropertiesMSFT&) + { + static const XrControllerModelPropertiesMSFT modelProperties{XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT}; + static const auto data = TwoCallStruct( + modelProperties, + CapacityInputCountOutput(NAME_AND_MEMPTR(XrControllerModelPropertiesMSFT::nodeCapacityInput), + NAME_AND_MEMPTR(XrControllerModelPropertiesMSFT::nodeCountOutput)) + .Array(NAME_AND_MEMPTR(XrControllerModelPropertiesMSFT::nodeProperties), {XR_TYPE_CONTROLLER_MODEL_NODE_PROPERTIES_MSFT})); + return data; + } + + /// Get the two-call-struct metadata for XrControllerModelStateMSFT + static inline auto getTwoCallStructData(const XrControllerModelStateMSFT&) + { + static const XrControllerModelStateMSFT modelState{XR_TYPE_CONTROLLER_MODEL_STATE_MSFT}; + static const auto data = TwoCallStruct( + modelState, CapacityInputCountOutput(NAME_AND_MEMPTR(XrControllerModelStateMSFT::nodeCapacityInput), + NAME_AND_MEMPTR(XrControllerModelStateMSFT::nodeCountOutput)) + .Array(NAME_AND_MEMPTR(XrControllerModelStateMSFT::nodeStates), {XR_TYPE_CONTROLLER_MODEL_NODE_STATE_MSFT})); + return data; } #undef NAME_AND_MEMPTR diff --git a/src/conformance/platform_specific/android_resources/drawable/ic_launcher_foreground.xml b/src/conformance/platform_specific/android_resources/drawable/ic_launcher_foreground.xml index 69c547db..ea4d6e26 100644 --- a/src/conformance/platform_specific/android_resources/drawable/ic_launcher_foreground.xml +++ b/src/conformance/platform_specific/android_resources/drawable/ic_launcher_foreground.xml @@ -5,10 +5,10 @@ android:viewportHeight="108" android:tint="#FFFFFF"> diff --git a/src/conformance/platform_specific/android_resources/mipmap-anydpi-v26/ic_launcher_round.xml b/src/conformance/platform_specific/android_resources/mipmap-anydpi-v26/ic_launcher_round.xml index 1ecaaf59..d61597bd 100644 --- a/src/conformance/platform_specific/android_resources/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/src/conformance/platform_specific/android_resources/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,9 +1,9 @@ diff --git a/src/conformance/platform_specific/android_resources/values/colors.xml b/src/conformance/platform_specific/android_resources/values/colors.xml index a784fbec..c2497a05 100644 --- a/src/conformance/platform_specific/android_resources/values/colors.xml +++ b/src/conformance/platform_specific/android_resources/values/colors.xml @@ -1,6 +1,6 @@ diff --git a/src/conformance/utilities/CMakeLists.txt b/src/conformance/utilities/CMakeLists.txt index 9a86511f..99128825 100644 --- a/src/conformance/utilities/CMakeLists.txt +++ b/src/conformance/utilities/CMakeLists.txt @@ -10,6 +10,7 @@ add_library( event_reader.cpp Geometry.cpp stringification.cpp + swapchain_format_data.cpp types_and_constants.cpp utils.cpp) diff --git a/src/conformance/utilities/d3d_common.cpp b/src/conformance/utilities/d3d_common.cpp index ca878e4c..8a82a881 100644 --- a/src/conformance/utilities/d3d_common.cpp +++ b/src/conformance/utilities/d3d_common.cpp @@ -2,19 +2,18 @@ // // SPDX-License-Identifier: Apache-2.0 -#if (defined(XR_USE_GRAPHICS_API_D3D11) || defined(XR_USE_GRAPHICS_API_D3D12)) && !defined(MISSING_DIRECTX_COLORS) +#if defined(XR_USE_GRAPHICS_API_D3D11) || defined(XR_USE_GRAPHICS_API_D3D12) #include "d3d_common.h" -#include "swapchain_parameters.h" #include "common/xr_linear.h" +#include "swapchain_format_data.h" +#include "swapchain_parameters.h" #include "throw_helpers.h" #include // For Microsoft::WRL::ComPtr -#include -#include - +#include #include using namespace Microsoft::WRL; @@ -89,163 +88,145 @@ namespace Conformance } } - // Shorthand constants for usage below. - static const uint64_t XRC_COLOR_TEXTURE_USAGE = (XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT); - - static const uint64_t XRC_COLOR_TEXTURE_USAGE_MUTABLE = (XRC_COLOR_TEXTURE_USAGE | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT); - - static const uint64_t XRC_COLOR_TEXTURE_USAGE_COMPRESSED = - (XR_SWAPCHAIN_USAGE_SAMPLED_BIT); // Compressed textures can't be rendered to, so no XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT. - - static const uint64_t XRC_DEPTH_TEXTURE_USAGE = (XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT); - -#define XRC_COLOR_CREATE_FLAGS \ - { \ - 0, XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT, XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT \ - } - -#define XRC_DEPTH_CREATE_FLAGS \ - { \ - 0, XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT \ - } - SwapchainTestMap& GetDxgiSwapchainTestMap() { - // clang-format off static SwapchainTestMap dxgiSwapchainTestMap{ - {{DXGI_FORMAT_R32G32B32A32_TYPELESS}, {"DXGI_FORMAT_R32G32B32A32_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G32B32A32_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_R32G32B32A32_FLOAT}, {"DXGI_FORMAT_R32G32B32A32_FLOAT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G32B32A32_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R32G32B32A32_UINT}, {"DXGI_FORMAT_R32G32B32A32_UINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G32B32A32_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R32G32B32A32_SINT}, {"DXGI_FORMAT_R32G32B32A32_SINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G32B32A32_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_R32G32B32_TYPELESS}, {"DXGI_FORMAT_R32G32B32_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G32B32_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_R32G32B32_FLOAT}, {"DXGI_FORMAT_R32G32B32_FLOAT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G32B32_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R32G32B32_UINT}, {"DXGI_FORMAT_R32G32B32_UINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G32B32_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R32G32B32_SINT}, {"DXGI_FORMAT_R32G32B32_SINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G32B32_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_R16G16B16A16_TYPELESS}, {"DXGI_FORMAT_R16G16B16A16_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16G16B16A16_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_R16G16B16A16_FLOAT}, {"DXGI_FORMAT_R16G16B16A16_FLOAT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16G16B16A16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R16G16B16A16_UNORM}, {"DXGI_FORMAT_R16G16B16A16_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16G16B16A16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R16G16B16A16_UINT}, {"DXGI_FORMAT_R16G16B16A16_UINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16G16B16A16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R16G16B16A16_SNORM}, {"DXGI_FORMAT_R16G16B16A16_SNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16G16B16A16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R16G16B16A16_SINT}, {"DXGI_FORMAT_R16G16B16A16_SINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16G16B16A16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_R32G32_TYPELESS}, {"DXGI_FORMAT_R32G32_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G32_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_R32G32_FLOAT}, {"DXGI_FORMAT_R32G32_FLOAT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G32_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R32G32_UINT}, {"DXGI_FORMAT_R32G32_UINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G32_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R32G32_SINT}, {"DXGI_FORMAT_R32G32_SINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G32_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_R32G8X24_TYPELESS}, {"DXGI_FORMAT_R32G8X24_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G8X24_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_D32_FLOAT_S8X24_UINT}, {"DXGI_FORMAT_D32_FLOAT_S8X24_UINT", IMMUTABLE, MUT_SUPPORT, NON_COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32G8X24_TYPELESS, {XRC_DEPTH_TEXTURE_USAGE}, XRC_DEPTH_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS}, {"DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_X32_TYPELESS_G8X24_UINT}, {"DXGI_FORMAT_X32_TYPELESS_G8X24_UINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_R10G10B10A2_TYPELESS}, {"DXGI_FORMAT_R10G10B10A2_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R10G10B10A2_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_R10G10B10A2_UNORM}, {"DXGI_FORMAT_R10G10B10A2_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R10G10B10A2_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R10G10B10A2_UINT}, {"DXGI_FORMAT_R10G10B10A2_UINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R10G10B10A2_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - // This doesn't have a typeless equivalent, so it's created as-is by the runtime. - {{DXGI_FORMAT_R11G11B10_FLOAT}, {"DXGI_FORMAT_R11G11B10_FLOAT", IMMUTABLE, NO_MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R11G11B10_FLOAT, {XRC_COLOR_TEXTURE_USAGE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_R8G8B8A8_TYPELESS}, {"DXGI_FORMAT_R8G8B8A8_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8G8B8A8_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_R8G8B8A8_UNORM}, {"DXGI_FORMAT_R8G8B8A8_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8G8B8A8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R8G8B8A8_UNORM_SRGB}, {"DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8G8B8A8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R8G8B8A8_UINT}, {"DXGI_FORMAT_R8G8B8A8_UINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8G8B8A8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R8G8B8A8_SNORM}, {"DXGI_FORMAT_R8G8B8A8_SNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8G8B8A8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R8G8B8A8_SINT}, {"DXGI_FORMAT_R8G8B8A8_SINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8G8B8A8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_R16G16_TYPELESS}, {"DXGI_FORMAT_R16G16_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16G16_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_R16G16_FLOAT}, {"DXGI_FORMAT_R16G16_FLOAT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16G16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R16G16_UNORM}, {"DXGI_FORMAT_R16G16_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16G16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R16G16_UINT}, {"DXGI_FORMAT_R16G16_UINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16G16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R16G16_SNORM}, {"DXGI_FORMAT_R16G16_SNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16G16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R16G16_SINT}, {"DXGI_FORMAT_R16G16_SINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16G16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_R32_TYPELESS}, {"DXGI_FORMAT_R32_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_D32_FLOAT}, {"DXGI_FORMAT_D32_FLOAT", IMMUTABLE, MUT_SUPPORT, NON_COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32_TYPELESS, {XRC_DEPTH_TEXTURE_USAGE}, XRC_DEPTH_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R32_FLOAT}, {"DXGI_FORMAT_R32_FLOAT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R32_UINT}, {"DXGI_FORMAT_R32_UINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R32_SINT}, {"DXGI_FORMAT_R32_SINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R32_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_R24G8_TYPELESS}, {"DXGI_FORMAT_R24G8_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R24G8_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_D24_UNORM_S8_UINT}, {"DXGI_FORMAT_D24_UNORM_S8_UINT", IMMUTABLE, MUT_SUPPORT, NON_COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R24G8_TYPELESS, {XRC_DEPTH_TEXTURE_USAGE}, XRC_DEPTH_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R24_UNORM_X8_TYPELESS}, {"DXGI_FORMAT_R24_UNORM_X8_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R24G8_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_X24_TYPELESS_G8_UINT}, {"DXGI_FORMAT_X24_TYPELESS_G8_UINT", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R24G8_TYPELESS, {}, {}, {}, {}, {}}}, - - {{DXGI_FORMAT_R8G8_TYPELESS}, {"DXGI_FORMAT_R8G8_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8G8_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_R8G8_UNORM}, {"DXGI_FORMAT_R8G8_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8G8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R8G8_UINT}, {"DXGI_FORMAT_R8G8_UINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8G8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R8G8_SNORM}, {"DXGI_FORMAT_R8G8_SNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8G8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R8G8_SINT}, {"DXGI_FORMAT_R8G8_SINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8G8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_R16_TYPELESS}, {"DXGI_FORMAT_R16_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_R16_FLOAT}, {"DXGI_FORMAT_R16_FLOAT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_D16_UNORM}, {"DXGI_FORMAT_D16_UNORM", IMMUTABLE, MUT_SUPPORT, NON_COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16_TYPELESS, {XRC_DEPTH_TEXTURE_USAGE}, XRC_DEPTH_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R16_UNORM}, {"DXGI_FORMAT_R16_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R16_UINT}, {"DXGI_FORMAT_R16_UINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R16_SNORM}, {"DXGI_FORMAT_R16_SNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R16_SINT}, {"DXGI_FORMAT_R16_SINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R16_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_R8_TYPELESS}, {"DXGI_FORMAT_R8_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_R8_UNORM}, {"DXGI_FORMAT_R8_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R8_UINT}, {"DXGI_FORMAT_R8_UINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R8_SNORM}, {"DXGI_FORMAT_R8_SNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R8_SINT}, {"DXGI_FORMAT_R8_SINT", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_A8_UNORM}, {"DXGI_FORMAT_A8_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - // These don't have typeless equivalents, so they are created as-is by the runtime. - {{DXGI_FORMAT_R1_UNORM}, {"DXGI_FORMAT_R1_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R1_UNORM, {XRC_COLOR_TEXTURE_USAGE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R9G9B9E5_SHAREDEXP}, {"DXGI_FORMAT_R9G9B9E5_SHAREDEXP", IMMUTABLE, NO_MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, {XRC_COLOR_TEXTURE_USAGE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R8G8_B8G8_UNORM}, {"DXGI_FORMAT_R8G8_B8G8_UNORM", IMMUTABLE, NO_MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R8G8_B8G8_UNORM, {XRC_COLOR_TEXTURE_USAGE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_G8R8_G8B8_UNORM}, {"DXGI_FORMAT_G8R8_G8B8_UNORM", IMMUTABLE, NO_MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_G8R8_G8B8_UNORM, {XRC_COLOR_TEXTURE_USAGE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_BC1_TYPELESS}, {"DXGI_FORMAT_BC1_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC1_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_BC1_UNORM}, {"DXGI_FORMAT_BC1_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC1_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_BC1_UNORM_SRGB}, {"DXGI_FORMAT_BC1_UNORM_SRGB", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC1_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_BC2_TYPELESS}, {"DXGI_FORMAT_BC2_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC2_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_BC2_UNORM}, {"DXGI_FORMAT_BC2_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC2_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_BC2_UNORM_SRGB}, {"DXGI_FORMAT_BC2_UNORM_SRGB", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC2_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_BC3_TYPELESS}, {"DXGI_FORMAT_BC3_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC3_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_BC3_UNORM}, {"DXGI_FORMAT_BC3_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC3_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_BC3_UNORM_SRGB}, {"DXGI_FORMAT_BC3_UNORM_SRGB", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC3_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_BC4_TYPELESS}, {"DXGI_FORMAT_BC4_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC4_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_BC4_UNORM}, {"DXGI_FORMAT_BC4_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC4_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_BC4_SNORM}, {"DXGI_FORMAT_BC4_SNORM", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC4_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_BC5_TYPELESS}, {"DXGI_FORMAT_BC5_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC5_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_BC5_UNORM}, {"DXGI_FORMAT_BC5_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC5_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_BC5_SNORM}, {"DXGI_FORMAT_BC5_SNORM", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC5_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - // These don't have typeless equivalents, so they are created as-is by the runtime. - {{DXGI_FORMAT_B5G6R5_UNORM}, {"DXGI_FORMAT_B5G6R5_UNORM", IMMUTABLE, NO_MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_B5G6R5_UNORM, {XRC_COLOR_TEXTURE_USAGE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_B5G5R5A1_UNORM}, {"DXGI_FORMAT_B5G5R5A1_UNORM", IMMUTABLE, NO_MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_B5G5R5A1_UNORM, {XRC_COLOR_TEXTURE_USAGE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM}, {"DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM", IMMUTABLE, NO_MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, {XRC_COLOR_TEXTURE_USAGE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_B8G8R8A8_TYPELESS}, {"DXGI_FORMAT_B8G8R8A8_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_B8G8R8A8_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_B8G8R8A8_UNORM}, {"DXGI_FORMAT_B8G8R8A8_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_B8G8R8A8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_B8G8R8A8_UNORM_SRGB}, {"DXGI_FORMAT_B8G8R8A8_UNORM_SRGB", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_B8G8R8A8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_B8G8R8X8_TYPELESS}, {"DXGI_FORMAT_B8G8R8X8_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_B8G8R8X8_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_B8G8R8X8_UNORM}, {"DXGI_FORMAT_B8G8R8X8_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_B8G8R8X8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_B8G8R8X8_UNORM_SRGB}, {"DXGI_FORMAT_B8G8R8X8_UNORM_SRGB", IMMUTABLE, MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_B8G8R8X8_TYPELESS, {XRC_COLOR_TEXTURE_USAGE, XRC_COLOR_TEXTURE_USAGE_MUTABLE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_BC6H_TYPELESS}, {"DXGI_FORMAT_BC6H_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC6H_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_BC6H_UF16}, {"DXGI_FORMAT_BC6H_UF16", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC6H_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_BC6H_SF16}, {"DXGI_FORMAT_BC6H_SF16", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC6H_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - {{DXGI_FORMAT_BC7_TYPELESS}, {"DXGI_FORMAT_BC7_TYPELESS", MUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC7_TYPELESS, {}, {}, {}, {}, {}}}, - {{DXGI_FORMAT_BC7_UNORM}, {"DXGI_FORMAT_BC7_UNORM", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC7_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - {{DXGI_FORMAT_BC7_UNORM_SRGB}, {"DXGI_FORMAT_BC7_UNORM_SRGB", IMMUTABLE, MUT_SUPPORT, COLOR, COMPRESSED, NO_RENDERING_SUPPORT, DXGI_FORMAT_BC7_TYPELESS, {XRC_COLOR_TEXTURE_USAGE_COMPRESSED}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - // This doesn't have a typeless equivalent, so it's created as-is by the runtime. - {{DXGI_FORMAT_B4G4R4A4_UNORM}, {"DXGI_FORMAT_B4G4R4A4_UNORM", IMMUTABLE, NO_MUT_SUPPORT, COLOR, UNCOMPRESSED, RENDERING_SUPPORT, DXGI_FORMAT_B4G4R4A4_UNORM, {XRC_COLOR_TEXTURE_USAGE}, XRC_COLOR_CREATE_FLAGS, {}, {}, {}}}, - - }; - // clang-format on + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G32B32A32_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G32B32A32_FLOAT).ExpectedFormat(DXGI_FORMAT_R32G32B32A32_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G32B32A32_UINT).ExpectedFormat(DXGI_FORMAT_R32G32B32A32_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G32B32A32_SINT).ExpectedFormat(DXGI_FORMAT_R32G32B32A32_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G32B32_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G32B32_FLOAT).ExpectedFormat(DXGI_FORMAT_R32G32B32_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G32B32_UINT).ExpectedFormat(DXGI_FORMAT_R32G32B32_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G32B32_SINT).ExpectedFormat(DXGI_FORMAT_R32G32B32_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16G16B16A16_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16G16B16A16_FLOAT).ExpectedFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16G16B16A16_UINT).ExpectedFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16G16B16A16_SINT).ExpectedFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16G16B16A16_UNORM).ExpectedFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16G16B16A16_SNORM).ExpectedFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G32_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G32_FLOAT).ExpectedFormat(DXGI_FORMAT_R32G32_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G32_UINT).ExpectedFormat(DXGI_FORMAT_R32G32_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G32_SINT).ExpectedFormat(DXGI_FORMAT_R32G32_TYPELESS).Build(), + + // 32bit channel, 8bit channel, 24bit ignored. All typeless. + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32G8X24_TYPELESS).Typeless().Build(), + // 32bit float depth, 8 bit uint stencil, 24bit ignored. + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_D32_FLOAT_S8X24_UINT).ExpectedFormat(DXGI_FORMAT_R32G8X24_TYPELESS).DepthStencil().Build(), + // 32bit float red, 8bit ignored, 24bit ignored. Not typeless because used parts are typed? + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS).Typeless().Build(), + // typeless unused 32bit component, 8bit uint green, and 24bit unused. Not typeless because used parts are typed? + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT).ExpectedFormat(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R10G10B10A2_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R10G10B10A2_UNORM).ExpectedFormat(DXGI_FORMAT_R10G10B10A2_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R10G10B10A2_UINT).ExpectedFormat(DXGI_FORMAT_R10G10B10A2_TYPELESS).Build(), + + // This doesn't have a typeless equivalent, so it's created as-is by the runtime. + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R11G11B10_FLOAT).NotMutable().Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8G8B8A8_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8G8B8A8_UNORM).ExpectedFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB).ExpectedFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8G8B8A8_UINT).ExpectedFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8G8B8A8_SINT).ExpectedFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8G8B8A8_SNORM).ExpectedFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16G16_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16G16_FLOAT).ExpectedFormat(DXGI_FORMAT_R16G16_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16G16_UINT).ExpectedFormat(DXGI_FORMAT_R16G16_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16G16_SINT).ExpectedFormat(DXGI_FORMAT_R16G16_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16G16_UNORM).ExpectedFormat(DXGI_FORMAT_R16G16_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16G16_SNORM).ExpectedFormat(DXGI_FORMAT_R16G16_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32_FLOAT).ExpectedFormat(DXGI_FORMAT_R32_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_D32_FLOAT).ExpectedFormat(DXGI_FORMAT_R32_TYPELESS).Depth().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32_UINT).ExpectedFormat(DXGI_FORMAT_R32_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R32_SINT).ExpectedFormat(DXGI_FORMAT_R32_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R24G8_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_D24_UNORM_S8_UINT).ExpectedFormat(DXGI_FORMAT_R24G8_TYPELESS).Depth().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R24_UNORM_X8_TYPELESS).ExpectedFormat(DXGI_FORMAT_R24G8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_X24_TYPELESS_G8_UINT).ExpectedFormat(DXGI_FORMAT_R24G8_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8G8_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8G8_UINT).ExpectedFormat(DXGI_FORMAT_R8G8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8G8_SINT).ExpectedFormat(DXGI_FORMAT_R8G8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8G8_UNORM).ExpectedFormat(DXGI_FORMAT_R8G8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8G8_SNORM).ExpectedFormat(DXGI_FORMAT_R8G8_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16_FLOAT).ExpectedFormat(DXGI_FORMAT_R16_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_D16_UNORM).ExpectedFormat(DXGI_FORMAT_R16_TYPELESS).Depth().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16_UINT).ExpectedFormat(DXGI_FORMAT_R16_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16_SINT).ExpectedFormat(DXGI_FORMAT_R16_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16_UNORM).ExpectedFormat(DXGI_FORMAT_R16_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R16_SNORM).ExpectedFormat(DXGI_FORMAT_R16_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8_UINT).ExpectedFormat(DXGI_FORMAT_R8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8_SINT).ExpectedFormat(DXGI_FORMAT_R8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8_UNORM).ExpectedFormat(DXGI_FORMAT_R8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8_SNORM).ExpectedFormat(DXGI_FORMAT_R8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_A8_UNORM).ExpectedFormat(DXGI_FORMAT_R8_TYPELESS).Build(), + + // These don't have typeless equivalents, so they are created as-is by the runtime. + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R1_UNORM).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R9G9B9E5_SHAREDEXP).NotMutable().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R8G8_B8G8_UNORM).NotMutable().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_G8R8_G8B8_UNORM).NotMutable().Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC1_TYPELESS).Compressed().Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC1_UNORM).Compressed().ExpectedFormat(DXGI_FORMAT_BC1_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC1_UNORM_SRGB).Compressed().ExpectedFormat(DXGI_FORMAT_BC1_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC2_TYPELESS).Compressed().Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC2_UNORM).Compressed().ExpectedFormat(DXGI_FORMAT_BC2_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC2_UNORM_SRGB).Compressed().ExpectedFormat(DXGI_FORMAT_BC2_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC3_TYPELESS).Compressed().Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC3_UNORM).Compressed().ExpectedFormat(DXGI_FORMAT_BC3_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC3_UNORM_SRGB).Compressed().ExpectedFormat(DXGI_FORMAT_BC3_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC4_TYPELESS).Compressed().Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC4_UNORM).Compressed().ExpectedFormat(DXGI_FORMAT_BC4_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC4_SNORM).Compressed().ExpectedFormat(DXGI_FORMAT_BC4_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC5_TYPELESS).Compressed().Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC5_UNORM).Compressed().ExpectedFormat(DXGI_FORMAT_BC5_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC5_SNORM).Compressed().ExpectedFormat(DXGI_FORMAT_BC5_TYPELESS).Build(), + + // These don't have typeless equivalents, so they are created as-is by the runtime. + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_B5G6R5_UNORM).NotMutable().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_B5G5R5A1_UNORM).NotMutable().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM).NotMutable().Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_B8G8R8A8_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_B8G8R8A8_UNORM).ExpectedFormat(DXGI_FORMAT_B8G8R8A8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB).ExpectedFormat(DXGI_FORMAT_B8G8R8A8_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_B8G8R8X8_TYPELESS).Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_B8G8R8X8_UNORM).ExpectedFormat(DXGI_FORMAT_B8G8R8X8_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB).ExpectedFormat(DXGI_FORMAT_B8G8R8X8_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC6H_TYPELESS).Compressed().Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC6H_UF16).Compressed().ExpectedFormat(DXGI_FORMAT_BC6H_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC6H_SF16).Compressed().ExpectedFormat(DXGI_FORMAT_BC6H_TYPELESS).Build(), + + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC7_TYPELESS).Compressed().Typeless().Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC7_UNORM).Compressed().ExpectedFormat(DXGI_FORMAT_BC7_TYPELESS).Build(), + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_BC7_UNORM_SRGB).Compressed().ExpectedFormat(DXGI_FORMAT_BC7_TYPELESS).Build(), + + // This doesn't have a typeless equivalent, so it's created as-is by the runtime. + XRC_SWAPCHAIN_FORMAT(DXGI_FORMAT_B4G4R4A4_UNORM).NotMutable().Build(), + + }; return dxgiSwapchainTestMap; } @@ -263,35 +244,20 @@ namespace Conformance // (e.g. DXGI_FORMAT_R8G8B8A8_TYPELESS). Only concrete formats are returned, and only concrete // formats may be specified by applications for swapchain creation. - SwapchainTestMap& dxgiSwapchainTestMap = GetDxgiSwapchainTestMap(); - SwapchainTestMap::iterator it = dxgiSwapchainTestMap.find(imageFormat); + const SwapchainTestMap& dxgiSwapchainTestMap = GetDxgiSwapchainTestMap(); + SwapchainTestMap::const_iterator it = dxgiSwapchainTestMap.find(imageFormat); // Verify that the image format is known. If it's not known then this test needs to be // updated to recognize new DXGI formats. XRC_CHECK_THROW_MSG(it != dxgiSwapchainTestMap.end(), "Unknown DXGI image format."); - if (it == dxgiSwapchainTestMap.end()) { - return false; - } // Verify that imageFormat is not a typeless type. Only regular types are allowed to // be returned by the runtime for enumerated image formats. XRC_CHECK_THROW_MSG(!it->second.mutableFormat, "Typeless DXGI image formats must not be enumerated by runtimes: " + it->second.imageFormatName); - if (it->second.mutableFormat) { - return false; - } // We may now proceed with creating swapchains with the format. - SwapchainCreateTestParameters& tp = it->second; - tp.arrayCountVector = {1, 2}; - if (tp.colorFormat && !tp.compressedFormat) { - tp.mipCountVector = {1, 2}; - } - else { - tp.mipCountVector = {1}; - } - - *swapchainTestParameters = tp; + *swapchainTestParameters = it->second; return true; } diff --git a/src/conformance/utilities/d3d_common.h b/src/conformance/utilities/d3d_common.h index 29245aea..2fa3ccad 100644 --- a/src/conformance/utilities/d3d_common.h +++ b/src/conformance/utilities/d3d_common.h @@ -3,12 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 #pragma once -#if (defined(XR_USE_GRAPHICS_API_D3D11) || defined(XR_USE_GRAPHICS_API_D3D12)) && !defined(MISSING_DIRECTX_COLORS) +#if defined(XR_USE_GRAPHICS_API_D3D11) || defined(XR_USE_GRAPHICS_API_D3D12) #include #include "common/xr_linear.h" #include "swapchain_parameters.h" +#include +#include + #include #include #include diff --git a/src/conformance/utilities/swapchain_format_data.cpp b/src/conformance/utilities/swapchain_format_data.cpp new file mode 100644 index 00000000..83507f49 --- /dev/null +++ b/src/conformance/utilities/swapchain_format_data.cpp @@ -0,0 +1,329 @@ +// Copyright (c) 2019-2023, 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. + +#include "common/hex_and_handles.h" +#include "swapchain_parameters.h" +#include "swapchain_format_data.h" +#include "throw_helpers.h" + +#include +#include +#include +#include +#include +#include + +namespace Conformance +{ + + // the app might request any combination of flags + static constexpr auto XRC_COLOR_UA_COPY_SAMPLED_MUTABLE_USAGE_FLAGS = { + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | + XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | + XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | + XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | + XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | + XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | + XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | + XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | + XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | + XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | + XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | + XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | + XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | + XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | + XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | + XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | + XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + }; + static constexpr auto XRC_COLOR_COPY_SAMPLED_USAGE_FLAGS = { + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | + XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + }; + static constexpr auto XRC_COLOR_COPY_SAMPLED_MUTABLE_USAGE_FLAGS = { + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | + XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT | + XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | + XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | + XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | + XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + }; + static constexpr auto XRC_DEPTH_COPY_SAMPLED_USAGE_FLAGS = { + XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, + XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT, + XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, + XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT | + XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + }; + static constexpr auto XRC_COMPRESSED_SAMPLED_MUTABLE_USAGE_FLAGS = { + XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, + }; + static constexpr auto XRC_COMPRESSED_SAMPLED_USAGE_FLAGS = { + XR_SWAPCHAIN_USAGE_SAMPLED_BIT, + }; + + static constexpr std::array kArrayOf1{{1}}; + static constexpr std::array kArrayOf1And2{{1, 2}}; + static constexpr std::array kDefaultCreateFlags{ + {0, XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT, XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT, + XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT | XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT}}; + + SwapchainFormatData::SwapchainFormatData(int64_t format, const char* name) + : m_imageFormat(format) + , m_imageFormatName(name) + , m_expectedCreatedImageFormat(format) + , m_createFlagsVector(kDefaultCreateFlags.begin(), kDefaultCreateFlags.end()) + { + } + + SwapchainCreateTestParameters GetSwapchainCreateTestParameters(const SwapchainFormatDataMap& formatData, int64_t imageFormat) + { + SwapchainFormatDataMap::const_iterator it = formatData.find(imageFormat); + + // Verify that the image format is known. If it's not known then this test needs to be + // updated to recognize new formats. + if (it == formatData.end()) { + XRC_THROW("Unknown image format: " + std::to_string(imageFormat)); + } + + // Verify that imageFormat is not a typeless type. Only regular types are allowed to + // be returned by the runtime for enumerated image formats. + if (it->second.IsTypeless()) { + XRC_THROW("Typeless image formats must not be enumerated by runtimes: " + std::string{it->second.GetImageFormatName()}); + } + + // We may now proceed with creating swapchains with the format. + return it->second.ToTestParameters(); + } + + const char* GetImageFormatName(const SwapchainFormatDataMap& formatData, int64_t imageFormat) + { + SwapchainFormatDataMap::const_iterator it = formatData.find(imageFormat); + + if (it != formatData.end()) { + return it->second.GetImageFormatName(); + } + + return "unknown"; + } + + bool IsImageFormatKnown(const SwapchainFormatDataMap& formatData, int64_t imageFormat) + { + SwapchainFormatDataMap::const_iterator it = formatData.find(imageFormat); + + return it != formatData.end(); + } + + SwapchainCreateTestParametersBuilder::SwapchainCreateTestParametersBuilder(int64_t imageFormat, const char* imageFormatName) + : m_data(imageFormat, imageFormatName) + { + UpdateDefaultUsageFlagVector(); + } + + std::pair SwapchainCreateTestParametersBuilder::Build() const + { + return m_data.Build(); + } + + std::pair SwapchainCreateTestParametersBuilder::ToPair() const + { + return m_data.ToPair(); + } + + std::string SwapchainCreateTestParametersBuilder::ToString() const + { + return m_data.ToString(); + } + + void SwapchainCreateTestParametersBuilder::UpdateDefaultUsageFlagVector() + { + if (m_data.m_isTypeless) { + m_data.m_usageFlagsVector = {}; + } + else if (m_data.m_compressedFormat) { + + if (m_data.m_supportsMutableFormat) { + // compressed, mutable + m_data.m_usageFlagsVector = XRC_COMPRESSED_SAMPLED_MUTABLE_USAGE_FLAGS; + } + else { + // compressed, not mutable + m_data.m_usageFlagsVector = XRC_COMPRESSED_SAMPLED_USAGE_FLAGS; + } + } + else { // not compressed + if (m_data.m_colorFormat) { + if (m_data.m_supportsMutableFormat) { + // not compressed, color, mutable + m_data.m_usageFlagsVector = + m_data.m_allowUA ? XRC_COLOR_UA_COPY_SAMPLED_MUTABLE_USAGE_FLAGS : XRC_COLOR_COPY_SAMPLED_MUTABLE_USAGE_FLAGS; + } + else { + + // not compressed, color, not mutable + m_data.m_usageFlagsVector = XRC_COLOR_COPY_SAMPLED_USAGE_FLAGS; + } + } + else { + + // not compressed, depth/stencil + m_data.m_usageFlagsVector = XRC_DEPTH_COPY_SAMPLED_USAGE_FLAGS; + } + } + } + + SwapchainCreateTestParameters SwapchainFormatData::ToTestParameters() const + { + + span mipCountVector{kArrayOf1.begin(), kArrayOf1.end()}; + if (m_colorFormat && !m_compressedFormat) { + mipCountVector = {kArrayOf1And2.begin(), kArrayOf1And2.end()}; + } + + span arrayCountVector{kArrayOf1And2.begin(), kArrayOf1And2.end()}; + return SwapchainCreateTestParameters{ + std::string{m_imageFormatName}, // + m_isTypeless ? SwapchainFormatMutability::MUTABLE : SwapchainFormatMutability::IMMUTABLE, // + m_supportsMutableFormat ? SwapchainFormatSupportsMutability::MUT_SUPPORT + : SwapchainFormatSupportsMutability::NO_MUT_SUPPORT, // + m_colorFormat ? SwapchainFormatIsColor::COLOR : SwapchainFormatIsColor::NON_COLOR, + m_compressedFormat ? SwapchainFormatIsCompressed::COMPRESSED : SwapchainFormatIsCompressed::UNCOMPRESSED, + m_compressedFormat ? SwapchainFormatSupportsRendering::NO_RENDERING_SUPPORT + : SwapchainFormatSupportsRendering::RENDERING_SUPPORT, + m_expectedCreatedImageFormat, + {m_usageFlagsVector.begin(), m_usageFlagsVector.end()}, + {m_createFlagsVector.begin(), m_createFlagsVector.end()}, + {arrayCountVector.begin(), arrayCountVector.end()}, + {/* sampleCountVector - unused */}, + {mipCountVector.begin(), mipCountVector.end()}, + m_depthFormat, + m_stencilFormat, + }; + } + + std::pair SwapchainFormatData::Build() const + { + + return std::make_pair(m_imageFormat, ToTestParameters()); + } + + std::pair SwapchainFormatData::ToPair() const + { + + return {m_imageFormat, *this}; + } + + std::string SwapchainFormatData::ToString() const + { + + std::ostringstream oss; + oss << m_imageFormatName << " (" << to_hex(m_imageFormat) << "):"; + if (m_compressedFormat) { + oss << " compressed"; + } + + // what kind of thing: color, depth, stencil + if (m_colorFormat) { + oss << " color"; + } + else if (m_depthFormat && m_stencilFormat) { + oss << " depth/stencil"; + } + else if (m_depthFormat) { + oss << " depth"; + } + else if (m_stencilFormat) { + oss << " stencil"; + } + + if (m_isTypeless) { + oss << " typeless"; + } + + oss << " texture format"; + + if (!m_supportsMutableFormat) { + oss << " (no mutable format support)"; + } + if (!m_allowUA) { + oss << " (no UA support)"; + } + if (m_expectedCreatedImageFormat != m_imageFormat) { + oss << " (expected to be created as " << to_hex(m_expectedCreatedImageFormat) << ")"; + } + return oss.str(); + } + +} // namespace Conformance diff --git a/src/conformance/utilities/swapchain_format_data.h b/src/conformance/utilities/swapchain_format_data.h new file mode 100644 index 00000000..2a2baf28 --- /dev/null +++ b/src/conformance/utilities/swapchain_format_data.h @@ -0,0 +1,308 @@ +// Copyright (c) 2019-2023, 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. + +#pragma once + +#include +#include +#include "swapchain_parameters.h" +#include "utils.h" + +#include +#include +#include +#include +#include + +namespace Conformance +{ + using nonstd::span; + + /// Minimal data structure storing details about a swapchain image format. + /// + /// May eventually replace @ref SwapchainImageTestParam + class SwapchainFormatData + { + public: + /// The graphics-API-specific numeric value of the image format + int64_t GetImageFormat() const + { + return m_imageFormat; + } + + /// String-ified version of the C identifier. + const char* GetImageFormatName() const + { + return m_imageFormatName; + } + + /// The graphics-API-specific created image format returned by `xrCreateSwapchain`, may be different from @ref GetImageFormat() + int64_t GetExpectedCreatedImageFormat() const + { + return m_expectedCreatedImageFormat; + } + + /// Whether "unordered access" usage flag is allowed + bool SupportsUnorderedAccess() const + { + return m_allowUA; + } + + /// Whether the image format is a mutable (a.k.a. typeless) type. + bool IsTypeless() const + { + return m_isTypeless; + } + + /// Whether the image format supports creation with XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT. + bool SupportsMutableFormatBit() const + { + return m_supportsMutableFormat; + } + + /// Whether the format is a color-specific format + bool GetColorFormat() const + { + return m_colorFormat; + } + + /// Whether the format can be use as a depth buffer: implies not color + bool GetDepthFormat() const + { + return m_depthFormat; + } + + /// Whether the format can be use as a stencil buffer: implies not color + bool GetStencilFormat() const + { + return m_stencilFormat; + } + + /// Whether the format is a compressed format (and thus cannot be rendered to) + bool GetCompressedFormat() const + { + return m_compressedFormat; + } + + /// XrSwapchainUsageFlags to exercise for this format. + /// Defaults to all combinations, including 0, of the core flags. + span GetUsageFlagsTestValues() const + { + return m_usageFlagsVector; + } + + /// XrSwapchainCreateFlags + span GetCreateFlagsTestValues() const + { + return m_createFlagsVector; + } + + /// Convert to a @ref SwapchainCreateTestParameters instance + SwapchainCreateTestParameters ToTestParameters() const; + + /// Convert to a pair of the numeric format and @ref SwapchainCreateTestParameters instance + std::pair Build() const; + + /// Return pair of the numeric format and and ourself. + std::pair ToPair() const; + + /// Describe this entry + std::string ToString() const; + + private: + friend class SwapchainCreateTestParametersBuilder; + SwapchainFormatData(int64_t format, const char* name); + + /// The graphics-API-specific numeric value of the image format + int64_t m_imageFormat; + + /// String-ified version of the C identifier. + const char* m_imageFormatName; + + /// The graphics-API-specific created image format returned by `xrCreateSwapchain`, may be different from @ref m_imageFormat in some cases. + int64_t m_expectedCreatedImageFormat; + + /// Whether "unordered access" usage flag is allowed + bool m_allowUA = true; + + /// Whether the image format is a mutable (a.k.a. typeless) type. + bool m_isTypeless = false; + + /// Whether the image format supports creation with XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT. + bool m_supportsMutableFormat = true; + + /// Whether the format is a color-specific format + bool m_colorFormat = true; + + /// Whether the format can be use as a depth buffer: implies not color + bool m_depthFormat = false; + + /// Whether the format can be use as a stencil buffer: implies not color + bool m_stencilFormat = false; + + /// Whether the format is a compressed format (and thus cannot be rendered to) + bool m_compressedFormat = false; + + /// XrSwapchainUsageFlags to exercise for this format. + /// Defaults to all combinations, including 0, of the core flags. + /// @todo Stop making so many copies of this, generate it from the other data instead + span m_usageFlagsVector; + + /// XrSwapchainCreateFlags + /// @todo Stop making so many copies of this, generate it from the other data instead + span m_createFlagsVector; + }; + + /// A map of swapchain format (numeric value) to @ref SwapchainFormatData + using SwapchainFormatDataMap = std::map; + + /// Look up the swapchain create test parameters in an map (API-specific). + /// + /// Throws if the format cannot be found. + SwapchainCreateTestParameters GetSwapchainCreateTestParameters(const SwapchainFormatDataMap& formatData, int64_t imageFormat); + + /// Returns a name for an image format. Returns "unknown" for unknown formats. + const char* GetImageFormatName(const SwapchainFormatDataMap& formatData, int64_t imageFormat); + + /// Returns true if the format is known to the plugin. Can be false if the runtime supports extra formats unknown to the conformance tests + /// (e.g. in APIs which have optional extensions). + bool IsImageFormatKnown(const SwapchainFormatDataMap& formatData, int64_t imageFormat); + + class SwapchainCreateTestParametersBuilder + { + public: + SwapchainCreateTestParametersBuilder(int64_t imageFormat, const char* imageFormatName); + + using Self = SwapchainCreateTestParametersBuilder; + + /// Mark this as not supporting "unordered access" + Self& NoUnorderedAccess() + { + m_data.m_allowUA = false; + UpdateDefaultUsageFlagVector(); + return *this; + } + + /// Mark this as being a "typeless" format (just channels of widths, no implied interpretation) + /// + /// Also sets some default usage flags. + Self& Typeless() + { + m_data.m_isTypeless = true; + /// @todo is this actually right? It's what the old d3d code did. + m_data.m_createFlagsVector = {}; + UpdateDefaultUsageFlagVector(); + return *this; + } + + /// Mark this as supporting depth buffer usage (and un-marking for color buffer usage) + /// + /// Also sets some default usage flags. + Self& Depth() + { + m_data.m_depthFormat = true; + NotColor(); + return *this; + } + + /// Mark this as supporting stencil buffer usage (and un-marking for color buffer usage) + /// + /// Also sets some default usage flags. + Self& Stencil() + { + m_data.m_stencilFormat = true; + NotColor(); + return *this; + } + + /// Mark this as supporting depth and stencil buffer usage (and un-marking for color buffer usage) + /// + /// Also sets some default usage flags. + /// + /// Equivalent to calling both @ref Depth() and @ref Stencil() + Self& DepthStencil() + { + m_data.m_stencilFormat = true; + m_data.m_depthFormat = true; + NotColor(); + return *this; + } + + /// Record that we expect the runtime to allocate this as the specified different format (normally a typeless version if one exists) + Self& ExpectedFormat(int64_t format) + { + assert(format == m_data.m_expectedCreatedImageFormat || !m_data.m_isTypeless); + m_data.m_expectedCreatedImageFormat = format; + return *this; + } + + /// Mark this as a format for which we should not test the `XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT` + Self& NotMutable() + { + assert(!m_data.m_isTypeless); + m_data.m_supportsMutableFormat = false; + UpdateDefaultUsageFlagVector(); + return *this; + } + + /// Mark this as a compressed format that we should not test rendering to + Self& Compressed() + { + m_data.m_compressedFormat = true; + UpdateDefaultUsageFlagVector(); + return *this; + } + + /// Populate the usage flags combinations to test. + /// + /// @note Call this method *after* any other builder methods other than @ref Build, since many of them update the usage flags + Self& UsageFlags(span usageFlagCombinationsToTest) + { + m_data.m_usageFlagsVector = usageFlagCombinationsToTest; + return *this; + } + + /// Populate the create flags combinations to test + Self& CreateFlags(span createFlagCombinationsToTest) + { + m_data.m_createFlagsVector = createFlagCombinationsToTest; + return *this; + } + + /// Convert to a pair of the numeric format and @ref SwapchainCreateTestParameters instance + std::pair Build() const; + + /// Return pair of the numeric format and and ourself. + std::pair ToPair() const; + + /// Describe this entry + std::string ToString() const; + + private: + void NotColor() + { + m_data.m_colorFormat = false; + UpdateDefaultUsageFlagVector(); + } + + void UpdateDefaultUsageFlagVector(); + SwapchainFormatData m_data; + }; + +/// Wraps constructor of @ref SwapchainCreateTestParametersBuilder to stringify format name +#define XRC_SWAPCHAIN_FORMAT(FORMAT) (::Conformance::SwapchainCreateTestParametersBuilder(FORMAT, #FORMAT)) + +} // namespace Conformance diff --git a/src/conformance/utilities/swapchain_parameters.h b/src/conformance/utilities/swapchain_parameters.h index 5b2a83d4..72390906 100644 --- a/src/conformance/utilities/swapchain_parameters.h +++ b/src/conformance/utilities/swapchain_parameters.h @@ -89,6 +89,12 @@ namespace Conformance /// Used only by color buffers. std::vector mipCountVector; + + /// Is this format usable as a depth buffer? + bool useAsDepth = false; + + /// Is this format usable as a stencil buffer? + bool useAsStencil = false; }; } // namespace Conformance diff --git a/src/conformance/utilities/vulkan_utils.h b/src/conformance/utilities/vulkan_utils.h index 99933130..2a4acceb 100644 --- a/src/conformance/utilities/vulkan_utils.h +++ b/src/conformance/utilities/vulkan_utils.h @@ -753,13 +753,13 @@ namespace Conformance swap(m_vkDevice, other.m_vkDevice); return *this; } - void Create(const VulkanDebugObjectNamer& namer, VkDevice device, VkImage aColorImage, VkImage aDepthImage, uint32_t baseArrayLayer, - VkExtent2D size, RenderPass& renderPass) + void Create(const VulkanDebugObjectNamer& namer, VkDevice device, VkImage aColorImage, VkImage aDepthOrStencilImage, + VkImageAspectFlags depthOrStencilImageAspect, uint32_t baseArrayLayer, VkExtent2D size, RenderPass& renderPass) { m_vkDevice = device; colorImage = aColorImage; - depthImage = aDepthImage; + depthImage = aDepthOrStencilImage; std::array attachments{}; uint32_t attachmentCount = 0; @@ -794,13 +794,25 @@ namespace Conformance depthViewInfo.components.g = VK_COMPONENT_SWIZZLE_G; depthViewInfo.components.b = VK_COMPONENT_SWIZZLE_B; depthViewInfo.components.a = VK_COMPONENT_SWIZZLE_A; - depthViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + depthViewInfo.subresourceRange.aspectMask = depthOrStencilImageAspect; depthViewInfo.subresourceRange.baseMipLevel = 0; depthViewInfo.subresourceRange.levelCount = 1; depthViewInfo.subresourceRange.baseArrayLayer = baseArrayLayer; depthViewInfo.subresourceRange.layerCount = 1; XRC_CHECK_THROW_VKCMD(vkCreateImageView(m_vkDevice, &depthViewInfo, nullptr, &depthView)); - XRC_CHECK_THROW_VKCMD(namer.SetName(VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)depthView, "CTS depth image view")); + + const bool isDepth = depthOrStencilImageAspect & VK_IMAGE_ASPECT_DEPTH_BIT; + const bool isStencil = depthOrStencilImageAspect & VK_IMAGE_ASPECT_STENCIL_BIT; + if (isDepth && isStencil) { + XRC_CHECK_THROW_VKCMD(namer.SetName(VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)depthView, "CTS depth/stencil image view")); + } + else if (isDepth) { + XRC_CHECK_THROW_VKCMD(namer.SetName(VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)depthView, "CTS depth image view")); + } + else if (isStencil) { + XRC_CHECK_THROW_VKCMD(namer.SetName(VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)depthView, "CTS stencil image view")); + } + attachments[attachmentCount++] = depthView; } diff --git a/src/loader/.gitignore b/src/loader/.gitignore index 5e8e0ba3..be1be1af 100644 --- a/src/loader/.gitignore +++ b/src/loader/.gitignore @@ -1,4 +1,4 @@ -# Copyright (c) 2020 The Khronos Group Inc. +# Copyright (c) 2020-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 diff --git a/src/loader/AndroidManifest.xml b/src/loader/AndroidManifest.xml index 2817b34a..0c151c63 100644 --- a/src/loader/AndroidManifest.xml +++ b/src/loader/AndroidManifest.xml @@ -2,7 +2,7 @@ package="org.khronos.openxr.openxr_loader_for_android"> diff --git a/src/loader/AndroidManifest.xml.in b/src/loader/AndroidManifest.xml.in index 9bd8a460..291a1e2d 100644 --- a/src/loader/AndroidManifest.xml.in +++ b/src/loader/AndroidManifest.xml.in @@ -4,7 +4,7 @@ android:versionName="${OPENXR_FULL_VERSION}${OPENXR_ANDROID_VERSION_SUFFIX}"> diff --git a/src/loader/CMakeLists.txt b/src/loader/CMakeLists.txt index 22047fbc..a98d3808 100644 --- a/src/loader/CMakeLists.txt +++ b/src/loader/CMakeLists.txt @@ -31,8 +31,8 @@ include(GNUInstallDirs) # List of all files externally generated outside of the loader that the loader # needs to build with. -set(LOADER_EXTERNAL_GEN_FILES ${COMMON_GENERATED_OUTPUT}) -set(LOADER_EXTERNAL_GEN_DEPENDS ${COMMON_GENERATED_DEPENDS}) +set(LOADER_EXTERNAL_GEN_FILES ${LOADER_GENERATED_OUTPUT}) +set(LOADER_EXTERNAL_GEN_DEPENDS ${LOADER_GENERATED_DEPENDS}) run_xr_xml_generate(loader_source_generator.py xr_generated_loader.hpp) run_xr_xml_generate(loader_source_generator.py xr_generated_loader.cpp) diff --git a/src/loader/abi.json.license b/src/loader/abi.json.license index ae931a24..924b9735 100644 --- a/src/loader/abi.json.license +++ b/src/loader/abi.json.license @@ -1,2 +1,3 @@ -Copyright (c) 2020 The Khronos Group Inc. -SPDX-License-Identifier: Apache-2.0 +Copyright (c) 2020-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 8f36b13b..fd646580 100644 --- a/src/loader/loader.rc +++ b/src/loader/loader.rc @@ -8,10 +8,17 @@ // Initial Author: Mark Young // +// The years here should always match the Khronos line above! +#define COPYRIGHT_NOTICE "2017-2023, The Khronos Group Inc. and others" + +// REUSE-IgnoreStart + /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Start customize section // Edit this section for your build +// The normal OpenXR CMake build will define the XR_CURRENT_API_*_VERSION +// symbols automatically so no manual changes are needed in that case. /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -63,7 +70,7 @@ BEGIN BEGIN VALUE "FileDescription", "OpenXR Loader" VALUE "FileVersion", VER_FILE_VERSION_STR - VALUE "LegalCopyright", "Copyright (C) 2015-2020" + VALUE "LegalCopyright", "Copyright (C) " COPYRIGHT_NOTICE VALUE "ProductName", "OpenXR Loader" VALUE "ProductVersion", VER_FILE_VERSION_STR END diff --git a/src/loader/loader_core.cpp b/src/loader/loader_core.cpp index 98d3fa97..06e68700 100644 --- a/src/loader/loader_core.cpp +++ b/src/loader/loader_core.cpp @@ -19,7 +19,7 @@ #include "loader_logger.hpp" #include "loader_platform.hpp" #include "runtime_interface.hpp" -#include "xr_generated_dispatch_table.h" +#include "xr_generated_dispatch_table_core.h" #include "xr_generated_loader.hpp" #include diff --git a/src/loader/loader_instance.cpp b/src/loader/loader_instance.cpp index badd3919..ce5c2055 100644 --- a/src/loader/loader_instance.cpp +++ b/src/loader/loader_instance.cpp @@ -18,7 +18,7 @@ #include "loader_interfaces.h" #include "loader_logger.hpp" #include "runtime_interface.hpp" -#include "xr_generated_dispatch_table.h" +#include "xr_generated_dispatch_table_core.h" #include "xr_generated_loader.hpp" #include diff --git a/src/loader/manifest_file.cpp b/src/loader/manifest_file.cpp index 99f4e841..0683bc16 100644 --- a/src/loader/manifest_file.cpp +++ b/src/loader/manifest_file.cpp @@ -274,16 +274,45 @@ static std::string GetXDGEnvAbsolute(const char *name, const char *fallback_path return fallback_paths; } +/// @param rt_dir_prefix Directory prefix with a trailing slash +static bool FindEitherActiveRuntimeFilename(const char *prefix_desc, const std::string &rt_dir_prefix, uint16_t major_version, + std::string &out) { + { + std::ostringstream oss; + oss << "Looking for active_runtime." XR_ARCH_ABI ".json or active_runtime.json in "; + oss << prefix_desc; + oss << ": "; + oss << rt_dir_prefix; + + LoaderLogger::LogInfoMessage("", oss.str()); + } + { + auto decorated_path = rt_dir_prefix + std::to_string(major_version) + "/active_runtime." XR_ARCH_ABI ".json"; + + if (FileSysUtilsPathExists(decorated_path)) { + out = decorated_path; + return true; + } + } + { + auto undecorated_path = rt_dir_prefix + std::to_string(major_version) + "/active_runtime.json"; + + if (FileSysUtilsPathExists(undecorated_path)) { + out = undecorated_path; + return true; + } + } + return false; +} // Return the first instance of relative_path occurring in an XDG config dir according to standard // precedence order. -static bool FindXDGConfigFile(const std::string &relative_path, std::string &out) { - out = GetXDGEnvHome("XDG_CONFIG_HOME", ".config"); - if (!out.empty()) { - out += "/"; - out += relative_path; - - LoaderLogger::LogInfoMessage("", "Looking for " + relative_path + " in XDG_CONFIG_HOME: " + out); - if (FileSysUtilsPathExists(out)) { +static bool FindXDGConfigFile(const char *relative_dir, uint16_t major_version, std::string &out) { + const std::string message{"Looking for active_runtime." XR_ARCH_ABI ".json or active_runtime.json"}; + std::string dir_prefix = GetXDGEnvHome("XDG_CONFIG_HOME", ".config"); + if (!dir_prefix.empty()) { + dir_prefix += "/"; + dir_prefix += relative_dir; + if (FindEitherActiveRuntimeFilename("XDG_CONFIG_HOME", dir_prefix, major_version, out)) { return true; } } @@ -294,29 +323,26 @@ static bool FindXDGConfigFile(const std::string &relative_path, std::string &out if (path.empty()) { continue; } - out = path; - out += "/"; - out += relative_path; - LoaderLogger::LogInfoMessage("", "Looking for " + relative_path + " in an entry of XDG_CONFIG_DIRS: " + out); - if (FileSysUtilsPathExists(out)) { + dir_prefix = std::move(path); + dir_prefix += "/"; + dir_prefix += relative_dir; + if (FindEitherActiveRuntimeFilename("an entry of XDG_CONFIG_DIRS", dir_prefix, major_version, out)) { return true; } } - out = SYSCONFDIR; - out += "/"; - out += relative_path; - LoaderLogger::LogInfoMessage("", "Looking for " + relative_path + " in compiled-in SYSCONFDIR: " + out); - if (FileSysUtilsPathExists(out)) { + dir_prefix = SYSCONFDIR; + dir_prefix += "/"; + dir_prefix += relative_dir; + if (FindEitherActiveRuntimeFilename("compiled-in SYSCONFDIR", dir_prefix, major_version, out)) { return true; } #if defined(EXTRASYSCONFDIR) - out = EXTRASYSCONFDIR; - out += "/"; - out += relative_path; - LoaderLogger::LogInfoMessage("", "Looking for " + relative_path + " in compiled-in EXTRASYSCONFDIR: " + out); - if (FileSysUtilsPathExists(out)) { + dir_prefix = EXTRASYSCONFDIR; + dir_prefix += "/"; + dir_prefix += relative_dir; + if (FindEitherActiveRuntimeFilename("compiled-in EXTRASYSCONFDIR", dir_prefix, major_version, out)) { return true; } #endif @@ -632,9 +658,8 @@ XrResult RuntimeManifestFile::FindManifestFiles(std::vector @@ -29,6 +29,10 @@ #include "android_utilities.h" #include #include + +// Needed for the loader init struct +#include +#include #endif // XR_USE_PLATFORM_ANDROID #ifdef XR_KHR_LOADER_INIT_SUPPORT @@ -105,33 +109,22 @@ XrResult LoaderInitData::initialize(const XrLoaderInitInfoBaseHeaderKHR* info) { if (cast_info->applicationContext == nullptr) { return XR_ERROR_VALIDATION_FAILURE; } + + // Copy and store the JVM pointer and Android Context, ensuring the JVM is initialised. _data = *cast_info; - jni::init((jni::JavaVM*)_data.applicationVM); _data.next = nullptr; - JNIEnv* Env; - ((jni::JavaVM*)(cast_info->applicationVM))->AttachCurrentThread(&Env, nullptr); - const jclass contextClass = Env->GetObjectClass((jobject)_data.applicationContext); - - const jmethodID getAssetsMethod = Env->GetMethodID(contextClass, "getAssets", "()Landroid/content/res/AssetManager;"); - const jobject AssetManagerObject = Env->CallObjectMethod((jobject)_data.applicationContext, getAssetsMethod); - _android_asset_manager = AAssetManager_fromJava(Env, AssetManagerObject); - - const jmethodID getApplicationContextMethod = - Env->GetMethodID(contextClass, "getApplicationContext", "()Landroid/content/Context;"); - const jobject contextObject = Env->CallObjectMethod((jobject)_data.applicationContext, getApplicationContextMethod); - const jmethodID getApplicationInfoMethod = - Env->GetMethodID(contextClass, "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;"); - const jobject applicationInfoObject = Env->CallObjectMethod(contextObject, getApplicationInfoMethod); - const jfieldID nativeLibraryDirField = - Env->GetFieldID(Env->GetObjectClass(applicationInfoObject), "nativeLibraryDir", "Ljava/lang/String;"); - const jobject nativeLibraryDirObject = Env->GetObjectField(applicationInfoObject, nativeLibraryDirField); - const jmethodID getBytesMethod = - Env->GetMethodID(Env->GetObjectClass(nativeLibraryDirObject), "getBytes", "(Ljava/lang/String;)[B"); - const auto bytesObject = - static_cast(Env->CallObjectMethod(nativeLibraryDirObject, getBytesMethod, Env->NewStringUTF("UTF-8"))); - const size_t length = Env->GetArrayLength(bytesObject); - const jbyte* const bytes = Env->GetByteArrayElements(bytesObject, nullptr); - _native_library_path = std::string(reinterpret_cast(bytes), length); + jni::init(static_cast(_data.applicationVM)); + const jni::Object context = jni::Object{static_cast(_data.applicationContext)}; + + // Retrieve a reference to the Android AssetManager. + const auto assetManager = context.call("getAssets()Landroid/content/res/AssetManager;"); + _android_asset_manager = AAssetManager_fromJava(jni::env(), assetManager.getHandle()); + + // Retrieve the path to the native libraries. + const auto applicationContext = context.call("getApplicationContext()Landroid/content/Context;"); + const auto applicationInfo = context.call("getApplicationInfo()Landroid/content/pm/ApplicationInfo;"); + _native_library_path = applicationInfo.get("nativeLibraryDir"); + _initialized = true; return XR_SUCCESS; } diff --git a/src/scripts/generate_api_layer_manifest.py b/src/scripts/generate_api_layer_manifest.py index 04013fdd..fc843f3c 100755 --- a/src/scripts/generate_api_layer_manifest.py +++ b/src/scripts/generate_api_layer_manifest.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 # -# Copyright (c) 2017 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 29eef030..188865c0 100755 --- a/src/scripts/loader_source_generator.py +++ b/src/scripts/loader_source_generator.py @@ -81,6 +81,7 @@ def getProto(self, cur_cmd): # self the LoaderSourceOutputGenerator object def outputGeneratedHeaderWarning(self): + # REUSE-IgnoreStart generated_warning = '' generated_warning += '// Copyright (c) 2017-2023, The Khronos Group Inc.\n' generated_warning += '// Copyright (c) 2017-2019 Valve Corporation\n' @@ -90,6 +91,7 @@ def outputGeneratedHeaderWarning(self): generated_warning += '// *********** THIS FILE IS GENERATED - DO NOT EDIT ***********\n' generated_warning += '// See loader_source_generator.py for modifications\n' generated_warning += '// ************************************************************\n' + # REUSE-IgnoreEnd write(generated_warning, file=self.outFile) # Call the base class to properly begin the file, and then add @@ -121,7 +123,7 @@ def beginFile(self, genOpts): preamble += '#include "loader_logger.hpp"\n' preamble += '#include "loader_platform.hpp"\n' preamble += '#include "runtime_interface.hpp"\n' - preamble += '#include "xr_generated_dispatch_table.h"\n\n' + preamble += '#include "xr_generated_dispatch_table_core.h"\n\n' preamble += '#include "xr_dependencies.h"\n' preamble += '#include \n' diff --git a/src/scripts/src_genxr.py b/src/scripts/src_genxr.py index 6bab4654..922e9d90 100755 --- a/src/scripts/src_genxr.py +++ b/src/scripts/src_genxr.py @@ -96,6 +96,7 @@ def makeGenOpts(args): emitExtensionsPat = makeREstring(emitExtensions, allExtensions) featuresPat = makeREstring(features, allFeatures) + # REUSE-IgnoreStart # Copyright text prefixing all headers (list of strings). prefixStrings = [ '/*', @@ -115,6 +116,7 @@ def makeGenOpts(args): '*/', '' ] + # REUSE-IgnoreEnd # Text specific to OpenXR headers xrPrefixStrings = [ @@ -191,37 +193,29 @@ def makeGenOpts(args): apientryp = 'XRAPI_PTR *',) ] - genOpts['xr_generated_dispatch_table.h'] = [ - UtilitySourceOutputGenerator, - AutomaticSourceGeneratorOptions( - conventions = conventions, - filename = 'xr_generated_dispatch_table.h', - directory = directory, - apiname = 'openxr', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'openxr', - addExtensions = None, - removeExtensions = None, - emitExtensions = emitExtensionsPat) - ] + DISPATCH_TABLE_FILES = [ + 'xr_generated_dispatch_table.h', + 'xr_generated_dispatch_table.c', + 'xr_generated_dispatch_table_core.h', + 'xr_generated_dispatch_table_core.c', + ] - genOpts['xr_generated_dispatch_table.c'] = [ - UtilitySourceOutputGenerator, - AutomaticSourceGeneratorOptions( - conventions = conventions, - filename = 'xr_generated_dispatch_table.c', - directory = directory, - apiname = 'openxr', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'openxr', - addExtensions = None, - removeExtensions = None, - emitExtensions = emitExtensionsPat) - ] + for filename in DISPATCH_TABLE_FILES: + genOpts[filename] = [ + UtilitySourceOutputGenerator, + AutomaticSourceGeneratorOptions( + conventions = conventions, + filename = filename, + directory = directory, + apiname = 'openxr', + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = 'openxr', + addExtensions = None, + removeExtensions = None, + emitExtensions = emitExtensionsPat) + ] genOpts['xr_generated_loader.hpp'] = [ LoaderSourceOutputGenerator, diff --git a/src/scripts/utility_source_generator.py b/src/scripts/utility_source_generator.py index c5728697..9ecb0c6b 100755 --- a/src/scripts/utility_source_generator.py +++ b/src/scripts/utility_source_generator.py @@ -29,15 +29,17 @@ class UtilitySourceOutputGenerator(AutomaticSourceOutputGenerator): # Override the base class header warning so the comment indicates this file. # self the UtilitySourceOutputGenerator object def outputGeneratedHeaderWarning(self): + # REUSE-IgnoreStart generated_warning = '' 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' + generated_warning += '// Copyright (c) 2017-2019, Valve Corporation\n' + generated_warning += '// Copyright (c) 2017-2019, LunarG, Inc.\n\n' # Broken string is to avoid confusing the REUSE tool here. - generated_warning += '// SPDX-License-' + 'Identifier: Apache-2.0 OR MIT\n' + generated_warning += '// SPDX-License-' + 'Identifier: Apache-2.0 OR MIT\n\n' generated_warning += '// *********** THIS FILE IS GENERATED - DO NOT EDIT ***********\n' generated_warning += '// See utility_source_generator.py for modifications\n' generated_warning += '// ************************************************************\n' + # REUSE-IgnoreEnd write(generated_warning, file=self.outFile) # Call the base class to properly begin the file, and then add @@ -47,15 +49,24 @@ def outputGeneratedHeaderWarning(self): def beginFile(self, genOpts): AutomaticSourceOutputGenerator.beginFile(self, genOpts) preamble = '' - if self.genOpts.filename == 'xr_generated_dispatch_table.h': - preamble += '#pragma once\n' + if self.genOpts.filename == 'xr_generated_dispatch_table_core.h': + preamble += '#pragma once\n\n' + preamble += '#include \n' + elif self.genOpts.filename == 'xr_generated_dispatch_table.h': + preamble += '#pragma once\n\n' + preamble += '#include "xr_dependencies.h"\n' + preamble += '#include \n' + preamble += '#include \n' + elif self.genOpts.filename == 'xr_generated_dispatch_table_core.c': + preamble += '#include "xr_generated_dispatch_table_core.h"\n' elif self.genOpts.filename == 'xr_generated_dispatch_table.c': preamble += '#include \n' preamble += '#include "xr_generated_dispatch_table.h"\n' + else: + raise RuntimeError("Unknown filename! " + self.genOpts.filename) + + preamble += '\n' - preamble += '#include "xr_dependencies.h"\n' - preamble += '#include \n' - preamble += '#include \n\n' write(preamble, file=self.outFile) # Write out all the information for the appropriate file, @@ -68,9 +79,14 @@ def endFile(self): file_data += 'extern "C" { \n' file_data += '#endif\n' - if self.genOpts.filename == 'xr_generated_dispatch_table.h': + if self.genOpts.filename == 'xr_generated_dispatch_table_core.h': file_data += self.outputDispatchTable() file_data += self.outputDispatchPrototypes() + elif self.genOpts.filename == 'xr_generated_dispatch_table.h': + file_data += self.outputDispatchTable() + file_data += self.outputDispatchPrototypes() + elif self.genOpts.filename == 'xr_generated_dispatch_table_core.c': + file_data += self.outputDispatchTableHelper() elif self.genOpts.filename == 'xr_generated_dispatch_table.c': file_data += self.outputDispatchTableHelper() else: @@ -115,6 +131,16 @@ def outputDispatchTable(self): commands = self.ext_commands for cur_cmd in commands: + if self.genOpts.filename == 'xr_generated_dispatch_table_core.h': + if self.isCoreExtensionName(cur_cmd.ext_name): + pass + # Loader implements XR_EXT_debug_utils + elif cur_cmd.ext_name == 'XR_EXT_debug_utils': + pass + else: + # Skip anything that is not core or XR_EXT_debug_utils in the loader dispatch table + continue + # If we've switched to a new "feature" print out a comment on what it is. Usually, # this is a group of core commands or a group of commands in an extension. if cur_cmd.ext_name != cur_extension_name: @@ -168,6 +194,16 @@ def outputDispatchTableHelper(self): if cur_cmd.name in self.no_trampoline_or_terminator: continue + if self.genOpts.filename == 'xr_generated_dispatch_table_core.c': + if self.isCoreExtensionName(cur_cmd.ext_name): + pass + # Loader implements XR_EXT_debug_utils + elif cur_cmd.ext_name == 'XR_EXT_debug_utils': + pass + else: + # Skip anything that is not core or XR_EXT_debug_utils in the loader dispatch table + continue + # If we've switched to a new "feature" print out a comment on what it is. Usually, # this is a group of core commands or a group of commands in an extension. if cur_cmd.ext_name != cur_extension_name: diff --git a/src/scripts/validation_layer_generator.py b/src/scripts/validation_layer_generator.py index c928838d..c037afcc 100644 --- a/src/scripts/validation_layer_generator.py +++ b/src/scripts/validation_layer_generator.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -i # -# Copyright (c) 2017 The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # Copyright (c) 2017 Valve Corporation # Copyright (c) 2017 LunarG, Inc. #