Привет всем, в эфире Асахи Лина!✨

marcan попросил меня написать статью о M1 GPU, и вот она готова ~! Это был долгий проект, растянувшийся на несколько месяцев, и было о чём поведать, так что, надеюсь, вам понравится!

Что такое GPU

Пожалуй, вы знаете, что такое GPU, но известно ли вам, как он работает под капотом? Давайте посмотрим! Почти у всех современных GPU одни и те же основные компоненты:

  • Набор шейдерных ядер, обрабатывающих треугольники (вершинные данные) и пиксели (фрагментные данные), выполняя программы, определяемые пользователем. Они используют разные кастомные наборы инструкций для каждого GPU!

  • Блоки растеризациисемплеры текстур, блоки вывода рендеринга, а также другие элементы, работающие вместе с шейдерами для перегона треугольников из приложения в пиксели на экране. Точный принцип работы этих механизмов отличается от GPU к GPU!

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

  • Блок управления памятью (MMU), отвечающий за ограничение доступа к тем областям памяти, что принадлежат конкретному приложению, использующему GPU. Поэтому различные приложения не могут друг друга обвалить или вмешаться в работу друг друга.

(Это очень упрощённая картина, на самом деле в работе участвует ещё множество элементов, варьирующихся от GPU к GPU, но выше я перечислила самые важные компоненты!)

Чтобы при обращении со всеми этими «шестерёнками» соблюдалась разумная безопасность, драйверы современных GPU делятся на две группы: драйверы пользовательского пространства и драйверы ядра. В данном случае та часть, что относится к пользовательскому пространству, отвечает за компиляцию шейдерных программ и трансляцию вызовов API (как при работе с OpenGL или Vulkan) в списки конкретных команд, которые командный процессор будет применять при рендеринге сцены. Пространство ядра, в свою очередь, отвечает за управление блоками MMU и операции выделения/высвобождения памяти от разных приложений, а также решает, как и когда отправлять различные команды в процессор, их обрабатывающий. Таким образом работают все современные драйверы для  GPU во всех крупных операционных системах!

Между драйвером пользовательского пространства и драйвером ядра обычно расположен своего рода кастомный API, настраиваемый для каждого семейства GPU. Обычно эти API отличаются для каждого драйвера! В Linux такие интерфейсы называются UAPI, но в каждой ОС есть подобная сущность. Именно этот UAPI позволяет пользовательскому пространству запрашивать у ядра выделение/высвобождение памяти и отправлять в GPU списки команд.

Таким образом, чтобы подружить M1 GPU с Asahi Linux, требуются две составляющие: драйвер ядра и драйвер пользовательского пространства! ????

Алисса подключается к проекту

C самого начала, ещё в 2021 году, когда история Asahi Linux только начиналась, Алисса Розенцвейг присоединилась к проекту и приступила к обратной разработке M1 GPU. Вместе с Дугаллом Джонсоном (сосредоточившимся на документировании архитектуры шейдеров GPU), она начала обратную разработку со всех компонентов пользовательского пространства, в том числе, шейдеров и всех структур списка команд, необходимых для налаживания рендеринга. Это огромный кусок работы, но менее чем через месяц она уже отрисовывала свой первый треугольник! Она чудо. Если вы ещё не читали серию её статей по разделке M1 GPU, обязательно зайдите к ней на сайт и взгляните! ✨✨

Но подождите, как же она может работать над драйвером пользовательского пространства, не затрагивая при этом драйвера ядра? Легко, ведь она делала это на macOS! Алисса достаточно преуспела в обратной разработке GPU-драйвера для UAPI под macOS и научилась выделять память, а также передавать собственные команды на GPU. Таким образом, она смогла заниматься разработкой драйвера для пользовательского пространства, не беспокоясь о том, что там происходит в ядре. Это так круто! Она принялась писать драйвер M1 GPU OpenGL для Mesa — это стек для Linux, позволяющий обрабатывать графику в пользовательском пространстве, а спустя всего пару месяцев она уже userspace прошла 75% тестов на совместимость с OpenGL ES 2, всё под macOS!

Ранее в этом году она успела так продвинуться в работе, что уже гоняла игры на целиком опенсорсном стеке Mesa OpenGL, который работает поверх драйвера ядра Apple под macOS! Но аналогичного драйвера ядра Linux на тот момент всё ещё не существовало… и пришло время это исправить! ✨

Таинственная прошивка GPU

В апреле текущего года я решила постепенно разобраться, как написать драйвер ядра для M1 GPU! К тому моменту, как я приступила к работе, Скотт Мэнзелл уже успел предварительно расследовать эту проблему… и уже было ясно, что перед нами не обычный GPU. Первую пару месяцев я писала и улучшала трассировщик гипервизора m1n1 для GPU и то, что я обнаружила, показалось мне очень, очень необычным для мира GPU в целом.

Как правило, драйвер GPU отвечает за такие операции, как планирование работы и расстановка приоритетов для задач в  GPU, а также за вытеснение тех заданий, чьё выполнение чрезмерно затягивается; таким образом, гарантируется, что приложения честно используют ЦП. Иногда драйвер отвечает за управление питанием, а в других случаях это делается через выделенную прошивку, работающую на сопроцессоре управления питанием. Бывает и так, что предусмотрена отдельная прошивка, в которой реализованы определённые детали обработки команд, но она, как правило, не видна драйверу ядра. В конце концов, особенно в сравнительно простых GPU «для мобильных устройств», например в  ARM Mali, предусматривается конкретный аппаратный интерфейс, заставляющий GPU отображать что-либо. Обычно этот интерфейс весьма прост: в нём есть блок управления памятью (MMU), действующий как стандартный MMU или IOMMU в ЦП, а также процессор команд. Процессор команд принимает указатели, направленные непосредственно в командные буферы пользовательского пространства, например, в те или иные регистры или в кольцевой буфер. Таким образом, драйверу ядра почти не остаётся работы, кроме как управлять памятью и назначать работу в GPU, а подсистема непосредственного управления рендерингом (DRM) в ядре Linux и так предоставляет массу вспомогательных функций, упрощающих написание драйверов! Здесь есть некоторые хитрые аспекты, например, вытеснение, но они не принципиальны, если нужно заставить GPU работать с совершенно новым драйвером. Однако M1 GPU устроен иначе…

