[Bf-blender-cvs] [eb0424c946f] soc-2019-openxr: Proper management of OpenXR graphics bindings for session setup

Julian Eisel noreply at git.blender.org
Mon Jun 10 22:03:42 CEST 2019


Commit: eb0424c946f4121bfd6f51a4fbbed4c4af0289a1
Author: Julian Eisel
Date:   Mon Jun 10 21:21:27 2019 +0200
Branches: soc-2019-openxr
https://developer.blender.org/rBeb0424c946f4121bfd6f51a4fbbed4c4af0289a1

Proper management of OpenXR graphics bindings for session setup

OpenXR needs to interface with some graphics library (OpenGL, Vulkan,
DirectX, etc.). This is done through graphics binding extensions. The
OpenXR specification requires these to be properly set up before a
session is created.

Adds the following:
* Support priority list of multiple graphics binding extensions (e.g.
  check OpenGL extension availability first, DirectX on Windows second,
  etc.)
* Barebones for passing graphics library data to OpenXR session
  creation. This is highly system dependent, e.g. it requires GLX data
  for OpenGL on X11 systems (XrGraphicsBindingOpenGLXlibKHR). More work,
  including additions to GHOST, will be needed once I get to the more
  graphics related stuff.
* Create an own graphics context for the VR session. It's not doing
  anything useful yet. This is just to fool the Monado OpenXR runtime
  so that it actually attempts to create the OpenXR session.
* Had to add two CMake modules for platform dependent #define's required
  by the OpenXR specification.

===================================================================

A	build_files/cmake/Modules/presentation.cmake
A	build_files/cmake/Modules/xr_platform_defines.cmake
M	source/blender/makesdna/DNA_windowmanager_types.h
M	source/blender/windowmanager/CMakeLists.txt
M	source/blender/windowmanager/intern/wm.c
M	source/blender/windowmanager/intern/wm_operators.c
M	source/blender/windowmanager/intern/wm_xr.c
M	source/blender/windowmanager/wm.h

===================================================================

