May I create a glFenceSync in one thread, and wait for it in another thread(glClientWaitSync) in GE8430?

Recently, in my project, I use glFenceSync to generate a sync object in my renderThread, and use a buffer to storage the sync obj. And in a other thread , I read the sync value and give it to the glClientWaitSync. But it not works, and error is WAIT_FAILED. I find the error is that the sync obj is not a valid sync obj. However, in rendering thread, I use glIsSync to judege the sync, the return value is true, but the return value is false when I use glIsSync to judge the value I read from the buffer? Do your driver not support the operation of this? can you give me suggestions to resolve this problem ?

Here is my code
in rendering thread:

m_mainThreadSyncObj = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
ImageShotThread::CaptureImageTask shotTask{m_FBOID, m_mainThreadSyncObj, m_Textures[m_CurrentFBOIndex].GetImageDataBuffer(),m_Textures[m_CurrentFBOIndex].GetImageWidth(), m_Textures[m_CurrentFBOIndex].GetImageHeight()};
m_ImageShotThread.AddImgCaptureTask(shotTask); // add the syncobj into the buffer

in a other thread:
GLenum ret = GL_TIMEOUT_EXPIRED;
while (GL_ALREADY_SIGNALED != ret && GL_CONDITION_SATISFIED != ret)
{
ret = glClientWaitSync(task.sync, 0, 100000000);
}

but here, glissync(task.sync) is false,but i read the opengles 3.2 documentation, it support this operation? Do your driver not support?

Respect your answer soon!

Hi zhuyingliang,

Thanks for your message and welcome to the PowerVR Developer Forum, we will analyse the sync issue you’re experiencing and come back to you with more information.

Best regards,
Alejandro

Hi zhuyingliang,

Apologies for the delay.

That functionality is supported by our drivers. As a first step, I would suggest you verify the following points below:

  • Before you call glFenceSync or glClientWaitSync, make sure you make current your GL context (i.e., you call eglMakeCurrent) in your current execution thread.
  • Make sure the GLES context bound is valid, you can query it with eglGetCurrentContext.
  • Make sure the fence value returned by glFenceSync in your rendering thread is the same as the one used in glClientWaitSync, given by task.sync in your example code.
  • Query the properties of the fence sync value m_mainThreadSyncObj after calling m_mainThreadSyncObj = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); and before calling glClientWaitSync. You can use glGetSynciv for that.

Let us know if after those tests you are still experiencing issues.

Best regards,
Alejandro

Hi Alejandro Cosin:
Apologies for the delay.
I verify the points you suggested, the results and logs here I can provide for you.
First, I make sure that when I call glFenceSync function, I make the current my GL context in my current renderthread thread. Because I can render birdview in my screen. But i am not sure that in another thread(using glClientWaitSync) should be in the same context as renderthread?
Secondly, In rendertherad, I print the value of sync in two thread, the value is same, But when using glIsSync to judge, the result is not same.


Thirdly, I found that if I use the glFenceSync and glClientWaitSync is a thread, it works well and not throw wait-failed error. But this using method not satisfy my program requirements. (I need synchonization between GPU and CPU, I want to load the data from GPU and transfer the data to other application by CPU)

Finally, here are two main points:
1、 The glFenceSync and glClientWaitSync should be in one GL context? And in my opinion, this pair of api can cross thread to use and needn’t be in the context. By contrast, if they all under one context, the fence will be no sense, becasue the command queue in the context is the same and it’s all serial.
2、Can you provide some example to give me some help( that can be tested successful in your GPU using glFenceSync and glWaitClientSync in two thread)?

The api of glFenceSync and glClientWaitSync I use is not working successfully as i expected, I hope you can give me help, because this is very important to me. Thank you!
Best wishes,
zhuyingliang

Hi zhuyingliang,

Below I reply to your questions.

Question: But i am not sure that in another thread(using glClientWaitSync) should be in the same context as renderthread?
Answer: Yes, you need to make current as well in the other thread. We have an example in our SDK (Native_SDK/examples/OpenGLES/Multithreading at master · powervr-graphics/Native_SDK · GitHub) that does asynchronous resource loading in GLES and we do that in both threads (main and secondary).

Question: The glFenceSync and glClientWaitSync should be in one GL context?
Answer: Yes, they should be in one GL context, the call to eglMakeCurrent with the same parameters as in your render thread should be enough for that.

Question: Can you provide some example to give me some help( that can be tested successful in your GPU using glFenceSync and glWaitClientSync in two thread)?
Answer: Unfortunately we do not have that specific example. You can at least review our GLES Multithreading example, it has some related code.

Below I add a schematic sample of how to use glFenceSync between threads, I hope that helps:

EGLDisplay display;
EGLSurface draw;
EGLSurface read;
EGLContext context;
GLsync synchronisationObject = 0;

// main thread
{
    // Init shared GL context and make it current
    eglMakeCurrent(display, draw, read, context);

    // [...]

    synchronisationObject = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
}


// worker thread
{
    eglMakeCurrent(display, draw, read, context);

    // [...]

    GLenum result = glClientWaitSync(synchronisationObject, 0, timeout_in_nanoseconds);

    if((result == GL_CONDITION_SATISFIED) || (result == GL_ALREADY_SIGNALED))
    {
        // Everything went fine
    }
    else
    {
        // Error (GL_TIMEOUT_EXPIRED / GL_WAIT_FAILED)
    }
}

Also, I would advice as in my previous message that you query the sync object on both threads with glIsSync and glGetSynciv to make sure it still exists. You might be passing the GLsync value between threads in the CPU but it might happen that the fence object in the GPU is being destroyed / becomes invalid somewhere else.

Please let us know if you still experience issues.

Best regards,
Alejandro