У этого GPU, как и у других элементов чипа M1, есть сопроцессор под названием “ASC”. На нём работает прошивка Apple, и он управляет GPU. Этот сопроцессор – полноценный ЦП ARM64, работающий на проприетарной операционной системе реального времени от Apple, она называется RTKit… и он отвечает за всё! Он управляет питанием, планированием и вытеснением команд, восстановлением после отказов и даже счётчиками производительности, статистикой и такими вещами как измерение температуры! На самом деле, драйвер ядра macOS вообще не обменивается информацией с аппаратной частью GPU. Вся коммуникация с GPU осуществляется через прошивку, при этом используются хранимые в памяти разделяемые структуры данных, сообщающие процессору, что делать. И таких структур много…

  • Данные инициализации применяются для того, чтобы сконфигурировать настройки управления питанием в прошивке, а также другие глобальные конфигурационные данные GPU, в том числе, таблицы преобразования цветовых пространств — а вдруг понадобится?! В этих структурах данных почти по 1000 полей, и мы пока даже не все их охарактеризовали!

  • Конвейеры доставки — это кольцевой буфер, применяемый для выстраивания очередей задач, стоящих на обработку в этом GPU.

  • Управляющие сообщения для устройств, при помощи которых контролируются глобальные операции, выполняемые в GPU.

  • Сообщения о событиях, которые прошивка отправляет обратно драйверу, если что-нибудь случится (например, завершится выполнение команды — удачно или неудачно).

  • Статистика, логи прошивки и трассировочные сообщения, в которых содержатся данные о состоянии GPU и отладочная информация.

  • Очереди команд — это список всех задач от одного приложения, стоящих в очереди на обработку в GPU.

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

  • Контекстные структуры и другие компоненты, позволяющие прошивке GPU отслеживать происходящее.

  • Команды рендеринга вершин. Они сообщают той части GPU, что занята обработкой вершин и замощением, как обрабатывать команды и шейдеры из пользовательского пространства, чтобы прогонять «вершинную» часть работы в рамках целого прохода визуализации.

  • Команды рендеринга фрагментов. Они сообщают той части GPU, что занята обработкой фрагментов и растрированием, как отображать тайловые вершинные данные, поступающие в кадровый буфер после фактической обработки вершин.

На самом деле, всё ещё сложнее! Команды рендеринга вершин и фрагментов — это очень запутанные структуры, внутри которых вложено множество других структур. Каждая такая команда содержит указатель на «микропоследовательность» более мелких команд, интерпретируемых прошивкой GPU — представьте себе, например, собственный виртуальный ЦП! Как правило, при помощи этих команд задаётся проход визуализации, далее процессор дожидается, пока он завершится, и производит очистку… но здесь поддерживаются и такие вещи, как команды по расстановке временных меток, и даже циклы и арифметика! Безумие! И все эти структуры нужно наполнять подробнейшей информацией о том, что должно отображаться: в частности, записывать сюда указатели на буферы глубины и трафаретные буферы, размер кадрового буфера. Здесь нужно указывать, включена ли MSAA (множественная выборка сглаживания) и как она сконфигурирована, ставить указатели на конкретные вспомогательные шейдерные программы и на многое другое!

Фактически, прошивка GPU странным образом соотносится с блоками управления памятью GPU. Она использует те же самые таблицы страниц! Прошивка буквально берёт тот же самый базовый указатель на таблицу страниц, который используется блоком управления памятью GPU и конфигурирует его как свою таблицу страниц для ARM64. Поэтому память GPU — это память прошивки! Это дичь! Здесь есть разделяемое «ядерное» адресное пространство (подобное адресному пространству ядра в Linux), и именно это пространство прошивка использует для себя, а также (в основном) для коммуникации с драйвером. Далее есть несколько буферов, которые совместно используются прошивкой и аппаратным обеспечением GPU как таковым, а также имеют адреса «пользовательского пространства», распределённые по отдельным адресным пространствам для каждого приложения, использующего GPU.

Так можно ли вынести всю эту сложность в пользовательское пространство и именно там организовать настройку всех этих команд, отвечающих за рендеринг вершин и фрагментов? Нетушки! Поскольку все эти структуры лежат в разделяемом адресном пространстве ядра вместе с самой прошивкой и оперируют целым роем указателей, направленных друг на друга, они не разграничены между отдельными процессами, использующими GPU! Поэтому нельзя предоставить приложениям непосредственный доступ к ним, ведь они могут нарушить друг другу рендеринг. По всем этим причинам Алисса отыскала все эти детали рендеринга в  macOS UAPI…

Драйверы для GPU на Python?!