diff --git a/build_files/cmake/Modules/presentation.cmake b/build_files/cmake/Modules/presentation.cmake
new file mode 100644
index 00000000000..1abcc0e66f7
--- /dev/null
+++ b/build_files/cmake/Modules/presentation.cmake
@@ -0,0 +1,101 @@
+set(PRESENTATION_BACKENDS xlib xcb wayland)
+set(PRESENTATION_BACKEND xlib CACHE STRING
+    "Presentation backend chosen at configure time")
+set_property(CACHE PRESENTATION_BACKEND PROPERTY STRINGS
+                ${PRESENTATION_BACKENDS})
+
+list(FIND PRESENTATION_BACKENDS ${PRESENTATION_BACKEND} index)
+if(index EQUAL -1)
+    message(FATAL_ERROR "Presentation backend must be one of
+            ${PRESENTATION_BACKENDS}")
+endif()
+
+message(STATUS "Using presentation backend: ${PRESENTATION_BACKEND}")
+
+
+if( PRESENTATION_BACKEND MATCHES "xlib" )
+    find_package(X11 REQUIRED)
+    if ((NOT X11_Xxf86vm_LIB) OR (NOT X11_Xrandr_LIB))
+        message(FATAL_ERROR "OpenXR xlib backend requires Xxf86vm and Xrandr")
+    endif()
+
+    add_definitions( -DSUPPORT_X )
+    add_definitions( -DOS_LINUX_XLIB )
+    set( XLIB_LIBRARIES
+            ${X11_LIBRARIES}
+            ${X11_Xxf86vm_LIB}
+            ${X11_Xrandr_LIB} )
+
+elseif( PRESENTATION_BACKEND MATCHES "xcb" )
+    find_package(PkgConfig REQUIRED)
+    # XCB + XCB GLX is limited to OpenGL 2.1
+    # add_definitions( -DOS_LINUX_XCB )
+    # XCB + Xlib GLX 1.3
+    add_definitions( -DOS_LINUX_XCB_GLX )
+
+    pkg_search_module(X11 REQUIRED x11)
+    pkg_search_module(XCB REQUIRED xcb)
+    pkg_search_module(XCB_RANDR REQUIRED xcb-randr)
+    pkg_search_module(XCB_KEYSYMS REQUIRED xcb-keysyms)
+    pkg_search_module(XCB_GLX REQUIRED xcb-glx)
+    pkg_search_module(XCB_DRI2 REQUIRED xcb-dri2)
+    pkg_search_module(XCB_ICCCM REQUIRED xcb-icccm)
+
+    set( XCB_LIBRARIES
+            ${XCB_LIBRARIES}
+            ${XCB_KEYSYMS_LIBRARIES}
+            ${XCB_RANDR_LIBRARIES}
+            ${XCB_GLX_LIBRARIES}
+            ${XCB_DRI2_LIBRARIES}
+            ${X11_LIBRARIES} )
+
+elseif( PRESENTATION_BACKEND MATCHES "wayland" )
+    find_package(PkgConfig REQUIRED)
+    pkg_search_module(WAYLAND_CLIENT REQUIRED wayland-client)
+    pkg_search_module(WAYLAND_EGL REQUIRED wayland-egl)
+    pkg_search_module(WAYLAND_SCANNER REQUIRED wayland-scanner)
+    pkg_search_module(WAYLAND_PROTOCOLS REQUIRED wayland-protocols>=1.7)
+    pkg_search_module(EGL REQUIRED egl)
+
+    add_definitions( -DOS_LINUX_WAYLAND )
+    set( WAYLAND_LIBRARIES
+            ${EGL_LIBRARIES}
+            ${WAYLAND_CLIENT_LIBRARIES}
+            ${WAYLAND_EGL_LIBRARIES} )
+
+    # generate wayland protocols
+    set(WAYLAND_PROTOCOLS_DIR ${CMAKE_SOURCE_DIR}/wayland-protocols/)
+    file(MAKE_DIRECTORY ${WAYLAND_PROTOCOLS_DIR})
+
+    pkg_get_variable(WAYLAND_PROTOCOLS_DATADIR wayland-protocols pkgdatadir)
+    pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner)
+
+    set(PROTOCOL xdg-shell-unstable-v6)
+    set(PROTOCOL_XML
+        ${WAYLAND_PROTOCOLS_DATADIR}/unstable/xdg-shell/${PROTOCOL}.xml)
+
+    if( EXISTS ${PROTOCOL_XML} )
+        execute_process(COMMAND
+                        ${WAYLAND_SCANNER}
+                        code
+                        ${PROTOCOL_XML}
+                        ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.c)
+        execute_process(COMMAND
+                        ${WAYLAND_SCANNER}
+                        client-header
+                        ${PROTOCOL_XML}
+                        ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.h)
+
+        set( WAYLAND_PROTOCOL_SRC
+                ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.c
+                ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.h )
+
+        include_directories(${WAYLAND_PROTOCOLS_DIR})
+    else()
+        message(FATAL_ERROR
+                "xdg-shell-unstable-v6.xml not found in "
+                ${WAYLAND_PROTOCOLS_DATADIR}
+                "\nYour wayland-protocols package does not "
+                "contain xdg-shell-unstable-v6.")
+    endif()
+endif()
diff --git a/build_files/cmake/Modules/xr_platform_defines.cmake b/build_files/cmake/Modules/xr_platform_defines.cmake
new file mode 100644
index 00000000000..033adb9c9da
--- /dev/null
+++ b/build_files/cmake/Modules/xr_platform_defines.cmake
@@ -0,0 +1,39 @@
+#=============================================================================
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#
+# Inspired on the Testing.cmake from Libmv
+#
+#=============================================================================
+
+
+# Determine the presentation backend for Linux systems.
+# Use an include because the code is pretty big.
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+    include(presentation)
+endif()
+
+# Several files use these compile-time platform switches
+if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+    add_definitions( -DXR_USE_PLATFORM_WIN32 )
+elseif( PRESENTATION_BACKEND MATCHES "xlib" )
+    add_definitions( -DXR_USE_PLATFORM_XLIB )
+elseif( PRESENTATION_BACKEND MATCHES "xcb" )
+    add_definitions( -DXR_USE_PLATFORM_XCB )
+elseif( PRESENTATION_BACKEND MATCHES "wayland" )
+    add_definitions( -DXR_USE_PLATFORM_WAYLAND )
+endif()
+
+add_definitions(-DXR_USE_GRAPHICS_API_OPENGL)
+
+if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+    add_definitions(-DXR_USE_GRAPHICS_API_D3D)
+    add_definitions(-DXR_USE_GRAPHICS_API_D3D10)
+    add_definitions(-DXR_USE_GRAPHICS_API_D3D11)
+    add_definitions(-DXR_USE_GRAPHICS_API_D3D12)
+endif()
+
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 41063753537..65226d8b931 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -178,8 +178,10 @@ typedef struct wmWindowManager {
   char par[7];
 
   struct wmMsgBus *message_bus;
+
   //#ifdef WITH_OPENXR
   struct wmXRContext *xr_context;
+  void *xr_gpu_context;
   //#endif
 } wmWindowManager;
 
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index b7bea4adb79..fa6640c5140 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -189,6 +189,8 @@ if(WITH_OPENXR)
       set(OPENXR_LOADER_NAME openxr_loader)
     endif()
 
