diff --git a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt index 6f65a52fc..86cc00360 100644 --- a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt +++ b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt @@ -45,6 +45,9 @@ set(INCLUDE include/TextureViewGLImpl.hpp include/VAOCache.hpp ) +if(DILIGENT_USE_OPENXR) + list(APPEND INCLUDE include/OpenXR_GLHelpers.hpp) +endif() set(INTERFACE interface/BaseInterfacesGL.h @@ -287,6 +290,11 @@ else() ) endif() +if(DILIGENT_USE_OPENXR) + target_link_libraries(Diligent-GraphicsEngineOpenGL-static PRIVATE OpenXR::headers) + target_compile_definitions(Diligent-GraphicsEngineOpenGL-static PRIVATE DILIGENT_USE_OPENXR=1) +endif() + add_library(Diligent-GLAdapterSelector OBJECT "src/GLAdapterSelector.cpp") target_link_libraries(Diligent-GLAdapterSelector PRIVATE Diligent-BuildSettings) diff --git a/Graphics/GraphicsEngineOpenGL/include/OpenXR_GLHelpers.hpp b/Graphics/GraphicsEngineOpenGL/include/OpenXR_GLHelpers.hpp new file mode 100644 index 000000000..eea2b0ec4 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/OpenXR_GLHelpers.hpp @@ -0,0 +1,90 @@ +/* + * Copyright 2024 Diligent Graphics LLC + * + * 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. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#if GL_SUPPORTED + +# define XR_USE_GRAPHICS_API_OPENGL +# include + +using XrGraphicsRequirementsGL = XrGraphicsRequirementsOpenGLKHR; +using PFN_xrGetGLGraphicsRequirements = PFN_xrGetOpenGLGraphicsRequirementsKHR; +static constexpr char xrGetGLGraphicsRequirementsFunctionName[] = "xrGetOpenGLGraphicsRequirementsKHR"; +static constexpr XrStructureType XR_TYPE_GRAPHICS_REQUIREMENTS_GL = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR; + + +#else GLES_SUPPORTED + +# define XR_USE_GRAPHICS_API_OPENGL_ES +# include + +using XrGraphicsRequirementsGL = XrGraphicsRequirementsOpenGLESKHR; +using PFN_xrGetGLGraphicsRequirements = PFN_xrGetOpenGLESGraphicsRequirementsKHR; +static constexpr char xrGetGLGraphicsRequirementsFunctionName[] = "xrGetOpenGLESGraphicsRequirementsKHR"; +static constexpr XrStructureType XR_TYPE_GRAPHICS_REQUIREMENTS_GL = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR; + +#endif + +namespace Diligent +{ + +static Version GetOpenXRRequiredGLVersion(const OpenXRAttribs* pXR) noexcept(false) +{ + if (pXR == nullptr || pXR->Instance == 0) + return {}; + + if (pXR->GetInstanceProcAddr == nullptr) + LOG_ERROR_AND_THROW("xrGetInstanceProcAddr must not be null"); + + XrInstance xrInstance = XR_NULL_HANDLE; + static_assert(sizeof(xrInstance) == sizeof(pXR->Instance), "XrInstance size mismatch"); + memcpy(&xrInstance, &pXR->Instance, sizeof(xrInstance)); + + XrSystemId xrSystemId = XR_NULL_SYSTEM_ID; + static_assert(sizeof(xrSystemId) == sizeof(pXR->SystemId), "XrSystemId size mismatch"); + memcpy(&xrSystemId, &pXR->SystemId, sizeof(XrSystemId)); + + PFN_xrGetInstanceProcAddr xrGetInstanceProcAddr = reinterpret_cast(pXR->GetInstanceProcAddr); + PFN_xrGetGLGraphicsRequirements xrGetOpenGLGraphicsRequirements = nullptr; + if (XR_FAILED(xrGetInstanceProcAddr(xrInstance, xrGetGLGraphicsRequirementsFunctionName, reinterpret_cast(&xrGetOpenGLGraphicsRequirements)))) + { + LOG_ERROR_AND_THROW("Failed to get ", xrGetGLGraphicsRequirementsFunctionName, ". Make sure that XR_KHR_opengl_enable/XR_KHR_opengl_es_enable extension is enabled."); + } + + XrGraphicsRequirementsGL xrGraphicsRequirements{XR_TYPE_GRAPHICS_REQUIREMENTS_GL}; + if (XR_FAILED(xrGetOpenGLGraphicsRequirements(xrInstance, xrSystemId, &xrGraphicsRequirements))) + { + LOG_ERROR_AND_THROW("Failed to get OpenGL graphics requirements"); + } + + return Version{ + XR_VERSION_MAJOR(xrGraphicsRequirements.minApiVersionSupported), + XR_VERSION_MINOR(xrGraphicsRequirements.minApiVersionSupported), + }; +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp index 52bdc59b5..8590e33a3 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 Diligent Graphics LLC + * Copyright 2019-2024 Diligent Graphics LLC * Copyright 2015-2019 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,6 +32,10 @@ #include "GLTypeConversions.hpp" #include "GraphicsAccessories.hpp" +#if DILIGENT_USE_OPENXR +# include "OpenXR_GLHelpers.hpp" +#endif + namespace Diligent { @@ -42,6 +46,15 @@ GLContext::GLContext(const EngineGLCreateInfo& InitAttribs, m_Context{0}, m_WindowHandleToDeviceContext{0} { +#if DILIGENT_USE_OPENXR + Version OpenXRRequiredGLVersion; + if (InitAttribs.Window.hWnd != nullptr) + { + // Check OpenXR requirements when not attaching to an existing context + OpenXRRequiredGLVersion = GetOpenXRRequiredGLVersion(InitAttribs.pXRAttribs); + } +#endif + int MajorVersion = 0, MinorVersion = 0; if (InitAttribs.Window.hWnd != nullptr) { @@ -202,6 +215,14 @@ GLContext::GLContext(const EngineGLCreateInfo& InitAttribs, APIVersion = Version{static_cast(MajorVersion), static_cast(MinorVersion)}; VERIFY(static_cast(APIVersion.Major) == MajorVersion && static_cast(APIVersion.Minor) == MinorVersion, "Not enough bits to store version number"); + +#if DILIGENT_USE_OPENXR + if (InitAttribs.Window.hWnd != nullptr && OpenXRRequiredGLVersion > APIVersion) + { + LOG_ERROR("OpenGL version ", APIVersion.Major, '.', APIVersion.Minor, " does not meet minimum required version for OpenXR: ", + OpenXRRequiredGLVersion.Major, '.', OpenXRRequiredGLVersion.Minor); + } +#endif } GLContext::~GLContext()