Поскольку организовать правильную работу всех этих структур критически важно, чтобы GPU работал, а прошивка не отказывала, мне требовалось изыскать способ, как бы с ними быстро поэкспериментировать, не отвлекаясь от обратной разработки. К счастью, в проекте Asahi Linux уже имелся инструмент для этой цели: фреймворк m1n1 для Python! Поскольку в то время я уже писала трассировщик GPU для гипервизора m1n1 и заполняла определения структур в Python, я решила просто поставить задачу с ног на голову и взяться за написание драйвера ядра GPU на Python. Для этого я собиралась воспользоваться всё теми же определениями структур. Python отлично для этого подходит, поскольку в нём очень легко организовать перебор! Ещё лучше, что я уже могу общаться с базовыми протоколами RTKit и  разбирать логи отказов. Кроме того, я доработала предназначенные для этого инструменты, чтобы точно видеть, что именно происходит с прошивкой, когда она отказывает. Чтобы всё это сделать, просто запускаем скрипты на той машине, где ведём разработку. Машина для разработки подключается к машине M1 по USB, поэтому её можно с лёгкостью перезагрузить, как только вам захочется что-нибудь протестировать. При этом цикл тестирования очень быстрый!

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

????????????????????????????????????????????????????????????????
????????????????????????????????????????????????????????????????
????????????????????????????????????????????????????????????????
????????????????????????????????????????????????????????????????
????????????????????????????????????????????????????????????????
????????????????????????????????????????????????????????????????
????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????? 

pic.twitter.com/dz68hvalLv

— Asahi Linya / 朝日りにゃ〜 // @lina@vt.social (@LinaAsahi) June 1, 2022

Это была просто наскоро сварганенная демка, но… прежде, чем приступать к разработке драйвера ядра Linux, я хотела убедиться, что действительно хорошо во всём разобралась, и только затем как следует проектировать драйвер. Просто отобразить кадр не составляет труда, но я хотела добиться, чтобы отображалось множество кадров, а также протестировать такие вещи, как конкурентность и вытеснение. Так что мне в самом деле требовался настоящий «драйвер ядра», но на Python его же не сделать, так?!

Оказывается, что у Mesa есть библиотека под названием drm-shim. Она подменяет интерфейс ядра Linux DRM, ставя на его место формальную реализацию, обрабатываемую в пользовательском пространстве. Обычно используется для таких вещей, как непрерывная интеграция шейдеров, но подходит и для более авантюрных вещей, вот, например… что, если вставить в drm_shim интерпретатор Python, и вызывать из неё весь тот драйвер-прототип, который я напишу на Python?

Могла бы я запускать Inochi2D поверх Mesa, вместе с Алиссиным драйвером Mesa M1 для GPU, работающим поверх drm-shim? А в drm_shim работал бы встроенный интерпретатор Python, посылавший бы команды моему драйверу-прототипу, написанному на Python. Этот драйвер был бы разработан на основе фреймворка m1n1 и общался бы по USB с реальной машиной M1, пересылая туда-сюда все данные. Таким образом, я могла бы сама управлять прошивкой GPU и рендерингом? Насколько смехотворно бы всё получилось?

Настолько, что даже работает! ✨

????????????????????????????????
✨✨ФУРЫЧИТ!!!! ✨✨
????????????????????????????????

Я сама себя отобразила на M1 GPU, воспользовавшись опенсорсным драйвером, который работал как eGPU по USB!!!!!!!!

При помощи m1n1 от @AsahiLinux в исполнении @marcan42 и Ко, а также драйвера mesa от @alyssarzg и моего драйвера ядра, написанного на Python – и этот драйвер управляет @Inochi2D!! ???? pic.twitter.com/xQdfLch64U

— Asahi Linya / 朝日りにゃ〜 // @lina@vt.social (@LinaAsahi) June 17, 2022

Новый язык для ядра Linux

Заставив работать криповый драйверный стек Mesa+Python, я постепенно стала осознавать, как должен работать драйвер ядра в конечном виде, и что он должен делать. А задач у него много! Не просматривается никакого способа жонглировать более чем 100 структурами данных, вовлечёнными в его работу и, если хотя бы что-то пойдёт не так, то всё может сломаться! Прошивка не выполняет вообще никакой проверки исправности (вероятно, ради производительности), и, если наткнётся на какие-нибудь дефектные указатели или данные, то просто аварийно завершится или вслепую затрёт информацию! Хуже того, если откажет прошивка, то единственный способ её восстановить – целиком перезагрузить машину! ????

DRM-драйверы для ядра Linux написаны на C, а C – не тот язык, на котором хотелось бы писать сложное управление структурами данных. Мне пришлось бы вручную отслеживать время жизни каждого объекта GPU, и, если бы я хоть где-нибудь ошиблась, то могла бы спровоцировать спонтанные отказы или даже уязвимости в системе безопасности. Как же мне всё это вытянуть? Слишком много вещей, которые могли бы пойти не так, а C мне вообще не поможет в случае чего!

В довершение всего этого мне также пришлось бы поддерживать сразу много версий прошивки, а Apple не поддерживает стабильность определений структур прошивки от версии к версии! В качестве эксперимента я уже добавила поддержку для второй версии, и в итоге мне пришлось вносить в структуры данных более 100 изменений. В демке с Python это можно было бы сделать при помощи причудливого метапрограммирования, поставив поля структур в зависимость от номера версии… но в С ничего подобного нет. Придётся прибегать к уловкам из разряда «много раз компилировать весь драйвер с разными #define»!

Но на горизонте замаячил новый язык…

Примерно в то же время пошли слухи, будто Rust вскоре официально включат в ядро Linux. В проекте Rust for Linux велась работа над тем, чтобы такая официальная поддержка была добавлена в ближайшие несколько лет, и складывалось впечатление, будто официального мерджа ждать уже недолго. А могу я… написать драйвер для GPU на Rust?

