Обработка, выполняемая параллельно на графическом процессоре, может использовать язык шейдинга, называемый оригинальным 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. Основные этапы (от примитивов до функции фрагмента) следующие:
- Группа вершин примитивов, которые представляют собой базовые фигуры, состоящие из вершин, таких как точки, линии, треугольники и т. Д., Передаются в вершинный шейдер.
- Вершинный шейдер выполняет такие вычисления, как преобразование координат. Выходная группа вершин передается в растеризацию.
- Растеризация растеризует вершины и передает растровые данные во фрагментный шейдер.
- Фрагментный шейдер определяет цвет каждого пикселя.
Функция вершины и функция фрагмента подробно описаны в разделе Функция.
Металлические системы координат
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
: на него нельзя ссылаться из других цепочек.