GSoC 2019: Core Support of Virtual Reality Headsets through OpenXR

The Last Third

We’re approaching the last third of the coding period. At this point I’d like to digress from my schedule and work on stuff that I find more important. Namely performance improvements and polish to get the branch into a mergeable state.
In the end we should have stable and well performing VR viewport rendering support. This would be the base from which we can work on a more rich VR experience. Possibly with the help from @makx and his MARUI-Plugin team.

Note that I’ve already done some work on performance. Last week we went from ~20 FPS to ~43 FPS in my benchmarks with the Classroom scene. Others have reported even bigger speedups.

The following explains a number of tasks I’d like to work on.

Perform VR Rendering on a Separate Thread

I see four reasons for this:

  • OpenXR blocks execution to synchronize rendering with the HMD refresh rate. This would conflict with the rest of Blender, potentially causing lags.
  • VR viewports should redraw continuously with updated view position and rotation. Unlike usually in Blender where we try to only perform redraws when needed. The usual Blender main loop with all of its overhead can be avoided by a giving the VR session an own, parallel draw loop.
  • On a dedicated thread, we can keep a single OpenGL context alive, avoiding expensive context switches which we could not avoid on a single thread.
  • With a bit more work (see below), viewports can draw entirely in parallel (at least the CPU side of it), pushing performance even further.

I already started work on this (b961b3f0c9) and am confident it can be finished soon.

Draw-Manager Concurrency

Get the CPU side of the viewport rendering ready for parallel execution.
From what I can tell all that’s missing is making the global DST and batches per thread data.

In general, this should improve viewport performance in cases where offscreen rendering already takes place on separate threads (i.e. Eevee light baking). Most importantly for us, it should minimize wait times when regular 3D views and VR sessions both want to draw.

Single Pass Drawing

We currently call viewport rendering for each eye separately, i.e. we do two pass drawing. The ideal thing to do would be drawing in a single pass, where each OpenGL draw call would use shaders to push pixels to both eyes. This would be quite some work though, and is not in scope of this project. We can however do a significant step towards it by letting every OpenGL call execute twice (for each eye) with adjusted view matrices and render targets. This would only require one pass over all geometry to be drawn.
The 2.8 draw-manager already contains an abstraction, DRWView, which according to @fclem is perfectly suited for this.

So I could work on single pass (but multiple draw calls) drawing by using DRWView.

Address Remaining TODO’s

T67083 lists a number of remaining TODOs for the project. They should probably all be tackled during GSoC.

6 Likes