View Full Version : Fragment Shading in a Threaded Plugin

Jay Cornwall
08-09-2005, 08:04 AM
This one's a bit tricky, so let me explain.

I'm adapting an image processing plugin for Autodesk's Toxik compositing software to utilise the GPU. I have a standalone equivalent of the CPU algorithm running perfectly and considerably faster. I need to integrate this code into a plugin.

The plugin is in the form of a DLL into which calls are made by the host application. The application has its own OpenGL context for full-screen rendering - which it continues to do while the DLL does its work - but the thread calling into the DLL does not have an associated OpenGL context. The theory goes that I can create my own context, do my rendering and clean up afterwards (if a little slower for the context switch).

I've attempted two methods to obtain a context. The first interferes with the full-screen OpenGL display, creating an invisible window (in Windows) from which a pixel format is set up and a context associated. The other approach latches on to the host's window and creates a context from this; cleaner, and doesn't interfere with the display. Both approaches exhibit identical behaviour in the case described below.

Now inside the thread, following context creation, I attempt to do some rendering with FBOs. The process is:

Set up FBO Set up textures Bind vertex shader Bind fragment shader Draw rectangle Read back from FBO Disable FBO
This approach is identical to that used in my standalone application. All of these steps succeed if I do not bind the fragment shader. Any attempt to bind a fragment shader, even the most trivial one, results in a black display. What puzzles me is why the vertex shader works at all (and I've confirmed that it is indeed being run, by making minor tweaks to the vertices).
Since the code in both cases is identical I can only assume I've made a bad assumption about OpenGL thread safety. Does this approach sound safe enough?

On XP with NVIDIA 77.72 drivers, GeForce 6800GT.

08-09-2005, 02:13 PM
There is a several issues regarding FBO. Simon Green can tell you more details, but AFAIK check for this issues:
- FBO doesn't work with 77.50 and below if 4xAnisotropical is Enabled in Driver Menu
- FBO is not thread safe. If using multiple threads and multiple contexts, do not share framebuffer objects across contexts.
- FBO is not working in dualview

Have you try something simple, without shaders? Is it work? Maybe glReadPixels gets data from wrong context? Check FBO spec and section about ReadBuffer. In short... if you readback from FBO you have to call glReadBuffer(GL_COLOR_ATTACHMENT0_EXT) before glReadPixels.

And one question about readback speed. Did you do some benches? Im trying to find fastest way to readback result. My current score is ~450MB/sec on 6800GT, P4 3.2, AGP, FSB800. It's a ~56 fps in HD resolution (1920x1080xBGRA). Im wondering can be a faster?


Jay Cornwall
08-09-2005, 11:51 PM
Thanks for the reply,

These are 77.72 drivers and no anisotropic filtering is set. The FBO (and context, and all of my OpenGL work - the host has its own context and thread) is used inside a single thread. This is also a single display setup.

I have tried a simpler example without shaders and it works great, FBO, readback and everything. Even the vertex shader works fine, but my attempts to bind a known working fragment shader consistently result in nothing but black on readback.

I'm fairly sure my use of the FBO code, including attachment setup, draw buffers, etc. is all correct, as it corresponds to all the examples I've been able to source and works fine standalone. It seems to me to be caused by some interaction with other thread's use of OpenGL, because I can't see any other difference between running the program alone and in the plugin.

I've not done any benchmarking yet, although I will be this weekend for a yet unpublished paper on EXT_framebuffer_object and ARB_draw_buffers performance. I'm impressed with your figure on an AGP system, though; I was under the impression that readback was limited to PCI speeds. I'll be testing on my PCI Express system soon.

08-10-2005, 01:41 AM
Did you try with very simple fragment shader? Or, could you post fragment shader here?


Jay Cornwall
08-10-2005, 01:59 AM
void main() {
gl_FragData[0] = half4(0.5, 0.5, 0.5, 1.0);

Even the most trivial shader does nothing, including ones which work identically in standalone programs.

Jay Cornwall
08-10-2005, 05:09 AM
Ok, please forgive my utter stupidity. This was completely unrelated to OpenGL and the fragment shader was, in fact, working fine.


08-10-2005, 10:49 AM
Originally posted by yooyo:
- FBO is not working in dualviewIt most certainly does work in dualview (77.76)

08-10-2005, 11:55 AM
Originally posted by knackered:
It most certainly does work in dualview (77.76)Thanx knackered. I didn't test this issue on newest driver releast. I just copy/paste info from Simon Green message. Seems that this info is related to older driver releases.