PDA

View Full Version : Multithreading in MFC



reignofchaos
02-04-2003, 05:23 AM
Hi folks,
I'm trying to write a client server application using MFC/WGL/OpenGL. The trouble is that any calls to OGL from the main thread succeed whereas any calls from other threads fail without a reason. I'm stuck on this for a long time.
What is the exact method to enable the client threads to issue gl calls?

thanks

HS
02-04-2003, 07:02 AM
Have you tried

wglMakeCurent(HDC hdc, HGLRC hglrc);

yet?

[This message has been edited by HS (edited 02-04-2003).]

reignofchaos
02-04-2003, 09:51 AM
Originally posted by HS:
Have you tried

wglMakeCurent(HDC hdc, HGLRC hglrc);

yet?

[This message has been edited by HS (edited 02-04-2003).]


Yes I have in the main thread. I tried to do it in the worker thread as well, I still get an invalid rendering context error.

How do u use wglMakeCurrent correctly for each thread? I tried looking for some info on this but found nothing on the web.
Do we have to create a separate rendering context and setup the pixel format for each thread even if they use to the same device context?

V-man
02-04-2003, 08:34 PM
It doesn't work that way. A worker thread can't make GL calls when the RC is created in the first thread.

What you can do is compute stuff in one thread and do GL stuff in another.

I really hate this limitation.

reignofchaos
02-04-2003, 11:20 PM
thanks for the info. it saved me a lot of headache.

tranders
02-05-2003, 07:43 PM
Originally posted by V-man:
It doesn't work that way. A worker thread can't make GL calls when the RC is created in the first thread.

What you can do is compute stuff in one thread and do GL stuff in another.

I really hate this limitation.
--------

Only one thread can be current to an RC/DC pair at any one time. However if you create multiple RCs and use GetDC(hwnd) to get multiple DCs that reference a single hwnd (DCs are not threadsafe), then you can render via multiple threads. It's pretty simple if you limit swaps to only one thread and that thread waits until all the other rendering threads are finished.

FWIW, multiple threads rendering to a single window is only useful on multiprocessor systems - otherwise your performance will suffer. Also, most gaming cards do not handle multiple on-board context pipelines efficiently, so performance will vary depending on your graphics vendor.

tranders

V-man
02-06-2003, 06:16 AM
>>>However if you create multiple RCs and use GetDC(hwnd) to get multiple DCs that reference a single hwnd (DCs are not threadsafe), then you can render via multiple threads. It's pretty simple if you limit swaps to only one thread and that thread waits until all the other rendering threads are finished.<<<

You have tried this and it works?
How do the multiple RC reference the same HWND?

And sure, you have to synchronize the threads, which will slow you down.
Another reason against this is that a system will have a single video card, and having multiple CPU's making GL calls won't help the graphics performance.

reignofchaos
02-06-2003, 08:59 AM
I tried what tranders said. multiple DC and RCs. It seems to work fine and fits my bill properly. I think performance might suffer but then I only need to render something like 1 frame every 3 seconds so performance is really not an issue.

tranders
02-09-2003, 04:17 PM
Originally posted by V-man:
You have tried this and it works?
How do the multiple RC reference the same HWND?

And sure, you have to synchronize the threads, which will slow you down.
Another reason against this is that a system will have a single video card, and having multiple CPU's making GL calls won't help the graphics performance.[/B]
---
I've been doing this (MT OpenGL on WindowNT) since 1994, so I know it works. It does depend a lot on what else is going on in the application (e.g., dynamic tessellations, concurrent scene graph processing, etc.).

All you need to do is make sure your window is NOT setup for CS_OWNDC or CS_PARENTDC, and simply call GetDC(hwnd) twice to get two seperate thread-safe DCs that point to the same window and set their pixel format to the same index. You then call wglCreateContext(...) twice (against either DC) to create two RCs - one for one thread and one for the other. The rest of the problem is the hard part :-)

Synchronization is not so much of a bottleneck if done correctly given the speed of processors these days.

As you point out, there is usually on one video card on a single screen system configuration, so the graphics card driver and HW construction play a major role in the success of the multi-threaded display. FWIW, the 3Dlabs Wildcat series graphics cards have alway won the performance war against other more popular cards in a multi-threaded OpenGL application. This is primarily because the Wildcat was originally designed for multi-processor systems and have fully thread-safe drivers, full HW state support for each thread, and do not block the data flow from the application to the graphics card. There are lots of variables and mileage will vary depending on the system. The thing you want to do is keep the AGP (or PCI) bus saturated with data and that's hard to do with a single processor.

HTH,
tranders

[This message has been edited by tranders (edited 02-09-2003).]

[This message has been edited by tranders (edited 02-09-2003).]

V-man
02-09-2003, 06:03 PM
>>>There are lots of variables and mileage will vary depending on the system. The thing you want to do is keep the AGP (or PCI) bus saturated with data and that's hard to do with a single processor.<<<

I'm guessing you mean keeping it busy with polygons (vertices, normals, texcoord, color) since that would be the major part of the traffic. The problem on most cards seem to be fillrate limitations and that's easy to reach on most cards.

I don't know about the Wildcat series (Oxygen too), but they are pretty high end cards. I think it was one version of the Oxygen card, that had 4 GPU's on board, 128MB, and a whole lot of fun info.
Perhaps it's what helps it give it the edge.

If anyone wants to send me their old oxygen card, I'll give it a good home http://www.opengl.org/discussion_boards/ubb/smile.gif