Похоже на ошибку драйвера, но я не уверен) Или, может быть, я что-то не так делаю
В моем приложении я использую два разных потока (и два общих контекста) для загрузки и рендеринга данных.
Приложение иногда падает (возможно, когда рабочая нагрузка выше средней), когда основной поток рендерит (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);
....
}
Так что иногда происходит сбой так:
(Исключение, выданное в 0x000001CD7121F302 в файле viewer.exe: 0xC0000005: Место чтения нарушения прав доступа 0x0000000000000100)
Если я использую режим отладки, ошибок ГЛ нет.
ВыполняетсяНЕ вылетает, если:
1) Я использую другой графический процессор (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