[Bf-blender-cvs] [6b43c82cb51] soc-2019-openxr: Set up OpenXR views and spaces for drawing

Julian Eisel noreply at git.blender.org
Sun Jun 23 18:29:05 CEST 2019


Commit: 6b43c82cb516c941d1a98b10a1a8e51d448433ea
Author: Julian Eisel
Date:   Sun Jun 23 18:07:46 2019 +0200
Branches: soc-2019-openxr
https://developer.blender.org/rB6b43c82cb516c941d1a98b10a1a8e51d448433ea

Set up OpenXR views and spaces for drawing

Using a dummy identity pose at {0, 0, 0} to start with. This should
later use the current viewport position & orientation I guess.

Also adds function to set a draw callback. There's quite some OpenXR
related stuff to be done before and after drawing anyting, as well as
before and after drawing each view (eye). Quite some info would have to
be exposed to WM to let it manage drawing. So I think using a callback
called from GHOST_Xr to draw each eye instead is a good way to go.

VR session currently crashes after opening. Seems to be related to
blocking frame wait call. I'm not too worried about that though, might
disappear once OpenXR frame sync functions get proper timing info
passed.

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

M	intern/ghost/GHOST_C-api.h
M	intern/ghost/intern/GHOST_XR.cpp
M	intern/ghost/intern/GHOST_XRSession.cpp
M	intern/ghost/intern/GHOST_XR_intern.h
M	source/blender/windowmanager/intern/wm_xr.c

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

diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 9527e12f975..0912fdf8168 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -990,6 +990,11 @@ typedef struct {
   unsigned int gpu_binding_candidates_count;
 } GHOST_XrContextCreateInfo;
 
+typedef struct {
+  // Required info to build matrices goes here.
+  int dummy;
+} GHOST_XrDrawViewInfo;
+
 /* xr-context */
 struct GHOST_XrContext *GHOST_XrContextCreate(const GHOST_XrContextCreateInfo *create_info);
 void GHOST_XrContextDestroy(struct GHOST_XrContext *xr_context);
@@ -997,11 +1002,14 @@ void GHOST_XrContextDestroy(struct GHOST_XrContext *xr_context);
 typedef void *(*GHOST_XrGraphicsContextBindFn)(GHOST_TXrGraphicsBinding graphics_lib);
 typedef void (*GHOST_XrGraphicsContextUnbindFn)(GHOST_TXrGraphicsBinding graphics_lib,
                                                 void *graphics_context);
+typedef void (*GHOST_XrDrawViewFn)(const GHOST_XrDrawViewInfo draw_view, void *customdata);
 
 void GHOST_XrGraphicsContextBindFuncs(struct GHOST_XrContext *xr_context,
                                       GHOST_XrGraphicsContextBindFn bind_fn,
                                       GHOST_XrGraphicsContextUnbindFn unbind_fn);
 
+void GHOST_XrDrawViewFunc(struct GHOST_XrContext *xr_context, GHOST_XrDrawViewFn draw_view_fn);
+
 /* sessions */
 GHOST_TSuccess GHOST_XrSessionIsRunning(const struct GHOST_XrContext *xr_context);
 void GHOST_XrSessionStart(struct GHOST_XrContext *xr_context);
@@ -1009,6 +1017,7 @@ void GHOST_XrSessionEnd(struct GHOST_XrContext *xr_context);
 void GHOST_XrSessionRenderingPrepare(struct GHOST_XrContext *xr_context);
 void GHOST_XrSessionBeginDrawing(struct GHOST_XrContext *xr_context);
 void GHOST_XrSessionEndDrawing(struct GHOST_XrContext *xr_context);
+void GHOST_XrSessionDrawViews(struct GHOST_XrContext *xr_context);
 
 /* events */
 GHOST_TSuccess GHOST_XrEventsHandle(struct GHOST_XrContext *xr_context);
diff --git a/intern/ghost/intern/GHOST_XR.cpp b/intern/ghost/intern/GHOST_XR.cpp
index faf3656fbfd..633de1dde16 100644
--- a/intern/ghost/intern/GHOST_XR.cpp
+++ b/intern/ghost/intern/GHOST_XR.cpp
@@ -301,3 +301,8 @@ void GHOST_XrGraphicsContextUnbind(GHOST_XrContext &xr_context)
   }
   xr_context.gpu_ctx = nullptr;
 }
