在GeForce GTX 1060上管理多线程应用程序中的共享OpenGL资源时崩溃

时间:2018-12-19 16:17:23

标签: multithreading opengl opengl-4 shared-resource

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

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

当主线程使用缓冲区(我猜是 $('#m_post_submit').validate({ rules: { name: { required: true }, phone_number: { required: true, minlength: 12 }, email: { required: false email: true } }, submitHandler: function(form) { form.ajaxSubmit({ type: 'post', url: form.attr('action'), data: form.serialize(), success: function() { btn.removeClass('m-loader m-loader--right m-loader--light').attr('disabled', false); location.reload(); } }); return false; } }); 的问题)渲染到另一个线程中渲染(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
}

因此有时会像这样崩溃:

  

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

如果我使用调试模式,则不会出现GL错误。

在以下情况下不会崩溃

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

2)我在上传线程中将{ ..... 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); .... } 更改为glFlush()

3)我评论glFinish()

4)在使用glMultiDrawArraysIndirect渲染之前,请插入以下代码行:

GL_DRAW_INDIRECT_BUFFER

(大约需要0.4毫秒)。 看来SSBO和VertexArrayBuffer没问题。

配置: Windows 10专业版,64位 GeForce GTX 1060 驱动程序版本416.81

0 个答案:

没有答案