Чтение данных из gpu асинхронно с объектами Pixel Buffer

Получение данных из gpu кажется очень медленной задачей, если вы хотите читать их синхронизированными с вашим приложением. Одной из возможностей является асинхронное чтение с помощью объектов Pixel Buffer. К сожалению, я не могу увидеть, как это делается.

Сначала я создаю объект Pixel Buffer:

glGenBuffers(1, &pbo);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
glBufferData(GL_PIXEL_PACK_BUFFER, pbo_size, 0, GL_DYNAMIC_READ);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

Затем я хочу прочитать пиксели из объекта Frame Buffer:

glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
glReadPixels(0, 0, w, h, GL_RGBA, GL_FLOAT, 0);
GLfloat *ptr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, pbo_size, GL_MAP_READ_BIT);
memcpy(pixels, ptr, pbo_size);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

Но как это асинхронно? Блокирует ли glReadPixels или glMapBufferRange приложение, пока gpu не "готов"?

1 ответ

Решение

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

glMapBufferRange заставит glReadPixels вызов до конца, если это не так (так как вы теперь получаете доступ к указателю на процессоре, нет никакого способа обойти это).

Так что... не делайте 2 спина к спине, но значительно позже.

Чтобы добавить к ответу Бахбара:

  • После glReadPixels, если вы планируете считывать данные, я считаю, что вам следует позвонить glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);.

  • После glReadPixels а также glMemoryBarrier, вы можете создать Fence Sync с помощью glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0), затем либо проверьте, что графический процессор завершил выполнение всех инструкций перед синхронизацией с glGetSynciv(fence_sync, GL_SYNC_STATUS, sizeof(GLint), NULL, &result), или дождитесь, пока графический процессор завершит выполнение всех инструкций перед синхронизацией с glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, nanosecond_timeout).

Другие вопросы по тегам