VirtualGL / virtualgl

Main VirtualGL repository
https://VirtualGL.org
Other
695 stars 105 forks source link

Direct buffer read from application #40

Closed skeggse closed 7 years ago

skeggse commented 7 years ago

This is mostly a feature-request, though this functionality might already exist and just need to be twisted around to get working.

I'd like the ability to read directly from the VirtualGL pixelbuffer/framebuffer from an arbitrary application running on the same physical server. I'd use the VGL_READBACK=none option to reduce duplication of work. I could read directly from X, but that solution is wasteful because of the repeated copying. Best I can tell, ParaView doesn't need this functionality because it has access to the OpenGL context, and can thus read from the appropriate buffer itself. If there's a means of accomplishing this without altering VirtualGL, I'm all ears.

nathankidd commented 7 years ago

On 31/01/17 06:10 PM, Eli Skeggs wrote:

This is mostly a feature-request, though this functionality might already exist and just need to be twisted around to get working.

I'd like the ability to read directly from the VirtualGL pixelbuffer/framebuffer from an arbitrary application running on the same physical server. I'd use the |VGL_READBACK=none| option to reduce duplication of work. I could read directly from X, but that solution is wasteful because of the repeated copying. Best I can tell, ParaView doesn't need this functionality because it has access to the OpenGL context, and can thus read from the appropriate buffer itself. If there's a means of accomplishing this without altering VirtualGL, I'm all ears.

The only way I'm aware of that two separate processes can share an OpenGL resource is with a shared context, which means either contexts in the same process, or indirect contexts[1] which will be bad for performance. [1] https://www.opengl.org/sdk/docs/man2/xhtml/glXCreateContext.xml

Even if you didn't care about performance(!), you must capture the frame at the point the app expects (i.e. SwapBuffers/glFinish/glFlush). Even double-buffered applications will draw to the front buffer on occasion. The only option I see is to block in VGL (i.e. the app rendering thread) until your external process signals that is has read the frame (did I mention bad performance?). You might have VGL copy to a buffer object that your app reads back, except that typical X servers don't support indirect PBO/FBO. (With NVIDIA's binary driver loaded and their unofficial > GLX 1.4 protocol enabled it is possible something else may be supported.)

If you need something custom I can't see a more efficient method than writing a plugin for VGL that will do whatever it is you want.

But I'm interested in any other theories on an approach for this, or if there's some technical angle I missed.

-Nathan

skeggse commented 7 years ago

OK I clearly missed the documentation on VGL Plugins. It looks like that's probably exactly what I want. Ultimately I just want to avoid copying the same buffer four times over. Thanks!

dcommander commented 7 years ago

Yeah, I'm not 100% sure if I understand the solution architecture that you need, but the proposed "deferred readback" feature (https://github.com/VirtualGL/virtualgl/issues/9) might also be relevant. Normally, plugins in VGL are activated after the pixels are read back from the GPU to main memory. Deferred readback would instead pass a PBO handle into the plugin, thus allowing the plugin to directly access the GPU memory region containing the rendered 3D frame.

skeggse commented 7 years ago

Ah, that's even better. In an ideal world, the data would never leave the GPU, but in my particular case that's unrealistic. I think being able to choose where I read the data to (having access to the PBO itself) is the optimal solution for my needs.

Thanks for the tips!

dcommander commented 7 years ago

I should be clear that deferred readback is only a proposal at the moment. It will likely not happen without direct financial sponsorship of that project, or unless one of my general sponsors identifies a need for it.