Check runtime OpenGL requirements prior to creating graphics binding
authorJulian Eisel <eiseljulian@gmail.com>
Thu, 11 Jul 2019 18:29:18 +0000 (20:29 +0200)
committerJulian Eisel <eiseljulian@gmail.com>
Thu, 11 Jul 2019 18:36:54 +0000 (20:36 +0200)
DirectX will need these checks too.
Also fix warnings due to wrong printf formatting.

intern/ghost/intern/GHOST_IXrGraphicsBinding.h
intern/ghost/intern/GHOST_XrContext.cpp
intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
intern/ghost/intern/GHOST_XrSession.cpp

index 6b1978bcf7dcb2594bff8ee779dcf3d49cf6a4ec..66073643317f64d6afa3641e8b0fec71676b7592 100644 (file)
@@ -39,6 +39,17 @@ class GHOST_IXrGraphicsBinding {
 #endif
   } oxr_binding;
 
+  /**
+   * Does __not__ require this object is initialized (can be called prior to
+   * #initFromGhostContext). It's actually meant to be called first.
+   *
+   * \param r_requirement_info Return argument to retrieve an informal string on the requirements
+   *                           to be met. Useful for error/debug messages.
+   */
+  virtual bool checkVersionRequirements(class GHOST_Context *ghost_ctx,
+                                        XrInstance instance,
+                                        XrSystemId system_id,
+                                        std::string *r_requirement_info) const = 0;
   virtual void initFromGhostContext(class GHOST_Context *ghost_ctx) = 0;
   virtual bool chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
                                      int64_t *r_result) const = 0;
index 2d740ca870503dd8b8ccdb1831c8a1203f0a00e3..0db55f6556f1529c372995085b8bf717cec4693b 100644 (file)
@@ -116,7 +116,7 @@ void GHOST_XrContext::printInstanceInfo()
   XrInstanceProperties instance_properties{XR_TYPE_INSTANCE_PROPERTIES};
   xrGetInstanceProperties(m_oxr->instance, &instance_properties);
 
-  printf("Connected to OpenXR runtime: %s (Version %i.%i.%i)\n",
+  printf("Connected to OpenXR runtime: %s (Version %u.%u.%u)\n",
          instance_properties.runtimeName,
          XR_VERSION_MAJOR(instance_properties.runtimeVersion),
          XR_VERSION_MINOR(instance_properties.runtimeVersion),
index aa047f92fd1a1f08fcfe884fbc6fb5196db1d356..b0b53888a80cd0ce4526bde2a0a0cd6746701dfc 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <algorithm>
 #include <list>
+#include <sstream>
 
 #if defined(WITH_X11)
 #  include "GHOST_ContextGLX.h"
@@ -54,6 +55,38 @@ static bool choose_swapchain_format_from_candidates(std::vector<int64_t> gpu_bin
 
 class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
  public:
+  bool checkVersionRequirements(GHOST_Context *ghost_ctx,
+                                XrInstance instance,
+                                XrSystemId system_id,
+                                std::string *r_requirement_info) const override
+  {
+#if defined(WITH_X11)
+    GHOST_ContextGLX *ctx_gl = static_cast<GHOST_ContextGLX *>(ghost_ctx);
+#else
+    GHOST_ContextWGL *ctx_gl = static_cast<GHOST_ContextWGL *>(ghost_ctx);
+#endif
+    XrGraphicsRequirementsOpenGLKHR gpu_requirements{XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR};
+    const uint32_t gl_version = XR_MAKE_VERSION(
+        ctx_gl->m_contextMajorVersion, ctx_gl->m_contextMinorVersion, 0);
+
+    xrGetOpenGLGraphicsRequirementsKHR(instance, system_id, &gpu_requirements);
+
+    if (r_requirement_info) {
+      std::ostringstream strstream;
+      strstream << "Min OpenGL version "
+                << XR_VERSION_MAJOR(gpu_requirements.minApiVersionSupported) << "."
+                << XR_VERSION_MINOR(gpu_requirements.minApiVersionSupported) << std::endl;
+      strstream << "Max OpenGL version "
+                << XR_VERSION_MAJOR(gpu_requirements.maxApiVersionSupported) << "."
+                << XR_VERSION_MINOR(gpu_requirements.maxApiVersionSupported) << std::endl;
+
+      *r_requirement_info = std::move(strstream.str());
+    }
+
+    return (gl_version >= gpu_requirements.minApiVersionSupported) &&
+           (gl_version <= gpu_requirements.maxApiVersionSupported);
+  }
+
   void initFromGhostContext(GHOST_Context *ghost_ctx) override
   {
 #if defined(WITH_X11)
@@ -119,6 +152,14 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
 #ifdef WIN32
 class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
  public:
+  bool checkVersionRequirements(GHOST_Context * /*ghost_ctx*/,
+                                XrInstance /*instance*/,
+                                XrSystemId /*system_id*/,
+                                std::string * /*r_requirement_info*/) const override
+  {
+    // TODO
+  }
+
   void initFromGhostContext(GHOST_Context *ghost_ctx) override
   {
     GHOST_ContextD3D *ctx_d3d = static_cast<GHOST_ContextD3D *>(ghost_ctx);
index 0c5a332f7e0357bc57d11ad7b6bb6e2953d2eb76..142620ed7fe2b2ec946328ce465ea4388a9a6e9f 100644 (file)
@@ -141,8 +141,16 @@ void GHOST_XrSession::start(const GHOST_XrSessionBeginInfo *begin_info)
             "GHOST_XrSessionStart()).\n");
     return;
   }
-  m_gpu_binding = std::unique_ptr<GHOST_IXrGraphicsBinding>(
-      GHOST_XrGraphicsBindingCreateFromType(m_context->getGraphicsBindingType()));
+
+  std::string requirement_str;
+  m_gpu_binding = GHOST_XrGraphicsBindingCreateFromType(m_context->getGraphicsBindingType());
+  if (!m_gpu_binding->checkVersionRequirements(
+          m_gpu_ctx, m_context->getInstance(), m_oxr->system_id, &requirement_str)) {
+    fprintf(stderr,
+            "Available graphics context version does not meet the following requirements: %s",
+            requirement_str.c_str());
+    return;
+  }
   m_gpu_binding->initFromGhostContext(m_gpu_ctx);
 
   XrSessionCreateInfo create_info{};