Когда использовать несколько MTLRenderCommandEncoders для выполнения рендеринга металла? - PullRequest
1 голос
/ 03 февраля 2020

Я изучаю Metal, и есть концептуальный вопрос, который я пытаюсь обернуть вокруг себя: на каком уровне именно мой код должен обрабатывать последовательные операции рисования, которые требуют различных состояний конвейера? Насколько я понимаю (из таких ответов: { ссылка }), я могу использовать один MTLRenderCommandEncoder и изменить его состояние конвейера, используемый им буфер вершин и т. Д. c. Между вызовами drawPrimitives:, и состояние датчика, которое было текущим на момент каждого вызова drawPrimitives:, будет сохранено. Ну и отлично. Но также кажется, что дизайн Metal таков, что можно создать несколько MTLRenderCommandEncoder экземпляров и использовать их для последовательного выброса пакетов команд в MTLCommandBuffer. Учитывая, что первый работает - используя один MTLRenderCommandEncoder и изменяя его состояние - зачем делать второй? При каких обстоятельствах правильно делать первое, и при каких обстоятельствах необходимо делать второе? Каков пример ситуации, когда последнее было бы необходимо / уместно?

Если это имеет значение, я работаю над приложением macOS, используя Objective- C. Спасибо.

Ответы [ 2 ]

3 голосов
/ 03 февраля 2020

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

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

Многие различные методы, включая отображение теней и эффекты постобработки, такие как Блум, требуют нескольких проходов. Поскольку вы не можете изменить вложения в середине прохода, создание нового кодировщика является единственным способом кодирования нескольких проходов в кадре.

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

2 голосов
/ 03 февраля 2020

В дополнение к ответу Уоррена, еще один способ взглянуть на вопрос - изучить API. Ряд металлических объектов создается из дескрипторов. Свойства дескриптора в момент создания объекта определяют его срок службы. Это те аспекты объекта, которые нельзя изменить после создания.

В отличие от этого, объект будет иметь различные методы установки для изменения других свойств в течение срока его службы.

Для кодировщика команды рендеринга свойства, которые фиксированы для его времени жизни, являются теми, которые определены MTLRenderPassDescriptor, используемым для его создания. Если вы хотите выполнить рендеринг с другими значениями для любого из этих свойств, единственный способ сделать это - создать новый кодировщик из другого дескриптора. С другой стороны, если вы можете делать все, что вам нужно / нужно делать, используя методы установки кодировщика, тогда вам не нужен новый кодировщик.

...