Обработка, выполняемая параллельно на графическом процессоре, может использовать язык шейдинга, называемый оригинальным Metal Shading Language (MSL) компании Metal.

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

Расширение имени файла MSL

Расширение имени файла MSL - .metal. Вы можете создать новый металлический файл, используя шаблон металлического файла в Xcode.

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

Встроенная библиотека по умолчанию (default.metallib) добавляется в пакет приложения. Вы можете получить библиотеку по умолчанию следующим образом:

let library = device.makeDefaultLibrary()
// makeDefaultLibrary() is equivalent to:
let filePath = Bundle.main.path(forResource: "default", ofType: "metallib")!
let library = try! device.makeLibrary(filepath: filePath)

Металлические файлы можно создать вручную следующим образом: (Подробнее см. 【Создание библиотеки с помощью инструментов командной строки Metal】)

xcrun -sdk macosx metal -c MyLibrary.metal -o MyLibrary.air
xcrun -sdk macosx metallib MyLibrary.air -o MyLibrary.metallib

Конвейер рендеринга металлической графики

Конвейер рендеринга обрабатывает команды рисования и записывает данные в целевые объекты прохода рендеринга. Конвейер рендеринга состоит из множества этапов, некоторые из которых запрограммированы с использованием шейдеров. Вершинная функция и Функция фрагмента в конвейере рендеринга должны быть написаны MSL. Основные этапы (от примитивов до функции фрагмента) следующие:

  1. Группа вершин примитивов, которые представляют собой базовые фигуры, состоящие из вершин, таких как точки, линии, треугольники и т. Д., Передаются в вершинный шейдер.
  2. Вершинный шейдер выполняет такие вычисления, как преобразование координат. Выходная группа вершин передается в растеризацию.
  3. Растеризация растеризует вершины и передает растровые данные во фрагментный шейдер.
  4. Фрагментный шейдер определяет цвет каждого пикселя.

Функция вершины и функция фрагмента подробно описаны в разделе Функция.

Металлические системы координат

Metal определяет несколько стандартных систем координат для представления преобразованных графических данных на разных этапах конвейера рендеринга.

Координаты пространства клипа

Вершинный шейдер генерирует позиции в координатах пространства отсечения. Трехмерная точка в координатах пространства клипа задается четырехмерным однородным вектором (x, y, z, w).

Metal делит значения _5 _, _ 6_ и z на w, чтобы преобразовать координаты пространства клипа в нормализованные координаты устройства. это называется перспективным делением. Следующее равенство определяет отношение между нормализованными координатами устройства и координатами зажима.

Нормализованные координаты устройства (NDC)

(x, y, z), обозначенный нормализованной системой координат устройства, находится в диапазоне от -1 до 1. Положительные значения z указывают в сторону от камеры. NDC использует левостороннюю систему координат и отображает позиции в области просмотра.

Координаты области просмотра

Этап растеризации преобразует NDC в координаты области просмотра. Область просмотра - это область, отображаемая на экране. Координаты (x,y) в этом пространстве измеряются в пикселях, где начало координат находится в верхнем левом углу области просмотра, а положительные значения идут вправо и вниз.

Координаты текстуры

Координаты текстуры указывают положения с плавающей запятой, которые отображают местоположения на изображении текстуры в местоположения на геометрической поверхности, представленные как 2D- или 3D-векторы. Координаты текстуры также можно указать с помощью нормализованных координат текстуры. Для 2D-текстур нормализованные координаты текстуры - это значения от 0,0 до 1,0 как по оси x, так и по оси y.

Функция

Metal поддерживает следующие атрибуты функции, определяющие, как использовать функцию: вершина, фрагмент и ядро ​​. Эти атрибуты функции используются в начале функции перед ее возвращаемым типом.

vertex void my_vertex_func(…) {…}
fragment void my_fragment_func(…) {…}
kernel void my_kernel(…) {…}

графическая функция

  • вершина: Metal выполняет вершинную функцию для каждой вершины в потоке вершин и генерирует выходные данные для каждой вершины.
  • фрагмент: Metal выполняет функцию фрагмента для каждого фрагмента в потоке фрагментов и связанных с ними данных и генерирует выходные данные для каждого фрагмента.

функция вычисления

  • Ядро. Вычислительная функция, называемая «ядром», - это функция параллельных данных, которая выполняется в 1-, 2- или трехмерной сетке.

Атрибут имени хоста

Начиная с Metal 2.2, атрибут [[hostname(name)]] может использоваться с функциями вершины, фрагмента и ядра для переопределения имени функции по умолчанию. Две разные функции не могут иметь одно и то же имя хоста, иначе компилятор вызовет ошибку времени компиляции.

[[host_name("foo")]] kernel void foo() {} //Metal API name is foo [[host_name("foo2")]] kernel void foo() {} // Metal API name is foo2

Шаблонные функции

Начиная с Metal 2.2, теперь можно определять C ++ подобные шаблоны для вершин, фрагментов и функций ядра. Поскольку они не могут быть вызваны непосредственно в шейдере, пользователи должны явно создать экземпляр шаблона, чтобы компилятор выдал код для данной специализации.

template<typename T>
kernel void bar(device T *x) { … } 
// Explicit specialization of `bar` with [T = int] 
template kernel void bar(device int *);

Квалификатор атрибута аргументов и переменных

Квалификатор атрибута для аргументов и значений функции имеет следующий вид:

  • [[position]]: Тип float4 и указывает координаты (x, y, z, w).
  • [[vertex_id]]: ushort или uint, чтобы указать индекс вершины.
  • [[stage_in]]: используется в качестве аргумента фрагментного шейдера и содержит данные фрагмента, которые представляют собой структуру, используемую для рисования одного пикселя дисплея.
  • [[buffer(index)]]: он определяет расположение буфера для аргументов функции. Вершинная функция может считывать входные данные для каждой вершины, индексируя буфер (буферы), переданный в качестве аргументов функции вершины, используя идентификаторы вершины и экземпляра.
  • [[texture(index)]]: текстуры (включая буферы текстур).
  • [[sampler(index)]]: Примеры, определяющие, как получить доступ к данным текстуры.
  • [[threadpositionin_grid]]: Положение резьбы в сетке.

Квалификаторы адресного пространства

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

device и constant можно указать в графической функции.

  • device: чтение / запись
  • constant: только для чтения

threadgroup и thread можно указать в функции вычисления.

  • threadgroup: весь поток в группе потоков является общим.
  • thread: на него нельзя ссылаться из других цепочек.

использованная литература