У меня не так много опыта с Rust, но из того, что я читала, сложилось впечатление, будто этот язык гораздо лучше С подходит для написания драйвера GPU! Особенно меня заинтересовали две вещи: поможет ли Rust смоделировать времена жизни структур, применяемых в прошивке GPU (даже притом, что эти структуры связаны с указателями GPU, которые, с точки зрения ЦП, реальными указателями не являются), и можно ли решить проблему множественности версий при помощи макросов Rust.

Итак, прежде, чем переходить непосредственно к разработке ядра, я обратилась за помощью к экспертам по Rust и написала пробный прототип объектной модели GPU, на простом Rust для пользовательского пространства. В сообществе Rust меня приняли супер любезно, а несколько человек за руку провели через все сложности! Что бы я делала без вашей помощи! ❤

Причём создалось впечатление, будто всё должно работать! Но Rust по-прежнему не относится к мейнстримовому Linux… и я попадала на неизведанную территорию, так как ранее никто ничего подобного не делал. Требовался известный азарт… но, чем больше я задумывалась об этом, тем явственнее сердце подсказывало, что путь лежит через Rust. Поболтала на эту тему со специалистами из поддержки Linux DRM и с другими ребятами, и они, как мне показалось, отнеслись к этой идее с энтузиазмом или хотя бы благосклонно, так что …

Я решила попробовать!

Начала Rust

Поскольку мне предстояло создать первый в истории написанный на Rust драйвер ядра Linux для работы с GPU, работа меня ждала большая. Мне нужно было написать не только сам драйвер, но и абстракции Rust для графической подсистемы Linux DRM. Притом, что из Rust можно делать вызовы прямо в функции C, в данном случае не обеспечиваются никакие свойственные Rust гарантии безопасности. Поэтому, чтобы спокойно использовать код C из Rust, сначала нужно написать обёртки, из которых получился бы безопасный Rust-подобный API. Мне пришлось написать почти 1500 строк кода на одни только абстракции, а чтобы спроектировать хорошую и безопасную систему, потребовалось подробно всё продумывать и переписывать!

18 августа я принялась писать драйвер на Rust. Поначалу работа с блоками управления памятью опиралась на код C (частично скопированный из драйвера Panfrost), хотя, позже я решила переписать весь этот код на Rust. В течение нескольких следующих недель я добавила объектную систему Rust GPU, которую ранее прототипировала, а затем повторно реализовала на Rust все прочие части того демо-драйвера, который уже был написан у меня на Python.

Чем больше я работала с Rust, тем сильнее в него влюблялась! Такое ощущение, что сам дизайн Rust ведёт тебя к качественным абстракциям и грамотным вариантам проектирования. Компилятор очень придирчив, но если уж код компилируется, то можно не сомневаться, что этот код будет работать надёжно. Иногда приходилось помучиться, чтобы применяемый мной вариант устроил компилятор, а потом выяснялось, что в спроектированной мной модели в самом деле были фундаментальные проблемы!

Драйвер медленно срастался, и 24 сентября у меня наконец-то был kmscube, чтобы отобразить первый куб при помощи моего новоиспечённого драйвера на Rust!

????????????????????????????????
????????????????????????????????
???? C U B E ????
????????????????????????????????
????????????????????????????????

Работает!!!!

Он не отображается на HDMI, так как что-то не так с kmsro, но он работает!!!! Отображает!!! Вращающийся кубик!!! С моего драйвера для Linux, написанного на Rust!!!!!!!!!

????✨✨✨✨✨✨✨✨✨✨???? pic.twitter.com/8duIAvnG4a

— Asahi Linya / 朝日りにゃ〜 // @lina@vt.social (@LinaAsahi) September 24, 2022

А потом произошло кое-что волшебное.

????????????????????????????????????⚙️

Neverball, Firefox + YouTube и @Inochi2D, сеанс в GNOME Wayland!!!

Всё работает одновременно под Apple M1 Mac Mini с моим драйвером ядра Linux на Rust Linux и с драйвером Mesa для M1 GPU от @alyssarzg!!!

????????????????????????????????????⚙️
▶️https://t.co/g0R1JZI6Pe pic.twitter.com/ek879MVc2D

— Asahi Linya / 朝日りにゃ〜 // @lina@vt.social (@LinaAsahi) September 29, 2022

Всего через несколько дней мне уже удавалось запускать полноценный сеанс для GNOME на ПК!

Rust волшебный!

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

Но всего этого просто… не случилось! Мне всего лишь потребовалось устранить несколько багов в логике, одну проблему в самом ядре кода, управлявшего памятью, после чего всё остальное работало стабильно! Rust поистине волшебный! Безопасность в нём на таком уровне, что спроектированный драйвер гарантированно получится безопасным на уровне потоков и на уровне памяти, если только нет проблем в немногочисленных небезопасных разделах. В самом деле, Rust ведёт вас не только к безопасным, но и просто к хорошим вариантам проектирования.

Разумеется, в коде всегда найдётся несколько небезопасных участков, но, поскольку Rust всегда ориентирует нас на использование безопасных абстракций, не составляет труда держать общую поверхность возникновения возможных багов минимальной. Кое-какие проблемы с безопасностью всё-таки есть! Например, у меня был баг в абстракции для управления памятью DRM, который мог бы привести к такой неприятности: аллокатор будет освобождён ещё до того, как окажется высвобождена вся выделенная им память. Но, поскольку баги такого рода специфичны для конкретного участка кода, обычно они кажутся явными и очевидными (поэтому их находят при аудите или ревью кода). Это вам не трудноуловимые условия гонок и не такие случаи ошибок, которые захватывают весь драйвер. Вы постепенно уменьшаете количество возможных багов, так, что в итоге остаётся беспокоиться о минимальном количестве – всего-то и дел, что продумать конкретные модули кода и участки, релевантные с точки зрения безопасности, каждый в отдельности. Их взаимодействия с прочим кодом можно не учитывать. Это сложно описать, если вы не пробовали Rust, но разница в самом деле огромна!

