Организация команды и модель выполнения
В Металлической архитектуре, MTLDevice
протокол определяет интерфейс, представляющий единственный GPU. MTLDevice
методы поддержки протоколов для опроса свойств устройства, для создания других специфичных для устройства объектов, таких как буферы и текстуры, и для кодирования и организации очередей представляют и вычисляют команды, которые будут представлены GPU для выполнения.
Очередь команды состоит из очереди буферов команд, и очередь команды организует порядок выполнения тех буферов команд. Буфер команд содержит закодированные команды, предназначающиеся для выполнения на определенном устройстве. Кодер команды добавляет рендеринг, вычисления и блитирование команд на буфер команд, и те буферы команд в конечном счете фиксируются для выполнения на устройстве.
MTLCommandQueue
протокол определяет интерфейс для очередей команды, прежде всего поддерживая методы для создания объектов буфера команд. MTLCommandBuffer
протокол определяет интерфейс для буферов команд и поддерживает методы для создания кодеров команды, буферов команд постановки в очередь для выполнения, проверяя состояние и другие операции. MTLCommandBuffer
поддержка протоколов следующие типы кодера команды, которые являются интерфейсами для кодирования различных видов рабочих нагрузок GPU в буфер команд:
MTLRenderCommandEncoder
протокол кодирует графические (3D) команды рендеринга для единственной передачи рендеринга.MTLComputeCommandEncoder
протокол кодирует параллельные данным рабочие нагрузки вычисления.MTLBlitCommandEncoder
протокол кодирует простые операции копии между буферами и текстурами, а также служебным операциям нравится, множественно отображают генерацию.
В любом моменте времени только единственный кодер команды может быть активным и добавить команды в буфер команд. Каждый кодер команды должен быть закончен, прежде чем другой кодер команды может быть создан для использования с тем же буфером команд. Одно исключение к “одному активному кодеру команды для каждого буфера команд” правило MTLParallelRenderCommandEncoder
протокол, обсужденный в Кодировании Единственной Передачи Рендеринга Используя Многократные Потоки.
Как только все кодирование завершается, Вы фиксируете MTLCommandBuffer
сам объект, отмечающий буфер команд как готовый к выполнению GPU. MTLCommandQueue
протокол управляет когда команды в зафиксированном MTLCommandBuffer
объект выполняется относительно другого MTLCommandBuffer
объекты, которые уже находятся в очереди команды.
Рисунок 2-1 показывает, как очередь команды, буфер команд и объекты кодера команды тесно связаны. Каждый столбец компонентов наверху схемы (буфер, текстура, сэмплер, глубина и состояние шаблона, конвейерное состояние) представляет ресурсы и состояние, которые являются определенными для определенного кодера команды.
Объект устройства представляет GPU
A MTLDevice
объект представляет GPU, который может выполнить команды. MTLDevice
протокол имеет методы, чтобы создать новые очереди команды, выделить буферы из памяти, создать текстуры и сделать запросы о возможностях устройства. Для получения предпочтительного системного устройства системы в системе вызовите MTLCreateSystemDefaultDevice
функция.
Переходные и непереходные объекты в металле
В то время как другие являются более дорогими и могут продержаться в течение длительного времени, возможно для времени жизни приложения, некоторые объекты в Металле разработаны, чтобы быть переходными и чрезвычайно легкими.
Буфер команд и объекты кодера команды являются переходными и разработаны для единственного использования. Они очень недороги, чтобы выделить и освободить, таким образом, их возврат методов создания автовыпустил объекты.
Следующие объекты не являются переходными. Снова используйте эти объекты в производительности чувствительный код и избегите создавать их неоднократно.
Очереди команды
Буферы данных
Текстуры
Состояния сэмплера
Библиотеки
Вычислите состояния
Конвейерные состояния рендеринга
Состояния глубины/шаблона
Очередь команды
Очередь команды принимает упорядоченный список буферов команд, которые выполнит GPU. Все буферы команд, отправленные единственной очереди, как гарантируют, выполнятся в порядке, в котором ставились в очередь буферы команд. В целом очереди команды ориентированы на многопотоковое исполнение и позволяют многократным активным буферам команд быть закодированными одновременно.
Для создания очереди команды вызовите любого newCommandQueue
метод или newCommandQueueWithMaxCommandBufferCount:
метод a MTLDevice
объект. В целом очереди команды, как ожидают, будут долгосрочны, таким образом, они не должны будут быть неоднократно созданы и уничтожаться.
Буфер команд
Буфер команд хранит закодированные команды, пока буфер не фиксируется для выполнения GPU. Единственный буфер команд может содержать много различных видов закодированных команд, в зависимости от числа и типа кодеров, использующихся для создания его. В типовом приложении весь кадр рендеринга кодируется в единственный буфер команд, даже если рендеринг того кадра включает многократные передачи рендеринга, вычислите функции обработки или блитируйте операции.
Буферы команд являются переходными объектами единственного использования и не поддерживают повторное использование. Как только буфер команд фиксировался для выполнения, единственные допустимые операции должны ожидать буфера команд, который будет запланирован или завершен — через синхронные вызовы или блоки обработчика, обсужденные в Регистрирующихся Блоках Обработчика для Выполнения Буфера команд — и проверит состояние выполнения буфера команд.
Буферы команд также представляют единственную независимо допускающую отслеживание единицу работы приложением, и они определяют границы когерентности, установленные Металлической моделью памяти, как детализировано в Объектах Ресурса: Буферы и Текстуры.
Создание буфера команд
Создать a MTLCommandBuffer
объект, вызовите commandBuffer
метод MTLCommandQueue
. A MTLCommandBuffer
объект может только фиксироваться в MTLCommandQueue
возразите, что создал его.
Буферы команд, создаваемые commandBuffer
метод сохраняет данные, которые необходимы для выполнения. Для определенных сценариев, где Вы содержите сохранение к этим объектам в другом месте на время выполнения a MTLCommandBuffer
объект, можно вместо этого создать буфер команд путем вызова commandBufferWithUnretainedReferences
метод MTLCommandQueue
. Используйте commandBufferWithUnretainedReferences
метод только для чрезвычайно критических по отношению к производительности приложений, которые могут гарантировать, что решающие объекты имеют ссылки в другом месте в приложении до выполнения буфера команд, завершается. Иначе, объект, больше не имеющий другие ссылки, может быть преждевременно выпущен, и результаты выполнения буфера команд не определены.
Выполнение команд
MTLCommandBuffer
протокол использует следующие методы для установления порядка выполнения буферов команд в очереди команды. Буфер команд не начинает выполнение, пока это не фиксируется. После того, как фиксировавший, буферы команд выполняются в порядке, в котором они ставились в очередь.
enqueue
метод резервирует место для буфера команд на очереди команды, но не фиксирует буфера команд для выполнения. Когда этот буфер команд в конечном счете фиксируется, он выполняется после любых ранее ставивших в очередь буферов команд в связанной очереди команды.commit
метод заставляет буфер команд выполняться как можно скорее, но после того, как фиксируются любые ранее ставившие в очередь буферы команд в той же очереди команды. Если буфер команд ранее не ставился в очередь,commit
делает подразумеваемоеenqueue
вызвать.
Для примера использования enqueue
с многократными потоками посмотрите Многократные Потоки, Буферы команд и Кодеры Команды.
Регистрация блоков обработчика для выполнения буфера команд
MTLCommandBuffer
методы упомянули ниже выполнение команды контроля. Запланированные и завершенные обработчики вызываются в порядке выполнения на неопределенном потоке. Любой код, который Вы выполняете в этих обработчиках, должен завершиться быстро; если дорогая или блокирующая работа должна быть выполнена, задержите ту работу к другому потоку.
addScheduledHandler:
метод регистрирует блок кода, который вызовут, когда планируется буфер команд. Буфер команд считают запланированным когда любые зависимости между работой, представленной другимMTLCommandBuffer
объекты или другой APIs в системе удовлетворены. Можно зарегистрировать многократные запланированные обработчики для буфера команд.waitUntilScheduled
метод синхронно ожидает и возвращается после того, как буфер команд планируется и все обработчики, зарегистрированныеaddScheduledHandler:
метод завершается.addCompletedHandler:
метод регистрирует блок кода, который сразу вызовут после того, как устройство завершит выполнение буфера команд. Можно зарегистрировать многократные завершенные обработчики для буфера команд.waitUntilCompleted
метод синхронно ожидает и возвращается после того, как устройство завершило выполнение буфера команд и всех обработчиков, зарегистрированныхaddCompletedHandler:
метод возвратился.
presentDrawable:
метод является особым случаем завершенного обработчика. Этот удобный метод представляет содержание визуализуемого ресурса (a CAMetalDrawable
объект), когда планируется буфер команд. Для получения дополнительной информации о presentDrawable:
метод, посмотрите Интеграцию с Базовой Анимацией: CAMetalLayer.
Контроль состояния выполнения буфера команд
Только для чтения status
свойство содержит a MTLCommandBufferStatus
перечисление значений, перечисленное в Command Buffer Status Codes
это отражает текущий этап планирования во времени жизни этого буфера команд.
Если выполнение заканчивается успешно, значение только для чтения error
свойство nil
. Если выполнение перестало работать, то status
установлен в MTLCommandBufferStatusError
, и error
свойство может содержать значение, перечисленное в Command Buffer Error Codes
это указывает причину отказа.
Кодер команды
Кодер команды является временным объектом, который Вы используете один раз для записи команд и состояния в единственный буфер команд в формате, который может выполнить GPU. Много методов объекта кодера команды добавляют команды для буфера команд. В то время как кодер команды активен, он имеет исключительное право добавить команды для своего буфера команд. Как только Вы заканчиваете кодировать команды, вызовите endEncoding
метод. Для записи дальнейших команд создайте новый кодер команды.
Создание объекта кодера команды
Becasuse кодер команды добавляет команды в определенный буфер команд, Вы создаете кодер команды путем запроса один от MTLCommandBuffer
объект Вы хотите использовать его с. Используйте следующий MTLCommandBuffer
методы для создания кодеров команды каждого типа:
renderCommandEncoderWithDescriptor:
метод создает aMTLRenderCommandEncoder
объект для рендеринга графики к присоединению в aMTLRenderPassDescriptor
.computeCommandEncoder
метод создает aMTLComputeCommandEncoder
объект для параллельных данным вычислений.blitCommandEncoder
метод создает aMTLBlitCommandEncoder
объект для операций памяти.parallelRenderCommandEncoderWithDescriptor:
метод создает aMTLParallelRenderCommandEncoder
объект, включающий несколькоMTLRenderCommandEncoder
объекты работать на различных потоках при тихом рендеринге к присоединению, указанному в совместно используемомMTLRenderPassDescriptor
.
Кодер команды рендеринга
Графический рендеринг может быть описан с точки зрения передачи рендеринга. A MTLRenderCommandEncoder
объект представляет состояние рендеринга и команды рисования, связанные с единственной передачей рендеринга. A MTLRenderCommandEncoder
требует связанного MTLRenderPassDescriptor
(описанный в Создании Дескриптора Передачи Рендеринга), который включает цвет, глубину и присоединения шаблона, служащие местами назначения для рендеринга команд. MTLRenderCommandEncoder
имеет методы к:
Укажите графические ресурсы, такие как буфер и текстурируйте объекты, содержащие вершину, фрагмент, или текстурирующие данные изображения
Укажите a
MTLRenderPipelineState
объект, содержащий скомпилированное состояние рендеринга, включая программы построения теней фрагмента и вершинуУкажите состояние стандартной функции, включая область просмотра, треугольный режим заливки, разрежьте ножницами прямоугольник, глубину и получите с помощью шаблона тесты и другие значения
Нарисуйте 3D примитивы
Для получения дальнейшей информации о MTLRenderCommandEncoder
протокол, посмотрите Графический Рендеринг: Кодер Команды Рендеринга.
Вычислите кодер команды
Для параллельных вычислений данных, MTLComputeCommandEncoder
протокол обеспечивает методы для кодирования команд в буфере команд, который может указать вычислить функцию и ее параметры (например, текстура, буфер и состояние сэмплера) и диспетчеризировать вычислить функцию для выполнения. Для создания вычислить объекта кодера команды используйте computeCommandEncoder
метод MTLCommandBuffer
. Для получения дальнейшей информации о MTLComputeCommandEncoder
методы и свойства, посмотрите, что Параллель данных Вычисляет Обработку: Вычислите Кодер Команды.
Кодер команды копирования битового массива
MTLBlitCommandEncoder
протокол имеет методы, добавляющие команды для операций копирования в памяти между буферами (MTLBuffer
) и текстуры (MTLTexture
). MTLBlitCommandEncoder
протокол также обеспечивает методы для заполнения текстур сплошным цветом, и генерировать множественно отображается. Для создания объекта кодера команды копирования битового массива используйте blitCommandEncoder
метод MTLCommandBuffer
. Для получения дальнейшей информации о MTLBlitCommandEncoder
методы и свойства, посмотрите Операции Буфера и Текстуры: Кодер Команды Копирования битового массива.
Многократные потоки, буферы команд и кодеры команды
Большинство приложений использует единственный поток для кодирования команд рендеринга для единственного кадра в единственном буфере команд. В конце каждого кадра Вы фиксируете буфер команд, который оба расписания и начинает выполнение команды.
Если Вы хотите параллелизировать кодирование буфера команд, то можно создать многократные буферы команд одновременно, и кодировать каждому с отдельным потоком. Если Вы знаете заранее, в каком порядке буфер команд должен выполниться, то enqueue
метод MTLCommandBuffer
может объявить порядок выполнения в очереди команды, не будучи должен ожидать команд, которые будут кодироваться и фиксироваться. Иначе, когда буфер команд фиксируется, он присваивается место в очереди команды после любых ранее ставивших в очередь буферов команд.
Во время только один поток ЦП может получить доступ к буферу команд. Многопоточные приложения могут использовать один поток на буфер команд для создания многократных буферов команд параллельно.
Рисунок 2-2 показывает пример с тремя потоками. Каждый поток имеет свой собственный буфер команд. Для каждого потока один кодер команды за один раз имеет доступ к своему связанному буферу команд. Рисунок 2-2 также показывает каждому получению буфера команд команды от различных кодеров команды. Когда Вы закончите кодировать, вызовите endEncoding
метод кодера команды и новый объект кодера команды могут тогда начать кодировать команды к буферу команд.
A MTLParallelRenderCommandEncoder
объект позволяет единственной передаче рендеринга быть разбитой через многократные кодеры команды и присвоенной разделить потоки. Для получения дополнительной информации о MTLParallelRenderCommandEncoder
, посмотрите Кодирование Единственной Передачи Рендеринга Используя Многократные Потоки.