我有一个设置,场景在屏幕外的OpenGL帧缓冲区中渲染,然后计算着色器从中提取一些数据,并将其放入设备上分配的环形缓冲区。该环形缓冲区使用glMapBufferRange()Map到主机可读内存。
在主机端,应该有一个接口,其中Push()函数将OpenGL操作排队到命令队列中,然后是glFenceSync()。Pull()函数使用glClientWaitSync()等待同步对象完成,然后从环形缓冲区的一部分读取并返回数据。
理想情况下,应该可以从不同的线程调用Push()和Pull()。但问题是,OpenGL上下文一次只能在一个线程上是当前的,而glClientWaitSync()和所有其他GL函数一样,需要正确的上下文才能是当前的。
因此,Pull()线程将获取OpenGL上下文,然后调用glClientWaitSync(),这可能会阻塞。在此期间,无法调用Push(),因为上下文在等待时仍属于另一个上下文。
在glClientWaitSync()中等待时,是否有方法临时释放线程的当前OpenGL上下文(类似于std::condition_variable::wait()解锁互斥锁的方式),或者等待属于另一个上下文的GLSync对象?
唯一的解决方案似乎是以零超时周期性地轮询glClientWaitSync()(并释放其间的上下文),或者设置第二个资源共享的OpenGL上下文。
1条答案
按热度按时间hpcdzsge1#
你不能改变别人线程中的当前上下文。你可以(通过使你线程中的上下文成为当前上下文),但是如果其他线程当前正在或试图调用一个OpenGL函数,这会导致数据竞争。
相反,您应该有两个上下文,它们之间共享对象。Sync objects在上下文之间共享,所以这不是问题。但是,您需要在创建围栏的上下文上创建围栏后,在另一个线程试图等待它之前刷新围栏。