O, а ещё нужно сказать об обработке ошибок и об очистке. Вся эта коварная обработка ошибок в стиле goto cleanup, которая нужна в C, чтобы прибрать за собой ресурсы, в Rust просто… исчезает. Одно лишь это ценно само по себе. Плюс, вы получаете реальные итераторы, а подсчёт ссылок здесь автоматический! ❤

Просто нравится видеть, как все странные и чреватые ошибками паттерны программирования ядра из C превращаются в красивый код на Rust. ♥

Только посмотрите, ни одного `of_node_put()` где бы то ни было!
Никаких странных макросов итераторов!
Нет `goto err_put_foo`!
Обработка ошибок в один символ!

???? pic.twitter.com/59X0jThkfZ

— Asahi Linya / 朝日りにゃ〜 // @lina@vt.social (@LinaAsahi) October 21, 2022

Объединяем усилия

Когда разработка драйвера ядра легла на верный курс, пришло время скооперироваться с Алиссой и взяться за общее дело! Она, уже не стеснённая необходимостью всё тестировать только на macOS, стала всерьёз улучшать драйвер Mesa! Я ей даже немного помогла ^^.

Мы выступили с совместным докладом на XDC 2022, и на тот момент всю информацию к лекции мы демонстрировали на M1, пользуясь нашими драйверами! С тех пор мы занимались добавлением новых фич, фиксили баги, а также улучшали производительность, каждая со своей стороны. Я добавила поддержку для семейства M1 Pro/Max/Ultra и M2 на стороне ядра, а также многое доработала по внесению дополнительных и более качественных отладочных инструментов. Также улучшила производительность при выделении памяти. Моя коллега методично улучшала соответствие с GL, так что совместимость с OpenGL ES 2.0 уже практически полная, а совместимость с 3.0 превышает 96%! Она также добавила множество новых фич и оптимизаций производительности, и теперь уже можно играть в такие игры, как Xonotic и Quake в качестве 4K!

А поскольку за управление питанием GPU отвечает прошивка, всё это просто работает. Я тестировала Xonotic при 1080p в рамках сеанса GNOME, и заряда батареи хватало более чем на 8 часов! ????

Что насчёт поддержки Vulkan? Не волнуйтесь… над этим работает Ella! ✨✨

VKCUBE на @AsahiLinux !!! pic.twitter.com/a7pMcLurpT

— @ella@tech.lgbt (@EllaStanforth) October 23, 2022

Что дальше?

Нам всё ещё предстоит долгий путь! Тот UAPI, которым мы сейчас пользуемся — это по-прежнему прототип, и остаётся ещё много новых фич, которые требуется добавить или перепроектировать, чтобы в будущем у нас мог поддерживаться полноценный драйвер Vulkan. Поскольку Linux требует, чтобы UAPI оставался стабильным и обратно совместимым от версии к версии (а macOS не требует), это означает, что ещё много месяцев драйвер не попадёт в стабильную ветку, пока мы не будем полнее представлять параметры рендеринга GPU и не реализуем все новые возможности проектирования, требуемые для Vulkan. Производительность актуального UAPI также ограничена… он даже пока не может конкурентно выполнять рендеринг на GPU одновременно с обработкой на ЦП!

Конечно же, остаётся ещё масса работы со стороны пользовательского пространства, нужно улучшать соответствие и производительность, а также добавлять поддержку для новых расширений и возможностей GL! Некоторые возможности, например, замощение и геометрические шейдеры, реализовать очень непросто (так как их требуется частично или полностью эмулировать), поэтому в ближайшей и даже отдалённой перспективе не ждите полной поддержки OpenGL 3.2+.

Но даже с учётом этих ограничений сегодня эти драйверы обеспечивают стабильную работу с программами для ПК, и производительность улучшается из недели в неделю! Wayland сейчас работает на этих машинах восхитительно гладко, точно как на нативной macOS! Xorg тоже работает с учётом некоторых усовершенствований, которые я не так давно внесла в драйвер дисплея, хотя не удивляйтесь возможным проблемам с разрывом изображения и с vsync из-за ограничений Xorg. Wayland – это в самом деле будущее новых платформ! ????

Итак, где всё это можно взять? У нас ещё далеко не всё готово! Прямо сейчас стек драйвера сложно как собирать, так и устанавливать (вам потребуются кастомные сборки m1n1, ядра и mesa), поэтому, пожалуйста, наберитесь терпения! Нам ещё осталось зачистить несколько концов… но, надеемся, мы сможем добавить всё это в Asahi Linux в качестве добровольно подключаемой тестовой сборки ещё до конца текущего года! ✨✨

Если вам интересно следить за моей работой над GPU, подпишитесь на меня в @lina@vt.social или на мой канал на YouTube! Завтра я планирую разбираться, как вычисляется энергопотребление для M1 Pro/Max/Ultra и M2, надеюсь, вы ко мне присоединитесь! ✨

Если хотите поддержать мою работу, то можете задонатить мне в фонд Asahi Linux для marcan на GitHub Sponsors или Patreon, это мне также пригодится! А если вам не терпится увидеть драйвер для Vulkan, посмотрите страницу Эллы на GitHub Sponsors! Алисса сама донатов не принимает, но она будет благодарна, если вы пожертвуете на благотворительность, например, в Software Freedom Conservancy. (Правда, может быть, настанет день, и она разрешит мне купить ей M2… ^^;;)