+    include(xr_platform_defines)
+
     list(APPEND LIB ${OPENXR_LOADER_NAME})
   endif()
 
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 049b9210385..a3b2b85e53b 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -292,7 +292,17 @@ void WM_check(bContext *C)
 
 #ifdef WITH_OPENXR
   if (wm->xr_context == NULL) {
-    wm->xr_context = wm_xr_context_create();
+    const eWM_xrGraphicsBinding gpu_bindings_candidates[] = {
+        WM_XR_GRAPHICS_OPENGL,
+#  ifdef WIN32
+        WM_XR_GRAPHICS_D3D11,
+#  endif
+    };
+    const wmXRContextCreateInfo create_info = {
+        .gpu_binding_candidates = gpu_bindings_candidates,
+        .gpu_binding_candidates_count = ARRAY_SIZE(gpu_bindings_candidates)};
+
+    wm->xr_context = wm_xr_context_create(&create_info);
   }
 #endif
 
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 8baf635f56b..a2f3f6e0264 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -81,6 +81,10 @@
 
 #include "BLF_api.h"
 
+#ifdef WITH_OPENXR
+#  include "GHOST_C-api.h"
+#endif
+
 #include "GPU_immediate.h"
 #include "GPU_immediate_util.h"
 #include "GPU_matrix.h"
@@ -3518,15 +3522,49 @@ static void WM_OT_stereo3d_set(wmOperatorType *ot)
 }
 
 #ifdef WITH_OPENXR
+static GHOST_ContextHandle xr_session_gpu_binding_context_create(
+    eWM_xrGraphicsBinding graphics_lib)
+{
+#  ifndef WIN32
+  BLI_assert(graphics_lib == WM_XR_GRAPHICS_OPENGL);
+#  endif
+
+  switch (graphics_lib) {
+    case WM_XR_GRAPHICS_OPENGL:
+      return WM_opengl_context_create();
+    default:
+      return NULL;
+  }
+}
+
+static void xr_session_gpu_binding_context_destroy(eWM_xrGraphicsBinding graphics_lib,
+                                                   GHOST_ContextHandle ghost_context)
+{
+  switch (graphics_lib) {
+    case WM_XR_GRAPHICS_OPENGL:
+      WM_opengl_context_dispose(ghost_context);
+    default:
+      return;
+  }
+}
+
 static int xr_session_toggle_exec(bContext *C, wmOperator *UNUSED(op))
 {
-  struct wmXRContext *xr_context = CTX_wm_xr_context(C);
+  wmWindowManager *wm = CTX_wm_manager(C);
+  struct wmXRContext *xr_context = wm->xr_context;
+  const eWM_xrGraphicsBinding graphics_lib = wm_xr_session_active_graphics_lib_get(xr_context);
 
   if (wm_xr_session_is_running(xr_context)) {
+    BLI_assert(wm->xr_gpu_context != NULL);
+
     wm_xr_session_end(xr_context);
+    xr_session_gpu_binding_context_destroy(graphics_lib, wm->xr_gpu_context);
   }
   else {
-    wm_xr_session_start(xr_context);
+    BLI_assert(wm->xr_gpu_context == NULL);
+
+    wm->xr_gpu_context = xr_session_gpu_binding_context_create(graphics_lib);
+    wm_xr_session_start(xr_context, wm->xr_gpu_context);
   }
   return OPERATOR_FINISHED;
 }
diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c
index edd40ad1a99..b26e6123af3 100644
--- a/source/blender/windowmanager/intern/wm_xr.c
+++ b/source/blender/windowmanager/intern/wm_xr.c
@@ -26,15 +26,21 @@
 
 #include "BKE_context.h"
 
-#include "DNA_windowmanager_types.h"
-
 #include "MEM_guardedalloc.h"
 
 #include "BLI_assert.h"
 #include "BLI_compiler_attrs.h"
 #include "BLI_string.h"
+#include "DNA_windowmanager_types.h"
+
+#include "GHOST_C-api.h"
+
+#ifdef WITH_X11
+#  include <GL/glxew.h>
+#endif
 
 #include "openxr/openxr.h"
+#include "openxr/openxr_platform.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -65,6 +71,9 @@ typedef struct OpenXRData {
 typedef struct wmXRContext {
   OpenXRData oxr;
 
+  /** Active

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list