glClientWaitSync在MacOS上不工作
glClientWaitSync not working on MacOS
在我的渲染引擎中,我已经实现了三重缓冲,用于使用glMapSubBuffer以及orphaning和fence更新着色器缓冲区。在Windows中一切都很好,但当我在Mac上运行引擎时,就会出现问题。当我调用glClientWaitSync
以等待缓冲区释放时,它总是返回GL_TIMEOUT_EXPIRED
,所以我无法更新缓冲区,引擎会无限循环等待它们释放。
我认为问题出在我如何实现三重缓冲上,也是因为使用它后我没有获得太多性能。
基本上我已经做到了:
- 对于每个着色器,我都会检查它是否有缓冲区,如果有,我会使用一个类来处理这些缓冲区的更新,这些缓冲区包含我在分析着色器时创建的3个缓冲区,并将3个栅栏设置为
0
(每个缓冲区一个) - 在我的渲染循环中,我为每个着色器设置数据,对模型进行分组,以保存着色器切换,因此我使用每个着色器循环进行渲染
-
然后,对于每个着色器,我调用一个绑定其缓冲区的函数,以便使用材质和模型的数据更新缓冲区。我调用这个函数传递一个索引,该索引告诉要绑定着色器的3个缓冲区中的哪个缓冲区。该索引在主程序执行的每次绘图调用时都会更新。我用来绑定缓冲区进行更新的函数是函数A(见下文)
-
更新缓冲区后,我用
glDrawElementsInstanced(GL_TRIANGLES, mesh->GetFacesIndicesCount(), GL_UNSIGNED_INT, 0, _instances.size());
绘制对象,然后为刚刚与下面给出的函数B一起使用的缓冲区创建围栏 - 然后,对于刚才使用的同一个着色器,可能会有更多的数据,所以我重新执行步骤a第3点和第4点,直到着色器必须绘制的数据完成
函数A:
bool BindForUpdate(AUint bufferIndex)
{
if (!_created)
return false;
if(_fences[bufferIndex] != nullptr)
{
// This is the point where the rendering goes into infinite loop
unsinged int result = glClientWaitSync(_fences[bufferIndex], 0, BUFFERS_UPDATE_TIMEOUT);
while (result == GL_TIMEOUT_EXPIRED || result == GL_WAIT_FAILED)
result = glClientWaitSync(_fences[bufferIndex], 0, BUFFERS_UPDATE_TIMEOUT);
glDeleteSync(_fences[bufferIndex]);
}
glBindBufferBase(GL_UNIFORM_BUFFER, _bindingPoint, _ubos[bufferIndex]);
glBufferData(GL_UNIFORM_BUFFER, _bufferDataSize * _bufferLength, nullptr, GL_STREAM_DRAW);
_updateDataBuffer = (unsigned char*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, _bufferDataSize, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
if (_updateDataBuffer == nullptr)
return false;
return true;
}
函数B:
void SyncBuffers(unsinged int bufferIndex)
{
_fences[bufferIndex] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
}
我认为问题正是我进行三重缓冲的方式,因为我在同一渲染周期内多次使用同一缓冲区,因为要使用的缓冲区的索引在每个渲染周期更改一次,而不是每次绑定着色器缓冲区时都更改一次。
我该如何解决这个问题?
我只是尝试在每次调用glDrawElementsInstanced(GL_TRIANGLES, mesh->GetFacesIndicesCount(), GL_UNSIGNED_INT, 0, _instances.size());
后更改缓冲区索引,而不是每次渲染调用只更改一次,但仍然存在同样的问题。
在glDrawElementsInstanced
调用glFlush
之后,我尝试强制OpenGL释放缓冲区,它工作了很短时间。我使用的是OS X 10.10,它与glFlush
一起工作(仍然存在问题,因为有时glFlush
在执行过程中会发出异常),但后来我更新到OS X 10.11,glFlush
开始每次都发出异常,导致程序崩溃。
最重要的是,我认为这根本不是解决这个问题的正确方法。
您应该使用GL_SYNC_FLUSH_COMMANDS_BIT
调用glClientWaitSync()
,至少在等待循环之前的第一次调用中是这样。否则,GL可能永远不会真正处理挂起的命令,等待将永远持续下去。
注意,这可能比使用glFlush
更有效。引用OpenGL 4.5核心配置文件规范第4.1.2节:
如果在
flags
中设置了SYNC_FLUSH_COMMANDS_BIT
位,并且sync
为调用ClientWaitSync
时无信号,则等效于CCD_ 18将在对CCD_。
因此,只有当围栏还没有发出信号时,才会发出冲水信号。理想情况下,您应该以这样一种方式编写代码,即实际等待同步将是例外,而不是规则。
- QSqlquery prepare()和bindvalue()不工作
- node-gyp 在 macOS 上未正确链接库
- 导入库可以跨dll版本工作吗
- 用MacOS Mojave编译C++:致命错误:mpi.h:没有这样的文件或目录
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- MacOS通过在莫哈韦"wchar.h"下破碎的自制啤酒发出叮当声
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 适用于 macOS 的 Xcode 应用程序。这就是我设置从USB麦克风输入获取音频的方式。一年前工作,现在没有了。为什么
- QT MacOS-正确的工作目录
- C++ 类模板显式实例化在 macOS 上工作,在 ubuntu 上不起作用
- glClientWaitSync在MacOS上不工作