Комментарии (55)


  1. krabdb
    16.12.2022 04:41
    +7

    Как-то "обратная разработка" попахивает... Что не так с понятным всем "реверс-инжинирингом"?


    1. nochkin
      16.12.2022 05:58
      +19

      Машинный перевод такой бессмысленный и беспощадный. А страдать почему-то надо нам, читателям.


      1. Sivchenko_translate Автор
        16.12.2022 09:12
        -1

        Потрудитесь примеры машинного перевода, желательно со скринами из оригинала и этой статьи


        1. panvartan
          16.12.2022 09:19
          +64

          Потрудитесь примеры машинного перевода

          Похоже, перевод действительно не машинный.


          1. dfgwer
            16.12.2022 13:30

            Уже скоро будем ругаться на ручной перевод.
            И на неиспользование улучшателей стилистики текста.


            1. nochkin
              16.12.2022 19:57

              Если такие "улучшатели" будут корябить глаз, то будем обязательно ругаться. В переводе главное, что бы текст шёл просто и легко усваивался с чаем и печеньками.

              Я рад, что автору этого перевода это не безразлично и он хочет прикладывать усилия для улучшения этого навыка. Это главное.


        1. nochkin
          16.12.2022 09:40
          +29

          Попробую немного пробежаться на сколько хватит.

          Про "обратную разработку" уже написали. Это первое что бросается и режет глаз.

          Падежи в некоторых местах не к месту, обычно так машинные переводчики путают (например, "приступила к обратной разработкой").

          Вот ещё кусок интересный: "а спустя всего пару месяцев она уже userspace прошла 75% тестов". Непонятно на каком это языке. Слова многие вроде русские, а собрано в кучу по-машинному. Кстати, в оригинале в этом месте нет "userspace", оно было до этого и в переводе это вроде даже уже было отражено.

          В куске "сравнительно простых GPU «для мобильных устройств», например, в  ARM Mali" непонятно почему "для мобильных устройств" взято в кавычки. В оригинале есть кавычки, но смысл немного в другом. В переводе смысл поменялся, а кавычки остались.

          "я уже писала трассировщик GPU для гипервизора m1n1 и заполнял определения структур" -- тут даже пол поменялся по ходу фразы. Машинные переводчики зачастую используют мужский пол.

          И так далее и много ещё по мелочам и не очень то тут, то сям. Мне сложно вычитывать такой перевод просто, что бы углубляться во все-все-все подробности. Прошу прощения за свою лень.

          Надеюсь, наличие скринов не обязательно.


      1. SnikeMK
        16.12.2022 10:25
        +5

        Страдать приходится только первопроходцам.

        У меня уже выработана привычка начинать читать статью с комментариев, а не с самой статьи...


    1. Sazonov
      16.12.2022 08:13
      +1

      Там ещё allocate/deallocate не осилили до конца. Выделение есть, но вместо освобождения почему-то "деаллокация".


      1. Sivchenko_translate Автор
        16.12.2022 09:12

        Да, поправил. Вообще я держал перевод "высвобождение" под "free" из оригинала, но здесь замена также уместна


        1. Sazonov
          16.12.2022 09:39
          +10

          Уместно всегда использовать устоявшиеся технические термины. Не уместно - мешать в одном предложении англицизмы и дословные переводы. Читается тяжело, видно что переводили гуглотранслейтом либо человеком который вообще не разбирается в предметной области.


      1. holydel
        16.12.2022 12:34

        Деаллокация есть, но вместо аллокации почему-то "выделение".


    1. Sivchenko_translate Автор
      16.12.2022 09:14
      +3

      Я предпочитаю термин "обратная разработка", так как он определенно более литературен и прозрачен https://xakep.ru/2016/09/02/reverse-rights/


      1. SerafimArts
        16.12.2022 12:27
        +4

        А вы хоть раз слышали, чтобы это кем-то хоть раз употреблялось?


        Человеку, для того чтобы понять что имеется ввиду, требуется вначале долго вдуплять, потом догадаться перевести на английский и только после этого становится понятным смысл этого словосочетания. Это не "прозрачность", а троллинг читателя/слушателя.


        1. Kogolbok
          17.12.2022 09:07
          +2

          Странные люди. Вы же откуда-то узнали эти англизмы и привыкли к ним. Теперь родная речь для вас нечто инородное.

          Я совершенно не специалист, и тем не менее периодически слышу "обратная разработка". Если этот термин вам всем неведом и вызывает такую бурю (вместо обсуждения того что там написано)... Надо поставить вопрос о вашей образованности и культурности. Ужас какой-то... Собрались все неучи хабра и с радостью лупят автора за неизвестный им термин...


          1. vics001
            17.12.2022 12:30

            Слышал заимствование, копирование, но обратная разработка ... - нет. А язык это всегда практика, если не слышишь, значит и слова уже нет (если вообще было)


          1. SerafimArts
            18.12.2022 15:13

            Конечно узнали. Потому что это известный и устоявшийся термин. А попытка перевести терминологию на любой другой язык очень часто приводит к проблемам.


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


    1. domix32
      16.12.2022 11:30

      Ну коли уж людям потоки это нити, то обратная разработка не так страшна.


      1. vikarti
        16.12.2022 11:39

        При чтении этой статьие — вспоминается статья в одном старом бумажном журнале.
        Где есть фраза вроде(именно на русском) — но если ваша программа использует все возможности Windows NT, такие как триады и пайпы, то вам потребуется для запуска Windows NT, но в этом случае можно обойтись минимальной запущенной на 8 Mb RAM…
        (сама статья про PharLap DOS Extender скорее)


    1. int0Ah
      17.12.2022 00:07
      +3

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


    1. brownfox
      18.12.2022 10:32

      "Пространство пользователя" из той же оперы. Перевод, в целом, понятный, но в отдельных местах странный.


  1. hello_my_name_is_dany
    16.12.2022 05:15

    Чем больше эмодзи, тем лучше - плохая мысль, могли бы из перевода и удалить их


    1. NeoCode
      16.12.2022 08:29
      +23

      А я считаю что если в оригинале эмодзи есть, то и в переводе должны быть. Сохраняется оригинальный стиль изложения.


      1. staticmain
        16.12.2022 08:48
        -15

        Мы на техническом ресурсе, а не в тик-токе


        1. lain8dono
          16.12.2022 09:21
          +11

          Кстати, этот оригинальный стиль изложения называется "делаю крутые штуки, что ты мне сделаешь".


        1. Gorthauer87
          16.12.2022 09:52
          +11

          И что? Вот эти девушки сделали очень сложные крутые технические вещи и хорошо написали о них, но они в своей статье эмодзи активно используют.


          1. junari
            16.12.2022 12:08
            -4

            Вот эти девушки сделали очень сложные крутые технические вещи

            Насколько я помню, Алисса не совсем девушка или, может, не всегда ею была.

            Но это не умаляет ее вклада в развитие lima, panfrost и других GPU-драйверов.


        1. bumzilla
          16.12.2022 11:41
          -3

          По технической части статьи есть что сказать? Или ты только в эмодзи понимаешь?


        1. AlanKaye
          16.12.2022 16:29
          +5

          лол мы На ТеХнИЧЕскОМ рЕСуРСЕ, а нЕ в ТиК-ТокЕ


    1. sshemol
      16.12.2022 14:32
      -3

      есть библиотека под названием drm-shim. Она подменяет интерфейс ядра Linux DRM, ставя на его место формальную реализацию, обрабатываемую в пользовательском пространстве.
      что, если вставить в drm_shim интерпретатор Python, и вызывать из неё весь тот драйвер-прототип, который я напишу на Python?

      Какой ужас. "... что, если гланды удалять через опу?"

      Зато, написание драйверов на питоне приводит к повышенному содержанию восклицательных знаков и эмодзи !!1


      1. beeruser
        16.12.2022 19:22
        +3

        Какой ужас. "... что, если гланды удалять через опу?"

        Слово "прототип" вас ни на какие мысли не наводит?

        Питон позволяет всё делать быстро и гибко.

        Зато, написание драйверов на питоне приводит к повышенному содержанию восклицательных знаков и эмодзи !!1

        triggered ????

        Смайлики не должны удивлять, потому как Лина это виртуальный аниме персонаж (появившийся 1 апреля 2022).


        1. sshemol
          17.12.2022 01:50
          -1

          Слово "прототип" вас ни на какие мысли не наводит?

          Поскольку это тестовое удаление гланд, то мы сделаем это через опу )


  1. vikarti
    16.12.2022 07:30
    +15

    драйвер ядра ещё много месяцев не пойдёт наверх

    куда куда пойдет?
    нет, я понимаю что в оригинале видимо было "upstreamed" но можно ж было как то по другому перевести, ну там — "влит в основную ветку" или что-то вроде


    1. Sivchenko_translate Автор
      16.12.2022 09:09
      +2

      Согласен, переформулировал


  1. px32337
    16.12.2022 09:00
    -10

    Это как опенсоурс драйвера от nvidia, спасибоненадо


    1. Eugeeny
      16.12.2022 16:37

      Нет.


  1. kin4stat
    16.12.2022 09:34
    +1

    Я конечно не эксперт в линукс тематике, но был ли смысл брать сырую обертку раста для драйверов в линуксе, которая еще и работает с версии ядра 6.1? Не лучше было бы все таки на Си написать, чтобы был бэкпорт в старые версии ядра(если такое вообще возможно)?

    Текст выглядит как типичный пример «Школьнику втюхали рекламу раста и теперь он везде трубит у нас тут blazingly fast and ultra mega extra safe code»


    1. vassabi
      16.12.2022 10:30
      +3

      молодежь будет писать на новых языках :) Бэкпорты - для старичков!

      во-вторых - можно же и раст "обмазать снаружи С", чтобы он вызывался нативно, если кому-то надо (я там глянул - он и в объектники умеет и llvm-ir)....

      PS: я и сам люблю С, но момент с обработчиком ошибок в С при помощи goto метка - это да, есть такое ...


    1. domix32
      16.12.2022 11:33
      +15

      Тут скорее возникает вопрос, а зачем ставить на новый M1 старое ядро, если можно не ставить? Это конечно же оставляя вопросы касательно страданий при отладке многопоточности на Си.


    1. DirectoriX
      16.12.2022 11:48
      +5

      чтобы был бэкпорт в старые версии ядра(если такое вообще возможно)
      Так можно бекпортировать всю обвязку вокруг Rust (если возможно), будет ещё лучше. Кстати, когда по вашему мнению должен наступить момент «ну вот теперь можно уже и на Rust писать»? Аргумент про желательность бекпортов и относительную сырость можно применять хоть до тепловой смерти Вселенной.
      blazingly fast and ultra mega extra safe code
      … в отличие от C, который имеет только половину этих свойств.


      1. KanuTaH
        16.12.2022 13:48
        -2

        … в отличие от C, который имеет только половину этих свойств.

        Ну, use-after-free в этом ultra mega extra safe code вполне себе присутствовал (и еще на самом деле неизвестно, сколько других багов до сих пор остается не найденными). Понятно, что это было обмазано этодругином для смягчения эффекта, но хорошо хоть, что не замолчали этот момент, чтобы не "портить впечатление". Растут над собой потихоньку.


        1. DirectoriX
          16.12.2022 14:27
          +4

          Баги — это плохо, и пока не исправлены все баги (как спецификации, так и реализации) нельзя сказать что Rust (или любой другой язык) полностью безопасен, с этим сложно не согласиться. Но и в GCC и Clang тоже бывают баги (кстати, часть багов Rust унаследована от багов нижележащего LLVM).
          К тому же для воспроизведения многих багов компилятора Rust надо писать не совсем тривиальный код, в то время как на C оно скорее всего получится непреднамеренно, иначе у нас бы не было PVS-studio, пишущих о (потенциальных) null pointer dereference в каждом первом проекте. Разница между «стараюсь воспроизвести баг» и «стараюсь НЕ воспроизвести баг» оказалась довольно важной для многих, в том числе и для автора этого видеодрайвера.


          1. KanuTaH
            16.12.2022 14:44
            -2

            иначе у нас бы не было PVS-studio, пишущих о (потенциальных) null pointer dereference в каждом первом проекте.

            Большая часть этих "потенциальных null pointer dereference" связана с тем, что при очередном рефакторинге проверку на NULL вынесли куда-то выше по стеку, а проверки из ЧАСТИ вызываемого свыше кода не убрали, что и сбивает PVS-studio и прочие подобные анализаторы с толку. Для C есть PVS-studio, для раста сделали miri, хрен редьки не слаще.

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

            Это был баг отнюдь не в компиляторе раста, а в коде самого драйвера ("I had a bug in my DRM memory management abstraction").


            1. lain8dono
              16.12.2022 17:31
              +1

              Большая часть того, что делает PVS Studio встроенно либо в rustc, либо в clippy. А miri покрывает немного другой класс задач.


              1. KanuTaH
                16.12.2022 17:50

                Ну описанная проблема в драйвере была скорее по части miri, хотя это только моё предположение.


    1. khajiit
      16.12.2022 12:46
      +3

      Имеет, потому что они пишут для собственного варианта Arch, а там уже оно есть.
      А когда допишут — уже и у бубунты как минимум в hwe появится 6.1.


      Совершенно незачем волочь старый проблемный код ради удобства насильников, задача — написать рабочий и быстрый драйвер, а не понянчиться с сями.


  1. outlingo
    16.12.2022 10:29

    И самое "замечательное" что этот драйвер будет ломаться каждый апдейт как только Apple будет привозить новую прошивку под этот ASC.


    1. vassabi
      16.12.2022 10:39

      а помните, как все переехали на Swift с Objective-C ?


    1. AcckiyGerman
      16.12.2022 10:40
      +3

      1. тут вина не разработчика драйвера, а Эппл

      2. если удалить МакОС и сидеть в линуксе, то новая прошивка "сама внезапно" не обновится


      1. KanuTaH
        16.12.2022 13:30

        если удалить МакОС и сидеть в линуксе, то новая прошивка "сама внезапно" не обновится

        Но на новых устройствах, которые, естественно, будут идти уже с новой прошивкой с завода, драйвер все равно не заработает, и от беготни кругами с криками "а-а-а" все равно никуда не деться.


        1. shlyakpavel
          17.12.2022 12:37

          Прошивок с завода нет, они не хранятся в SoC. Соответственно старые прошивки работают, пока не обновят физически железку.
          Поэтому на каждый новый SoC (m1, m1 pro, m2 и так далее) делается новый срез прошивки и под него дописывается драйвер. Учитывая скорость, с которой добавляли m2, Apple особо активно обратную совместимость не ломает.


          1. KanuTaH
            17.12.2022 13:28

            А какая разница, где хранится прошивка - в SoC или на разделе с macOS, главное, что на новых устройствах с завода она уже новая. Попытаться где-то найти и подпихнуть другую, более старую, версию прошивки можно, но ИМХО это может быть апасно вплоть до физического повреждения - вы же не знаете, зачем она новая, вдруг там что-то уже и аппаратно поменялось. Apple вряд ли будет вам об этом докладывать.


    1. shlyakpavel
      17.12.2022 12:34

      Как я это понял - прошивка подгружается в онлайн режиме и не хранится в SoC.

      Asahi Linux запускается в много этапов: PMU OTP fuses → SecureROM → iBoot stage 1 → iBoot stage 2 → m1n1 stage 1 → m1n1 stage 2 → Das U-Boot → GRUB. Причём по возможности данные и прошивки копируются из macOS как отдельная инсталляция macOS. Про это можно почитать тут и тут.
      Соответственно, если прошивка под ASC обновится в macOS, она останется прежней на разделах с Asahi Linux.


  1. Lapk
    17.12.2022 23:23

    едва прочитала половину статьи. Они не сталкивались с китайскими микрокомпами. Пример - банан пи м3 с чипом A83t (от планшета вроде бы), Mali и всё такое. Всё это там уже было примерно в 2014 году. То есть ГПУ рулил самим ЦПУ, загрузкой ядра линукса... И работал с графикой хреново даже на 1024х768, либо это сильно зависело от экземпляра железки.


    1. beeruser
      17.12.2022 23:50

      Они не сталкивались с китайскими микрокомпами.

      Рекомендую посмотреть кто автор Panfrost (это драйвер Mali).

      Всё это там уже было примерно в 2014 году. То есть ГПУ рулил самим ЦПУ.

      2014? PowerVR мобильный давным давно выполнял на шейдерах свою прошивку.