+
+void GHOST_XrDrawViewFunc(struct GHOST_XrContext *xr_context, GHOST_XrDrawViewFn draw_view_fn)
+{
+  xr_context->draw_view_fn = draw_view_fn;
+}
diff --git a/intern/ghost/intern/GHOST_XRSession.cpp b/intern/ghost/intern/GHOST_XRSession.cpp
index 58f84313eaa..1ae4e4b7533 100644
--- a/intern/ghost/intern/GHOST_XRSession.cpp
+++ b/intern/ghost/intern/GHOST_XRSession.cpp
@@ -172,34 +172,42 @@ static XrSwapchain swapchain_create(const XrSession session,
 void GHOST_XrSessionRenderingPrepare(GHOST_XrContext *xr_context)
 {
   OpenXRData *oxr = &xr_context->oxr;
-  std::vector<XrViewConfigurationView> views;
+  std::vector<XrViewConfigurationView> view_configs;
   uint32_t view_count;
 
   xrEnumerateViewConfigurationViews(
       oxr->instance, oxr->system_id, oxr->view_type, 0, &view_count, nullptr);
-  views.resize(view_count, {XR_TYPE_VIEW_CONFIGURATION_VIEW});
-  xrEnumerateViewConfigurationViews(
-      oxr->instance, oxr->system_id, oxr->view_type, views.size(), &view_count, views.data());
-
-  for (const XrViewConfigurationView &view : views) {
+  xrEnumerateViewConfigurationViews(oxr->instance,
+                                    oxr->system_id,
+                                    oxr->view_type,
+                                    view_configs.size(),
+                                    &view_count,
+                                    view_configs.data());
+
+  for (const XrViewConfigurationView &view : view_configs) {
     XrSwapchain swapchain = swapchain_create(oxr->session, xr_context->gpu_binding.get(), &view);
     auto images = swapchain_images_create(swapchain, xr_context->gpu_binding.get());
 
     oxr->swapchain_images.insert(std::make_pair(swapchain, std::move(images)));
   }
+
+  oxr->views.resize(view_count, {XR_TYPE_VIEW});
 }
 
 void GHOST_XrSessionBeginDrawing(GHOST_XrContext *xr_context)
 {
   OpenXRData *oxr = &xr_context->oxr;
   XrFrameWaitInfo wait_info{XR_TYPE_FRAME_WAIT_INFO};
-  XrFrameState state_info{XR_TYPE_FRAME_STATE};
   XrFrameBeginInfo begin_info{XR_TYPE_FRAME_BEGIN_INFO};
+  XrFrameState frame_state{XR_TYPE_FRAME_STATE};
 
   // TODO Blocking call. Does this intefer with other drawing?
-  xrWaitFrame(oxr->session, &wait_info, &state_info);
+  xrWaitFrame(oxr->session, &wait_info, &frame_state);
 
   xrBeginFrame(oxr->session, &begin_info);
+
+  xr_context->draw_frame = std::unique_ptr<GHOST_XrDrawFrame>(new GHOST_XrDrawFrame());
+  xr_context->draw_frame->frame_state = frame_state;
 }
 
 void GHOST_XrSessionEndDrawing(GHOST_XrContext *xr_context)
@@ -207,4 +215,27 @@ void GHOST_XrSessionEndDrawing(GHOST_XrContext *xr_context)
   XrFrameEndInfo end_info{XR_TYPE_FRAME_END_INFO};
 
   xrEndFrame(xr_context->oxr.session, &end_info);
+  xr_context->draw_frame = nullptr;
+}
+
+void GHOST_XrSessionDrawViews(GHOST_XrContext *xr_context)
+{
+  OpenXRData *oxr = &xr_context->oxr;
+  XrViewLocateInfo viewloc_info{XR_TYPE_VIEW_LOCATE_INFO};
+  XrViewState view_state{XR_TYPE_VIEW_STATE};
+  XrReferenceSpaceCreateInfo refspace_info{XR_TYPE_REFERENCE_SPACE_CREATE_INFO};
+  XrSpace space;
+  uint32_t view_count;
+
+  refspace_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
+  // TODO Use viewport pose here.
+  refspace_info.poseInReferenceSpace.position = {0.0f, 0.0f, 0.0f};
+  refspace_info.poseInReferenceSpace.orientation = {0.0f, 0.0f, 0.0f, 1.0f};
+  xrCreateReferenceSpace(oxr->session, &refspace_info, &space);
+
+  viewloc_info.displayTime = xr_context->draw_frame->frame_state.predictedDisplayTime;
+  viewloc_info.space = space;
+
+  xrLocateViews(
+      oxr->session, &viewloc_info, &view_state, oxr->views.size(), &view_count, oxr->views.data());
 }
diff --git a/intern/ghost/intern/GHOST_XR_intern.h b/intern/ghost/intern/GHOST_XR_intern.h
index 2fb5bdcdff9..5daeb79cab9 100644
--- a/intern/ghost/intern/GHOST_XR_intern.h
+++ b/intern/ghost/intern/GHOST_XR_intern.h
@@ -37,6 +37,7 @@ typedef struct OpenXRData {
   XrSystemId system_id;
   // Only stereo rendering supported now.
   const XrViewConfigurationType view_type{XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO};
+  std::vector<XrView> views;
   XrSession session;
   XrSessionState session_state;
 
@@ -56,10 +57,18 @@ typedef struct GHOST_XrContext {
   /** Active Ghost graphic context. */
   class GHOST_Context *gpu_ctx;
 
+  GHOST_XrDrawViewFn draw_view_fn;
+  /** Information on the currently drawn frame. Set while drawing only. */
+  std::unique_ptr<struct GHOST_XrDrawFrame> draw_frame;
+
   /** Names of enabled extensions */
   std::vector<const char *> enabled_extensions;
 } GHOST_XrContext;
 
+struct GHOST_XrDrawFrame {
+  XrFrameState frame_state;
+};
+
 void GHOST_XrGraphicsContextBind(GHOST_XrContext &xr_context);
 void GHOST_XrGraphicsContextUnbind(GHOST_XrContext &xr_context);
 
diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c
index c9fd9b164c1..c53e021d5f6 100644
--- a/source/blender/windowmanager/intern/wm_xr.c
+++ b/source/blender/windowmanager/intern/wm_xr.c
@@ -25,9 +25,8 @@ void wm_xr_session_draw(struct GHOST_XrContext *xr_context)
   if (!GHOST_XrSessionIsRunning(xr_context)) {
     return;
   }
-
   GHOST_XrSessionBeginDrawing(xr_context);
-  /* TODO execute drawcall. Something like this? */
-  // ED_XR_view_draw();
+  // TODO session visible?
+  GHOST_XrSessionDrawViews(xr_context);
   GHOST_XrSessionEndDrawing(xr_context);
 }



More information about the Bf-blender-cvs mailing list