Сбой при управлении общими ресурсами OpenGL в многопоточном приложении на GeForce GTX 1060 - PullRequest
0 голосов
/ 19 декабря 2018

Похоже на ошибку драйвера, но я не уверен) Или, может быть, я что-то не так делаю

В моем приложении я использую два разных потока (и два общих контекста) для загрузки и рендеринга данных.

Приложение иногда падает (возможно, когда рабочая нагрузка выше средней), когда основной поток рендерит (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

...