PDA

View Full Version : It will block in OpenGL function when using mutlithread on Windows



HeavenJen
11-25-2005, 02:14 AM
I create two thread and two HGLRC,Them can share list and texture(because I use wglShareLists.

Thread1 for draw the created model and have priority THREAD_PRIORITY_NORMAL

Thread2 for create the next model and have priority THREAD_PRIORITY_BELOW_NORMAL

When Thread2 finish a creating model job,Thread2 will change the model that thread1 draw,so thread1 will draw the new model

The problem is:
Sometimes,when thread2 put texture data to graphic card or get texture data from graphic card or remove some texture data,thead1 will block in some gl function for a moment,like glClear ,glViewport and so on...
I think maybe the GPU or pipeline are too busy,so

The first method I try is:
I use CCriticalSection to synchronization the two thread in order to prevent the two thread send command at the same time.
However It does not work,thread1 also block in some gl funtion sometimes.

The second method I try is:
I think that maybe there are many command reside in the command queue,When queue is full,the next command will waiting for a moment to let graphic card run these command.
So besides the first method,I add glFinish everywhere to make sure the command before call glFinish will send to graphic card then the next command will be sent after calling glFinish.
However It does not work,thread1 also block in some gl funtion sometimes.

The second method I try is:
I doubt glFinish do nothing,so I replace glFinish by the code below:

glFlush();
GLuint querie;
glGenQueriesARB(1,&querie);
glBeginQueryARB(GL_SAMPLES_PASSED_ARB,querie);
glEndQueryARB(GL_SAMPLES_PASSED_ARB);
GLint available=1;
glGetQueryObjectivARB(querie,GL_QUERY_RESULT_AVAIL ABLE_ARB,&available);
while (!available)
{
Sleep(1);
glGetQueryObjectivARB(querie,GL_QUERY_RESULT_AVAIL ABLE_ARB,&available);
}

However It does not work,thread1 also block in some gl funtion sometimes.But it is better than before,the times of block are fewer and the time of block is shorter.

Another situation is that ATI chip is more seriously than nVidia chip.
The situation of block always happen in ATI chip no matter the level of chip
The situation of block seldom happen in high level nVidia chip,even if it happened,the time of block is very short.It usually happened in low level nVidia chip.

The problem have confused me for three month.
I have tried many mothods,but ....

Can anyone help me ?

jide
11-25-2005, 02:46 AM
I guess this is a normal behavior, what you made seems okay for me. Creating display list can takes a while, so you might need to use something else like vertex arrays and progressively fill them as thread 2 creates the newly model. Then, when the new model is created, display it in the first thread, and before create the new new one, progressively delete the previous one. But you might adopt a slightly different method, like allocating an enough memory before starting your thread, then play with that memory so that thread 1 renders the first part of the memory, then the second part, then back the the first, at the opposite of thread 2 which will fill in the second part of the memory first, then the first part...

Also I have some questions: do you use the same display list in both threads ? How do you manage that, can you explain more, and please explain ?

Hope that could help.

HeavenJen
11-27-2005, 10:16 PM
I don't use list.
I define a struct to store the data that include some texture and some vector data.Named ModelList
then I declare two ModelList,the first one for rendering by thread1 and the second prepare for the new model,when thread2 finish the model creating,I will change the index of ModelList,so thread1 will rendering the newer one.
then thread2 free the older ModelList and creating for next model.

nik_bg
11-28-2005, 02:59 AM
A general rule: never put gl commands in separate threads that work in parallel. All gl commands (including state changes and data upload, not only actual drawing) should be in one thread. I also have multithreading application, and all gl commands are in one thread.

HeavenJen
11-28-2005, 06:02 PM
So I must divide one work to many small work and do every small work in the interval of every frame.
Is it right ?
If it is right,It is hard to code.
Do you have any good idea ?