Page MenuHome

WM: new offscreen window draw method to replace existing ones.
ClosedPublic

Authored by Brecht Van Lommel (brecht) on Feb 13 2018, 4:42 PM.

Details

Summary

For Blender 2.8 we had to be compatible with very old OpenGL versions, and
triple buffer was designed to work without offscreen rendering, by copying
the the backbuffer to a texture right before swapping. This way we could
avoid redrawing unchanged regions by copying them from this texture on the
next redraws. Triple buffer used to suffer from poor performance and driver
bugs on specific cards, so alternative draw methods remained available.

Now that we require newer OpenGL, we can have just a single draw method
that draws into offscreen buffers, and then draws those to the screen.
This has some advantages:

  • Poor 3D view performance when using Region Overlap should be solved now, since we can also cache overlapping regions in offscreen buffers.
  • Page flip, anaglyph and interlace stereo drawing can be a little faster by avoiding a copy to an intermediate texture.
  • The new 3D view drawing already writes to an offscreen buffer, which we can draw from directly instead of duplicating it to another buffer.
  • We can remove depth and multisample buffers from the window, and instead only allocate them for the 3D view offscreen buffer. This will save some memory as well.
  • Windows have different OpenGL contexts, and we can't share everything between them (VAOs). With this change only minimal drawing will happen directly to the screen (cursors, gestures, borders), and so all other drawing can then happen with a single OpenGL context, see D3057.

This is a work in progress (see TODO's in the code), but posting it now
so you know this is being worked on.

Diff Detail

Event Timeline

Brecht Van Lommel (brecht) created this revision.

GHOST: remove support for multisample, depth, stencil and preferred swap method.

These are no longer needed by the new window manager drawing, which mainly
draws into offscreen buffers, so we can save memory. I didn't remove alpha
because it may still be useful in the future if we ever want to have
transparent windows.

Some questions:

  • Already in the blender2.8 branch, stereo Eevee drawing causes continuous redraws and only shows a single noisy sample. The problem is that the 3D viewport only has a single GPUViewport, which is constantly switching between the two views and resetting, so it never makes progress. Perhaps the 3D view should have a second GPUViewport for stereo drawing?
  • Many operators call view3d_operator_needs_opengl. It currently sets up glViewport, glScissor and matrices on the screen framebuffer, which doesn't have a depth buffer anymore. I added offscreen depth buffer drawing at some point in the past, but I need to figure out to what extent that is used now and what other kind of OpenGL drawing operators need this for. The fact that we have both new and legacy drawing code makes it difficult to understand, is there a reason we still have the legacy draw code?

As much as I'm hyped by this, I would hold my breath until we are 100% sure the offscreen contexts works on a wide set of hardware config.

I was planning to do this already before D3057 came up. I think it's a good improvement regardless if we end up drawing in a single offscreen context or not, because of the other advantages.

Idea to have 2 GPUViewport for stereo is good but they need to share the same FramebufferList and TextureList unless you want to double every offscreen texture buffers. Edit : heh forget it it wont work. You really need to duplicate everything. But byebye vram.

The old drawing path was to support other coders to work on the old viewport while we were creating the Clay & Mode engine. I don't know if it's still required. (I would personnaly say no but I don't everyone's situation).

Rebase after committing code cleanups to blender2.8.

It's indeed a lot of memory usage for stereo. Maybe there's a couple intermediate buffers that can be shared? But no easy solutions I guess.

On a 4K monitor, with multisample 4, big 3D viewport and empty scene, this patch saves quite a bit of GPU memory. (Some is already used before Blender starts).

VersionGPU Memory Usage
2.791768MB
2.81778MB
2.8 + patch1275 MB

Update to fix all known bugs in the original patch.

  • A bunch of related code cleanups have already been committed.
  • Most of the memory usage reduction came from disabling multisample for the window, which has been committed separately.
  • GPUViewport (also in blender2.8) is currently creating multisample buffers, but Eevee does its own progressive sampling and Clay still looks aliased, so it seems they are not actually used? Not sure what the plan is here, but if for example Eevee will continue to do its own antialiasing we should be saving the memory.
  • I've left out the GHOST changes and disabling of the depth and stencil buffer from the window for now. There's still too many operators doing legacy OpenGL drawing into the backbuffer, so best leave it for another time.
  • GPUViewport is now managed by the window manager drawing. I'm not sure this is ideal, but we need to be able to bind/unbind and draw its color texture, and this seemed simpler than adding ARegionType methods to abstract that.
  • Eevee stereo drawing is now converging correctly due to storing two viewports. There is some engine data attached to the viewport, which is now duplicated as well, I'm not sure if that's a good idea or not, see TODO's in the code.
  • Performance seems to be the same as before, tested with Intel HD on macOS and NVIDIA Titan Xp on Linux. Tested with many editors, few editors, heavy scene, fast scene, etc. Overall this part of the drawing code is not so significant.
This revision was not accepted when it landed; it landed in state Needs Review.Apr 27 2018, 12:18 PM
This revision was automatically updated to reflect the committed changes.