Известный вопрос, с которым приходится сталкиваться при реализации эффективной системы синхронизации между рендером разных кадров — это то, сколько именно наборов ресурсов необходимо в зависимости от количества одновременно отрендериваемых кадров. Например, сколько нужно command buffer'ов? Сколько нужно depth buffer'ов? Странность заключается в том, что на такой простой вопрос можно найти обратно диаметральные ответы.
Например, интел утверждает, что в схеме с двойной буферизацией кадров необходимо 2 копии рендертаргетов вроде буфера глубины: https://software.intel.com/en-us/articles/practical-approach-to-vulkan-part-1
А многие тьюториалы говорят, что, так как одновременно на видюхе рендерится только 1 кадр, то достаточно одного буфера: https://vulkan-tutorial.com/Depth_buffering , даже если количество кадров в полёте больше 1.
Если же задуматься, то в случае схемы синхронизации как у интела, у них действительно никогда не рендерится на GPU более одного кадра в каждый конкретный момент времени:
Но при этом пока один command buffer выполняется на GPU, второй при этом записывается на CPU. То есть получается так, что если на GPU одновременно рендерится в полёте N кадров, то должно быть N наборов ресурсов кадра вроде буфера глубины, но N+1 command buffer, так как +1 записывается, пока N рендерятся.
Но почему я такой схемы нигде не видел? Во всех примерах в этих ваших интернетах все используют либо N command buffer'ов и N depth buffer'ов (как intel), либо N command buffer'ов и 1 depth buffer (как во многих примерах).
Как же правильно?
Suslik
> у них действительно никогда не рендерится на GPU более одного кадра в каждый
> конкретный момент времени
но если ещё подумать, то всё ещё хитрее. а именно, если представить, что у CPU время записи command buffer'а равно 0 (мы полностью GPU-bound), то посреди работы программы действительно мы ожидаем fence, после ожидания ресурсы, соответствующие этому fence уже гарантированно не используются. одна, если рассмотреть начальный момент времени, то это не так: мы засабмитим два кадра рендериться одновременно, так как ни у одного из них fence не заблочен. то есть никогда два кадра не будут одновременно рендериться кроме первых двух. тупенькая ситуация-то, так как чисто из-за этого нужно хранить дополнительный frame resource set.
Suslik
> Как же правильно?
сравнить скорость не пробовал ?
Suslik
> Например, интел утверждает, что в схеме с двойной буферизацией кадров
> необходимо 2 копии рендертаргетов вроде буфера глубины:
> https://software.intel.com/en-us/articles/practical-approach-to-vulkan-part-1
интуитивно понятно же
Suslik
> мы засабмитим два кадра рендериться одновременно
это как так ? multiGPU ?
Suslik
командных буферов 2. image из swapchain 2, так как пока презентится один, можно рендить в другой. depth буферов 1, они же реально не могут одновременно использоваться для двух разных командных буферов. а где там Intel говорит что их надо 2?
xruck
> depth буферов 1, они же реально не могут одновременно использоваться для двух
> разных командных буферов.
не понял, каждый depth buffer в своём cmd используется
может же быть асинк что берёт на текущем кадре из depth buffer старого
можно передовать буфер глубины в другую очередь для симуляции частиц, например, тогда есть смысл двойной буфертзации.
а так видеокарты пока не поддерживают параллельный рендеринг, есть тесты для дх12 где можно с этим экспериментировать.
документация вулкана разрешает параллельное рисование и даже сабпасы без зависимостей друг от друга могут рисоваться параллельно и в любой последовательности.
/A\
> документация вулкана разрешает параллельное рисование и даже сабпасы без
> зависимостей друг от друга могут рисоваться параллельно и в любой
> последовательности.
если GPU один - как рисовать параллельно ?
innuendo
> если GPU один - как рисовать параллельно ?
а как компьют шейдеры работают параллельно?
/A\
> а так видеокарты пока не поддерживают параллельный рендеринг
случается это на практике или нет — дело десятое. суть в том, что если сделать 2 frames in flight, то 2 могут оказаться засабмиченные одновременно. это значит, что между ними нет явной синхронизации и видюха имеет право решить, что их можно выполнять одновременно. в этом случае необходимо иметь 2 depth buffer'а.
xruck
> а где там Intel говорит что их надо 2?
короче, у меня есть некотрые соображения по поводу того, как это должно быть, но в первую очередь меня удивляет, почему по этому поводу нет нормальных пейперов и нет единственного решения, которое бы считалось правильным.
Suslik
> суть в том, что если сделать 2 frames in flight, то 2 могут оказаться
> засабмиченные одновременно. это значит, что между ними нет явной синхронизации
> и видюха имеет право решить, что их можно выполнять одновременно.
А Present - это разве не синхронизация?
/A\
> а как компьют шейдеры работают параллельно?
так они же не рендерят :)
prowkan
> Present - это разве не синхронизация?
в пределах одной очереди.
даже если это 2 очереди с одной family то их команды могут мержится перед выполнением и будут проблемы с синхронизацией.
в пределах одной очереди барьер в любом случае все синхронизирует.
/A\
> в пределах одной очереди барьер в любом случае все синхронизирует.
во-первых, очередей две: как минимум render queue и present queue. во-вторых, почему тогда интел рекомендуют по depth buffer'у на кадр?
Suslik
> необходимо 2 копии рендертаргетов вроде буфера глубины
не всегда.
один рендертаргет отображается. один рендертаргет ждет vsync для отображения (вертикальной синхронизации). один рендертаргет рендерится из команд буферов
Тема в архиве.