2

看起来像一个驱动程序错误,但我不确定)或者我做错了什么

在我的应用程序中,我使用两个不同的线程(和两个共享上下文)来上传和呈现数据。

当主线程渲染()时,应用程序有时会崩溃(可能是当工作负载高于平均水平时glMultiDrawArraysIndirect),使用缓冲区(GL_DRAW_INDIRECT_BUFFER我想问题出在另一个线程中)。

一些简化的伪代码:

工作线程:

{

    ...
    uploadContext->makeCurrent();
    glCreateBuffers(1, &tile.geometryBuf);
    glNamedBufferStorage(tile.geometryBuf, geometryBuffer.size(), geometryBuffer.constData(), 0);

    glCreateBuffers(1, &tile.indirectBuffer);
    glNamedBufferStorage(tile.indirectBuffer, indirectBuffer.size(), indirectBuffer.constData(), 0);

    glCreateBuffers(1, &tile.settingsBuffer);//);
    glNamedBufferStorage(tile.settingsBuffer, settingsBuffer.size(), settingsBuffer.constData(), 0);    

    //need this for syncronization between threads
    tile.sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); 
    glFlush();

    emit tileReady(tile); //send a signal to the main thread
}

主线程:

{
    .....
    renderingContext->makeCurrent();
    ///sync
    GLenum waitReturn = glClientWaitSync(tile.sync, 0, 0);

    if (waitReturn != GL_ALREADY_SIGNALED && waitReturn != GL_CONDITION_SATISFIED)
        return;
    glDeleteSync(tile.sync);

    //binding should validate the buffer in rendering context according to specs (but seems that it doesn't)
    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, tile.indirectBuffer);

    //vao is defined during initialization
    //now only change arrayVertexBuffer binding
    glVertexArrayVertexBuffer(vao, 0, tile.geometryBuf, 0, 2 * sizeof(float));
    glBindVertexArray(vao);

    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, tile.settingsBuffer);
    glMultiDrawArraysIndirect(GL_TRIANGLES, 0, tile.counts, 0);
    ....
}

所以它有时会像这样崩溃:

(在 viewer.exe 中的 0x000001CD7121F302 处引发异常:0xC0000005:访问冲突读取位置 0x0000000000000100)

如果我使用调试模式,则没有 GL 错误。

如果出现以下情况,它不会崩溃:

1) 我使用另一个 GPU (Nvidia Geforce 980 Titan X)

或者

2)我在上传线程中更改glFlush()glFinish()

或者

3)我评论glMultiDrawArraysIndirect

或者

4)在渲染之前,GL_DRAW_INDIRECT_BUFFER我插入这些代码行:

glBindBuffer(GL_DRAW_INDIRECT_BUFFER, tile.indirectBuffer);
qint64 sz;
glGetBufferParameteri64v(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_SIZE, &sz);

(大约需要 0.4 毫秒)。SSBO 和 VertexArrayBuffer 似乎没有问题。

配置:Windows 10 Pro,64 位 GeForce GTX 1060 驱动版本 416.81

4

0 回答 0