Сколько кадров занимает современный графический конвейер?

Предположим, что конвейер полностью заполнен: графический процессор ожидает vsync, буферы команд графического процессора / драйвера полностью заполнены, и, таким образом, пользовательская программа заблокирована.

Сколько кадров данных находится в (современном) конвейере?

Например: (4)

  1. Кадр в переднем буфере графического процессора
  2. Кадр в заднем буфере графического процессора
  3. Кадр в буфере команд графического процессора
  4. Кадр в буфере команд драйвера ЦП

person Kay    schedule 12.12.2016    source источник


Ответы (2)


Для традиционных API (API буферов команд) единственное, что действительно имеет значение, - это количество используемых вами буферов. Графический конвейер может быть конвейерным, но конвейер не настолько глубок, чтобы одновременно обрабатывать несколько полностью отдельных кадров. Таким образом, очередь (и) графического процессора и сам графический процессор обычно обрабатывают только один кадр.

И поскольку в этих API нет реального способа создавать командные данные для нескольких полных кадров, количество кадров, которые вы можете иметь в полете, будет ограничено количеством фактически используемых вами буферов. Количество кадров задержки обычно равно количеству буферов + 1, представляющему создаваемый вами кадр.

Для API командного буфера количество кадров обычно зависит от того, сколько памяти ЦП у вас есть. Количество буферов обеспечивает минимум, но технически ничто не мешает вам заранее буферизовать десятки или сотни кадров. Вне памяти процессора.

Конечно, это предполагает, что все ваши покадровые данные находятся в CB. Если какие-либо из этих данных находятся в доступной графическому процессору памяти (например, массивы матриц и т. Д.), Или вам нужно изменить наборы дескрипторов между кадрами, то теперь у вас есть другой набор вещей для буферизации. Это накладывает дополнительное ограничение на то, насколько далеко могут заходить вещи.

person Nicol Bolas    schedule 12.12.2016
comment
Благодарю за ответ. Как узнать, сколько буферов я использую? (это уровень моих знаний о графике: P) Например, в своих проектах я использую только один кадровый буфер. - person Kay; 13.12.2016
comment
@ user7226419: В OpenGL вы не можете напрямую контролировать количество буферов в буфере кадра по умолчанию. Так что на самом деле не имеет значения, сможете вы подсчитать или нет; вы ничего не можете сделать с этой информацией. Для API командного буфера вы запрашиваете определенное количество буферов. - person Nicol Bolas; 13.12.2016
comment
Несмотря на то, что невозможно контролировать количество буферов, существуют ли обычно X-буферы? Пример: для реализаций OpenGLES 2.0 на iOS, Android. - person Kay; 13.12.2016
comment
В GLES 2.0 при использовании дисплея по умолчанию используется два буфера: передний и задний. После цикла рендеринга ваше приложение должно вызвать eglSwapBuffer (display, surface), чтобы поменять местами задний и передний буфер. - person Alex Byrth; 23.04.2018

Это зависит от того, какую видеокарту вы используете и в какой режим вы ее поместили, но, вообще говоря, ответ - 1-3 кадра (или 2-4, если вы считаете кадр, в который вставляется буфер как фрейм).

  • Без Vsync или любой другой стратегии двойной буферизации нет ничего, что требовало бы, чтобы в памяти в любой момент времени сохранялось более 1 кадра, который перезаписывался, как только новый кадр помещается в буфер.
  • Когда VSync включен, новые кадры помещаются во вторую секцию буфера кадров и задерживают выполнение любых будущих команд до тех пор, пока не сработает «Вертикальная синхронизация» (отсюда и название, очевидно), после чего два кадра переворачиваются.
  • A third mode, uncommon to OpenGL but familiar to Vulkan and DirectX users, called "Letterbox mode", or sometimes called "Triple Buffering", keeps two "Back Buffers" for a total of three buffers:
    • One of the back buffers is reserved for use for when the Vertical Sync triggers.
    • Другой задний буфер получает готовые кадры напрямую, без задержек.
    • Каждый раз, когда происходит вертикальная синхронизация, роли этих двух обратных буферов переключаются.

Обратите внимание, что с тройной буферизацией хост не блокируется, когда буфер заполнен.

Графический процессор может выбрать для буферизации дополнительные кадры, как в вашем примере, хотя это более характерно для OpenGL / DirectX11-, чем для Vulkan / DirectX12 +, поскольку в этих последних API-интерфейсах хост гораздо более явным с точки зрения того, что Графический процессор должен делать это, и я не могу представить себе программиста, который намеренно расширяет буфер кадра. Не совсем ясно, какие преимущества он может предложить помимо того, что уже предлагает тройная буферизация.

person Xirema    schedule 12.12.2016
comment
OK. Итак, опытным путем, используя OpenGL с включенной vsync, я заметил, что: (1) Пока я могу получить 2 кадра ЦП, отправленные в течение 32,2 мс (не имеет значения, если первый занимает 27 мс, а второй заняло 3 мс) - то пропавших кадров не наблюдаю. (2) Однако в противном случае происходит пропадание кадра. Что я могу сделать о конвейере платформы? - person Kay; 12.12.2016
comment
@ user7226419 Это естественное поведение VSync. Если второй кадр проходит даже немного дальше отсечки для вертикальной синхронизации, графический процессор будет ждать следующего кадра перед представлением кадра. - person Xirema; 12.12.2016
comment
Однако графический процессор не стал ждать, если первый кадр пропустит обрезку. Я предполагаю, что это связано с тем, что графический процессор смог отобразить кадр 0, уже находящийся в конвейере, перед первым? Т.е. хоть 1 скрытый фрейм в конвейере? - person Kay; 12.12.2016
comment
@ user7226419 Возможно. Имейте в виду, конечно, что OpenGL позволяет делать много странных вещей, потому что графическая модель, которую он представляет, настолько отличается от того, как работают современные графические процессоры, что требуется множество Driver Magic, чтобы все соответствовало. - person Xirema; 12.12.2016