Приложение B - Диспетчер прямого построения изображений
Данное приложение является адаптированным переводом статьи wikipedia
DRM (Direct Rendering Manager, Диспетчер прямого построения изображений) является подсистемой ядра Linux, которая взаимодействует с GPU современных видео карт. DRM выставляет некий API, который могут применять программы пользовательского пространства для отправки команд и данных в имеющийся GPU, а также для выполнения таких операций, как настройка установок режима подключённого дисплея. Изначально DRM был разработан как компонент инфраструктуры прямого построения изображений сервера X (X Server's Direct Rendering Infrastructure), однако с тех пор он применялся и прочими альтернативами графических стеков, такими как Wayland.
Программы пространства пользователя могут применять API DRM для выдачи команд имеющемуся GPU на осуществление построения 3D изображения и видео- декодирования с аппаратным ускорением, а также для вычислений GPGPU.
Ядро Linux уже имело некий API с названием fbdev (устройство кадрового буфера), применяемое для управления имеющимся кадровым буфером графического адаптера, однако его нельзя было применять для обработки потребностей современного видео- оборудования 3D ускорения GPU. Эти устройства обычно требовали настройки и управления некоторой очередью команд в своей собственной памяти для отгрузки команд в свой GPU, а также требовали управления буферами и свободным пространством такой памяти. Изначально программы пространства пользователя (такие как X сервер) напрямую управляли этими ресурсами, однако они обычно действовали так, как если бы они были единственными, кто имел к ним доступ. В случае, когда две или более программы пытаются управлять одним и тем же оборудованием одновременно, а также каждая сама по себе устанавливает свои ресурсы собственным способом, в большинстве случаев это завершается катастрофически.
Для того, чтобы позволить множеству программ совместно применять ресурсы видео- оборудования, был разработан DRM (Диспетчер прямого построения изображений). Именно DRM получает эксклюзивный доступ к GPU и именно он отвечает за инициализацию и поддержание имеющейся очереди команд, памяти и всех прочих аппаратных ресурсов. Те программы, которые желают применять GPU отправляют запросы в DRM, который выступаетв роли некоего арбитра и заботится об избежании возможных конфликтов.
|
|
DRM делает возможным множеству программ одновременно осуществлять доступ к 3D видео картам избегая конфликты |
Сфера действия DRM на протяжении лет была расширена на дополнительную функциональность, которая изначально обрабатывалась программами пользовательского пространства, такую как диспетчеризацию кадровым буфером и установкой режимов, совместное использование объектов в памяти, а также синхронизацию памяти. Некоторые из этих расширений получили особые наименования, такие как GEM (Graphics Execution Manager, Диспетчер графического исполнения) или KMS (Kernel Mode-Setting, Установки режима ядра), причём когда конкретно упоминается предоставляемая ими функциональность, преобладает используемая терминология. Однако все они в действительности являются частями общего ядра подсистемы DRM.
Тенденция включать два GPU в один компьютер - выделенное GPU и интегрированное - приводит к новым проблемам, таким как переключение GPU, которое также требует разрешения на уровне обсуждаемого DRM. Для соответствия технологии nVidia Optimus был представлен GPU с возможностями разгрузки GPU под названием PRIME.
Диспетчер прямого построения изображения расположен в пространстве ядра, следовательно программы пространства
пользователя должны применять системные вызовы ядра для запроса его служб. Однако, DRM не определяет свои
собственные персональные системные вызовы. Вместо этого он следует принципу Unix "всё является файлом"
для выставления своего GPU через пространство имён файловой системы с помощью файлов устройства в
имеющейся иерархии /dev
. Всякий GPU, обнаруженный DRM именуется как
некое устройство DRM (DRM device) и для взаимодействия с ним
создаётся некий файл устройства /dev/dri/cardX
(где
X
является последовательным номером). Программы пользовательского
пространства, которые желают общаться с данным GPU должны открыть этот файл и применять вызовы
ioctl
для взаимодействия с DRM. Различные ioctl соответствуют
различным функциям API DRM.
Рисунок B-3
Процесс применения Диспетчера прямого построения изображения в Ядре Linux для доступа к графической карте с 3D ускорением
Для снабжения необходимого взаимодействия программ пользовательского пространства с имеющейся подсистемой
DRM была создана библиотека с названием libdrm
. Эта библиотека
в основном представлена некими обёртками, которые представляют некие написанные а C функции для всех ioctl
API DRM, а также константы, структуры и прочие вспомогательные элементы (helper). Такое применение
libdrm не только избегает выставления интерфейса самого ядра напрямую в пользовательское пространство, но также
предоставляет обычные преимущества повторного использования и совместного применения кода между программами.
Рисунок B-4
Подробности архитектуры Диспетчера прямого построения изображения: ядро DRM и драйвер DRM (включая GEM и KMS), взаимодействующий с
libdrm
DRM состоит из двух частей: некоторого общего "ядра DRM" и некоторой специфичной части
("DRM driver") для каждого типа поддерживаемого оборудования. Ядро DRM предоставляет саму базовую
инфраструктуру в которой могут регистрироваться различные драйверы DRM, а также снабжает пространство
пользователя неким минимальным набором ioctl с общей, независимой от оборудования функциональностью.
Некий драйвер DRM, с другой стороны, реализует собственно аппаратно- зависимую часть имеющегося API, особенного
для того типа GPU, которое он поддерживает; он должен предоставлять конкретную реализацию остающихся ioctl,
которые не охвачены ядром DRM, но он, тем не менее, может также расширять имеющийся API, предлагая дополнительные
ioctl с расширенной функциональностью, доступной только на этом оборудовании. Когда некий определённый драйвер
DRM предоставляет какой- то расширенный API, libdrm пространства пользователя также расширяется какой- то
библиотекой libdrm-driver
, которая может применяться пространством
пользователя для взаимодействия с дополнительными ioctl.
Основное ядро DRM экспортирует определённые интерфейсы в приложения пользовательского пространства,
в основном, предназначенные для применения через соответствующие функции оболочек
libdrm
. Кроме того, драйверы экспортируют специфичные для устройства
интерфейсы чтобы применять их драйверами пространства пользователя и осведомлёнными об оборудовании приложениями
через файлы ioctl и sysfs. Внешние интерфейсы содержат: установление соответствия памяти, управление контекстом,
операции DMA, управление AGP, контроль vblank, управление ограждением (fence), управление памятью и
управление выводом.
DRM-Master и DRM-Auth
В применяемом API DRM имеются некоторые определённые операции (ioctl), для которых либо по причине безопасности,
или из- за проблем одновременного использования следует ограничить их применение неким отдельным процессом
пользовательского пространства на устройство. Для реализации такого ограничения DRM устанавливает пределы таких
ioctl для вызовов только тем процессом, который рассматривается в качестве "хозяина" (master) некоторого
устройства DRM, обычно именуемого как DRM-Master. Только один из всех
процессов, которые имеют открытым определённый узел устройства
/dev/dri/cardX
будет иметь свой дескриптор файла
(file handle) помеченным как хозяин, в частности, самый первый вызов ioctl
SET_MASTER
. Все попытки применения одного из таких ограниченных
ioctl без наличия роли DRM-Master будет возвращать некую ошибку. Некий процесс может также взять свою роль
хозяина - и позволить другому процессу захватить её - через вызов ioctl
DROP_MASTER
.
Определённый X сервер - или любой прочий сервер дисплея - обычно является тем процессом, который запрашивает состояние DRM-Master для всех управляемых им устройств DRM, как правило, когда он открывает этот соответствующий узел устройства в процессе своего запуска и оставляет за собой данные привилегии для всего текущего графического сеанса пока не завершит его или не умрёт.
Для всех оставшихся процессов пространства пользователя существует иной способ получения полномочий вызова неких
операций с ограничением для данного устройства DRM, который именуется как
DRM-Auth
. Это основной метод аутентификации для конкретного
утройства DRM чтобы гарантировать, что данный процесс получил подтверждение DRM-Mater для обретения таких
полномочий. Данная процедура составляется из:
-
данный клиент получает некий уникальный маркер (token) - некое 32- битное целое - от запрашиваемого устройства DRM при помощи вызова ioctl
GET_MAGIC
и передаёт его в такой процесс DRM-Master каким- либо образом (обычно посредством некоторого вида IPC; скажем, в DRI2 существует некий запросDRI2Authenticate
, который любой X клиент может отправлять в свой X сервер) -
имеющийся процесс DRM-Master, в свою очередь, отправляет обратно этот марекер в своё устройство DRM через вызов ioctl
AUTH_MAGIC
-
данное устройство предоставляет особые права тому процессу дескриптора файла, чей маркер соответствует полученному от его DRM-Master маркеру.
Из- за значительного увеличения размера видео памяти и роста сложности графических API, таких как OpenGL, имеющаяся стратегия повторной инициализации определённого состояния графической карты при всяком переключении контекста было слишком затратным, с точки зрения производительности. Кроме того, современные рабочие места Linux требуют некоторого оптимального способа совместного использования находящихся вне экрана буферов с помощью диспетчера наборщика (compositing manager). Эти требования повлекли за собой разработку новых методов управления графическими буферами внутри ядра ОС.В качестве одного из таких методов появился GEM (Graphics Execution Manager, Диспетчер исполнения графики).
GEM предоставляет некий API с определяемыми в явном виде примитивами управления памятью. Через GEM некая программа пространства пользователя может создавать объекты памяти, управлять ими и разрушать их, оставаясь в самой видео памяти GPU. Данные объекты, именуемые "объектами GEM", являются постоянными с точки зрения таких программ пространства пользователя и нет потребности перегружать их всякий раз, когда данная программа повторно получает управление данным GPU. Когда некая программа пользовательского пространства нуждается в какоё-то порции видео памяти (для хранения кадрового буфера, текстуры или любых иных данных, необходимых данному GPU), она запрашивает соответствующее выделение в имеющемся драйвере DRM с помощью определённого API GEM. Данный драйвер DRM отслеживает такое использование видео памяти, а также способен удовлетворить такой запрос если имеется доступной свободная память, возвращая "дескриптор" (handle) в пользовательское пространство для дальнейшей ссылки на эту выделенную память в последующих операциях. API GEM также предоставляет операции заполнения такого буфера и его освобождения когда он больше не нужен. Память от высвобождаемых дескрипторов GEM восстанавливается в когда данный процесс пользовательского пространства закрывает такой файловый дескриптор DRM - намеренно или из- за завершения.
GEM также позволяет двум или более процессам пользовательского пространства использовать одно и то же устройство
DRM (а следовательно один и тот же драйвер DRM) для разделения какого- то объекта GEM. Дескрипторы GEM
являются локальными 32- битными целыми, уникальными для какого- то процесса, но повторяемыми в прочих процессах,
следовательно не подходят для совместного использования. Требуется некое глобальное пространство имён, и GEM
предоставляет его посредством применения глобальных дескрипторов под названием
GEM names (Имена GEM). Некое Имя GEM ссылается на один единственный
объект GEM, создаваемый в рамках одного и того же устройства DRM в одном и том же драйвере DRM с применением
некоторого уникального 32- битного целого. GEM предоставляет операцию,
flink
, для получения Имени GEM по дескриптору GEM. Процесс может
затем передавать это Имя GEM - данное 32- битное целое - другому процессу с применением любого доступного
механизма IPC. Данное Имя GEM может применяться процессом преемником для получения какого- то локального
дескриптора GEM указывающего на данный первоначальный объект GEM.
К сожалению, такое применение Имён GEM для совместного использования буферов не является безопасным. Вредоносный процесс третьей стороны, имеющий доступ к тому же самому устройству DRM может предпринять попытку и догадаться о конкретном Имени GEM какого- то буфера, разделяемого другими двумя процессами, просто перебрав 32- битные целые. Если уж Имя GEM определено, к его содержимому можно получить доступ и его можно изменить, нарушив имеющуюся конфиденциальность и целостность имеющейся в этом буфере информации. Этот недостаток позде был обойдён путём введения в DRM поддержки DMA-BUF.
Другая важная задача для любой системы управления видео памятью, помимо управления собственно пространством видео памяти, состоит в отработке необходимой синхронизации между данным GPU и его ЦПУ. Имеющаяся в настоящее время архитектура памяти очень сложна и обычно вовлекает различные уровни кэширования для имеющейся системной памяти, а иногда также и для видео памяти. Таким образом, диспетчеры видео памяти должны также обрабатывать существующую когерентность кэширования чтобы гарантировать согласованность данных между ЦПУ и GPU. Это означает, что зачастую внутреннее устройство управления видео памятью сильно зависит от подробностей аппаратных средств данного GPU и архитектуры памяти и, следовательно, зависит от драйвера.
GEM изначально был разработан инженерами Intel для предоставления диспетчера видео памяти своему драйверу i915. Данное семейство Intel GMA 9xx является интегрированным GPU с UMA (Uniform Memory Architecture, Однородной архитектурой памяти), при которой имеющиеся GPU и ЦПУ совместно используют располагаемой физической памятью, а не какой- то выделенной VRAM. GEM определяет "memory domains" (области памяти) для синхронизации памяти и, в то время как эти области памяти не зависят от GPU, они специально разработаны с прицелом на архитектуру UMA, что делает их менее пригодными для прочих архитектур памяти, например, с отдельной VRAM. По этой причине другие драйверы DRM, приняли решение выставлять такой API GEM в программы пользовательского пространства, однако внутренне они реализуют иной диспетчер памяти, лучше подходящий под их определённые оборудование и архитектуру памяти.
API GEM также предоставляет ioctl для управления самим потоком исполнения (буфером команд), однако оно является специфичным для Intel - и применяется с GPU Intel i915 и более поздними. Никакие иные драйверы DRM не пытаются реализовать какую бы то ни было часть имеющегося API GEM за пределами ioctl, относящихся к самому управлению памятью.
Translation Table Maps
TTM (Translation Table Maps, Таблица соответствий трансляции) является названием общего диспетчера памяти для GPU, который был разработан перед GEM. Он был специально разработан для управления всеми различными типами памяти, к которым может осуществлять доступ GPU, включая выделенную Video RAM (Видео памяти, обычно устанавливаемую в самой видео карте) и системной памяти RAM (ОЗУ), доступной через устройство ввода/ вывода управления памятью (IOMMU, I/O memory management unit), имеющее собственное наименование GART (Graphics Address Remapping Table, Таблица переадресации графических адресов). TTM также должен обрабатывать те части имеющейся Видео памяти, которые не имеют прямой адресации к своему ЦПУ и делают это с наилучшей доступной производительностью, предполагая что графические приложения пространства пользователя обычно работают с большими объёмами видео данных. Другое важное соображение состояло в сопровождении необходимой согласованности между различными вовлечёнными областями памяти и кэширования.
Основным понятием TTM являются "объекты буфера", области видео памяти, которые в определённый момент времени должны быть доступными со стороны GPU. Когда графическое приложение пользовательского пространства желает получить доступ к определённому объекту буфера (обычно чтобы заполнить его неким содержимым), TTM может потребовать его его размещения в некотором типе памяти, имеющей адресацию в своём ЦПУ. Дальнейшее выделение - или операции установления соответствия GART - могут произойти когда данному GPU необходимо получить доступ к какому- то объекту буфера, а он ещё пока не находится в адресном пространстве этого GPU. Каждая из этих операций выделения обязана обрабатывать все связанные с ней данные и проблемы когерентности кэша.
Другим важным понятием TTM являются ограждения (fences). Ограждения являются существенным механизмом управления когерентностью между основным ЦПУ и имеющимся GPU. Некое ограждение отслеживает когда какой- то объект буфера больше не применяется его GPU, как правило, чтобы уведомить любой процесс пользовательского пространства с доступом к нему.
Тот факт, что TTM пытается подходящим образом управлять всеми видами архитектуры памяти, включая те из них, которые содержат выделенную VRAM и без неё, а также обеспечить все возможные функции в диспетчере памяти для его использования с любым типом оборудования, повлёк к чрезмерно сложному решению с неким API, намного превосходящим потребности. Некоторые разработчики сочли его неподходящим для какого- то определённого драйвера, в особенности для соответствующего API. Когда появился GEM в виде более простого диспетчера памяти, его API стал более предпочтительным нежели API TTM. Однако ряд разработчиков драйверов полагают, что выбранный TTM подход был более подходящим для дискретных видео карт с выделенной видео памятью и IOMMU, поэтому они приняли решение использовать TTM внутренним образом, в то же самое время выставляя свои объекты буфера в виде объектов GEM и тем самым поддерживать существующий API GEM. Примерами современных драйверов, применяющих TTM в качестве некоторого внутреннего диспетчера памяти, но при этом предоставляющих некий API GEM являются драйвер radeon driver для видео карт AMD и драйвер nouveau для видео карт nVidia.
Совместное использование буфера DMA и PRIME
API совместного использования буфера DMA (DMA Buffer Sharing API, часто сокращённо именуемого как DMA-BUF) является неким внутренним API ядра Linux, разработанным для предоставления некоего общего механизма для совместного использования буферов DMA для множества устройств, возможно управляемых различными видами драйверов устройств. Например, устройство Video4Linux и некое устройство графического адаптера могут разделять буферы через DMA-BUF для получения нулевого копирования (zero- copy) необходимых данных какого- то видео потока, производимого первым и потребляемого последующим. Любое устройство Linux может реализовывать этот API как экспортёр, как пользователь (потребитель), или как и тот и другой.
Данная функциональность впервые была введена в эксплуатацию в DRM для реализации PRIME, некоего решения для GPU, которое применяло DMA-BUF для совместного применения получаемых в результате кадровых буферов между имеющимися драйверами DRM дискретного и интегрированного GPU. Неким важным свойством DMA-BUF является то, что совместно используемый буфер представляется в пространстве пользователя в виде файлового дескриптора. В имеющийся API DRM были добавлены два новых ioctl для данной разработки PRIME, а именно, один для преобразования локального дескриптора GEM в некий файловый дескриптор DMA-BUF, а другой для в точности обратной операции.
Эти два новых ioctl были впоследствии повторно применены в качестве способа для залатывания имеющегося
внутреннего нарушения безопасности при совместном использовании буфера GEM. В отличии от Имён GEM, файловые
дескрипторы не могут быть подобраны (они не располагаются в глобальном пространстве имён) и операционные системы
Unix предоставляют некий безопасный способ передачи их через соекты межпроцессного взаимодействия
(Unix domain socket) с помощью имеющейся семантики SCM_RIGHTS
. Некий процесс,
который желает применять объекты GEM совместно с другим процессом может преобразовывать свой локальный дескриптор
GEM в файловый дескриптор DMA-BUF и передавать его своему получателю, который в свою очередь может получить
свой собственный дескриптор GEM из полученного файлового дескриптора. Данный метод применяется в
DRI3 для
совместного использования буферов между определённым клиентом и его X сервером, а также в Wayland.
Для работы надлежащим образом некая видео карта или графический адаптер должны установить какой- то режим (mode) - комбинацию разрешающей способности экрана, глубины цвета и частоты обновления - причём они обязаны находиться в том диапазоне значений, который поддерживается сам по себе и со стороны подключённого к нему экрана дисплея. Данная операция имеет название установки режима (mode- setting) и она обычно требует сырого доступа к имеющемуся графическому оборудованию - т.е. определённой возможности записи в конкретные регистры данной видео карты. Операция установки режима должна выполняться прежде чем запустить применение имеющегося кадрового буфера (framebuffer), а также когда данный режим требуется изменить неким приложением или определённым пользователем.
В стародавние времена те программы, которые желали применять имеющийся графический кадровый буфер, также отвечали и за предоставления необходимых операции по установке режима и, тем самым, им было необходимо выполнять привилегированный доступ к своему видео оборудованию. В операционных системах подобных Unix X сервер был наиболее выдающимся примером и его реализация установки режима располагалась в определённом драйвере DDX для каждого определённого типа видео карты. Такой подход, позже названный UMS (User space Mode-Setting, Установкой режимов пространства пользователя) таил определённые проблемы. Он не только нарушал ту изоляцию, которую операционная система должна была предоставлять между программами и аппаратными средствами, порождая как вопросы стабильности, так и проблемы безопасности, но также и оставляя всё графическое оборудование в несогласованном состоянии если две или более пользовательские программы попытаются осуществить в одно и то же время установку режима. Во избежание данного конфликта, X сервер стал на практике единственной программой пользовательского пространства, которая осуществляла операции установки режима; остальные программы пользовательского пространства полагались на имеющийся X сервер в установке надлежащего режима и для обработки всех прочих операций, вовлечённых в установку режима. Изначально все установки режима выполнялись исключительно в процессе запуска самого процесса X сервера, однако позднее X сервер получил определённую возможность делать это во время исполнения. В XFree86 3.1.2 было включено расширение XFree86-VidModeExtension, которое позволило любому клиенту X запрашивать изменения границ режима (разрешения) в своём X сервере. Позднее расширение VidMode было заменено более общим расширением XRandR.
Однако, это был не единственный код, выполняющий установку режима в системе Linux. В процессе загрузки самой операционной системы само ядро Linux должно установить некий минимальный текстовый режим для своей виртуальной консоли (базирующейся на имеющихся стандартных режимах, определяемых расширениями VESA BIOS). Кроме того, сам кадровый буфер ядра Linux содержал код установки режима для настройки устройств кадрового буфера. Во избежание конфликтов установки режима сервер XFree86 - а позднее и сервер X.Org - обрабатывали тот вариант, когда их пользователь переключался из имеющейся графической среды в некую виртуальную текстовую консоль сохраняя своё состояние установок режима и восстанавливая их когда этот пользователь переключается обратно в X. Этот процесс вызывал нежелательное мерцание при самом переходе и к тому же мог быть причиной отказа, что приводило к нарушению отображения или невозможности осуществления вывода.
Имевшийся подход установки режима пространства пользователя также вызывал прочие проблемы:
-
Сам процесс приостановки/ восстановления не полагался на инструменты пространства пользователя для восстановления предыдущего режима. Один отдельный отказ или крушение одной из таких программ мог оставить всю систему без работающего дисплея в процессе некоторого неверного установления режима и, те самым, приводил к невозможности её применения.
-
Также не было возможности для самого ядра показывать ошибку или отладочные сообщения при данном экране в каком- то гарфическом режиме - например, когда исполнялся X - так как только сами режимы ядра знают о том, какие стандартные текстовые режимы имеются в VESA BIOS.
-
Более существенной проблемой было распространение графических приложений минуя сам X сервер и появление прочих альтернатив стека графики помимо X, что расширяло имеющееся дублирование кода установки режима по всей системе ещё больше.
Для решения данной проблемы сам код установки режима был перемещён в некое отдельное место внутри самого ядра, особенное для имеющегося модуля DRM. Затем, все процессы - включая и сам X сервер - обязаны иметь возможность выдавать команду в ядро системы на выполнение операций установки режима и ядро системы будет гарантировать что одновременные операции не приведут в результате к несогласованному состоянию. Такой новый API ядра и код добавленные в имеющийся модуль DRM для осуществления таких операций установки режима получил название KMS (Kernel Mode-Setting, Установок режима ядра).
Установки режима ядра предоставляют определённые преимущества. Самыми быстрыми, естественно, является само удаление дублирования кода установки режима как из ядра системы (консоль Linux, fbdev), так и из пространства пользователя (драйверы DDX X сервера). KMS также позволяет боле просто писать альтернативные графические системы, которым теперь нет нужды реализовывать свой собственный код установки режима. Предоставляя некий единый централизованный режим управления, он решает проблемы моргания при изменении между консолью и X, а также между различными экземплярами X (быстрое переключение пользователя). Доступность в самом ядре позволяет применять его с самого начала загрузки, при этом сохраняя мерцание из- за изменения режимов на таких ранних этапах.
Тот факт, что KMS является частью самого ядра позволяет нам применять ресурсы, доступные только в пространстве ядра, такие как прерывания. К примеру, собственно восстановление режима после процесса приостановки/ восстановления значительно упрощается при управлении самим ядром и, между прочим, улучшает безопасность (более никаким инструментам пространства пользователя не требуются полномочия root). Ядро системы также делает возможным простое подключение в горячем режиме новых устройств отображения, решая давнюю проблему. Установка режима также тесно связана с управлением памятью - поскольку кадровые буферы в основном буферы памяти - поэтому тесная интеграция с диспетчером графической памяти настоятельно рекомендуется. Это всё основные причины того, почему данный код установки режима ядра был включён в DRM, а не является отдельной системой.
Во избежание нарушения обратной совместимости с API DRM, Установка режима ядра предоставляется как некая
дополнительная функциональность драйвера определённых драйверов DRM.
Всякий драйвер DRM может выбрать для предоставления установку флага DRIVER_MODESET
при своей регистрации в основном ядре DRM для указания того, что он поддерживает API KMS. Те драйверы, которые
реализуют Утановку режима ядра часто именуются драйверами KMS, как
вариант их отличия от наследуемых драйверов DRM - без KMS.
KMS был адаптирован до такой степени, что определённые драйверы, которые предоставляют возможности 3D ускорения (или для которых сам производитель оборудования не желает выставлять их или реализовывать), те не менее, реализуют весь API KMS без остального API DRM.
Модель устройства KMS
Модели KMS и управления всеми устройствами вывода как некоторой последовательностью абстрактных блоков оборудования обычно обнаруживается в своём конвейере вывода отображения контроллера дисплея. Таким блоками являются:
-
CRTC: каждый CRTC (от контроллера CRT) представляет собой механизм развёртки своего контроллера дисплея, указывающий на некий буфер развёртки (кадровый буфер). Основная цель CRTC состоит в считывании всех пиксельных данных, находящихся в настоящее время в буфере развёртки и генерации их них собственно сигнала синхронизации видео режима при помощи цикла контура фазовой синхронизации (PLL circuit). Общее число доступных CRTC определяет сколько независимых устройств вывода может обслуживать данное оборудование одновременно, поэтому для применения в конфигурациях со множеством устройств (multi-head) требуется по крайней мере один CRTC на устройство отображения. Два - или более - CRTC могут также работать в режиме клонирования если они выполняют развёртку из одного и того же кадрового буфера для отправки одного и того же образа на различные устройства вывода.
-
Connector: некое подключение представлено когда имеющийся контроллер отображения отправляет получаемый видео сигнал из операции развёртки, подлежащей отображению. Обычно, данная концепция KMS подключений соотносится с физическими коннекторами (VGA, DVI, FPDLink, HDMI, DisplayPort, S-Video ...) в том оборудовании, в котором некое устройство вывода (монитор, панель ноутбука, ...) является постоянным или может быть временно подключено. Информация, относящаяся к подключённому в настоящий момент времени устройству вывода - такая как состояние подключения, данные EDID, состояние DPMS или поддерживаемые видео режимы - также сохраняется внутри данного подключения.
-
Encoder: данный контроллер отображения обязан декодировать сам сигнал синхронизации видео режима из своего CRTC при помощи некоторого формата, совместимого с применяемым подключением (connector). Некий декодер представляет собой аппаратный блок, способный выполнять одно из таких декодирований. Примерами декодирования - для цифрового вывода - являются TMDS и LVGS; для аналогового вывода ими являются выводы VGA и TV, обычно применяющими особые блоки DAC. Некое подключение может только получать свой сигнал от дного декодера в одно и то же время, причём каждый тип подключения поддерживает только некоторые декодеры. Также могут иметься дополнительные физические ограничения из- за которых не всякий CRTC подключается ко всем доступным декодерам, что ограничивает возможные комбинации CRTC- encoder- connector.
-
Plane: некая матрица (plane) является не неким аппаратным блоком, а всего лишь каким- то объектом памяти, содержащим некий буфер, из которого подаётся какой- то механизм развёртки (CRTC). Данная матрица, которая содержит сам кадровый буфер именуется как первичная матрица (primary plane), причём всякий CRTC обязан иметь одну из них связанную с ним, так как именно она является источником для этого CRTC чтобы задавать текущий видео режим - разрешающую способность отображения (ширину и высоту), размер пикселя, формат пикселя, кадровую частоту и тому подобное. Некий CRTC должен также иметь связанные с ним матрицы курсора (cursor planes) если данный контроллер отображения поддерживает перекрытия, либо вторичные матрицы (secondary planes), если он способен осуществлять развёртку из дополнительного перекрывающего оборудования и составлять или смешивать "на лету" окончательное изображение, отправляемое в устройство вывода.
Атомарный дисплей
В последние годы предпринимаются постоянные усилия по внесению атомарности в некотрые относящиеся к API KMS регулярные операции, в частностик настройкам режима и пролистыванию страниц. Именно такой расширенный API KMS является тем, что именуется как Атомарный дисплей, (ранее имевший названия атомарного режима установок и атомарного или ядерного перелистывания).
Основная цель данного атомарного режима установок состоит в обеспечении правильного изменения режима в сложных настройках с множеством ограничений посредством избежания промежуточных шагов, которые могут привести к несогласованному или неверному состоянию видео, он также избегает опасных настроек видео на случай процесса восстановления установок режима в случае отказа ("отката"). Атомарные установки режима позволяют заранее узнать что определённая специфичная конфигурация является приемлимой, предоставляя возможности проверки режима. После того как некий атомарный режим проверен и его допустимось подтверждена, он может быть применён единой неделимой (атомарной) операцией фиксации (commit). Обе операции тестирования и фиксации предоставляются одним и тем же новым ioctl с различными флагами.
Атомарное перелистывание с другой стороны позволяет обновлять множество плоскостей за один и тот же вывод (например, самой первой плоскости, плоскости курсора и, может быть, некоторых перекрывающих или вторичных плоскостей), причём все они синхронизуются в рамках одного и того же интервала VBLANK, что обеспечивает надлежащее отображение без образования разрывов. Данное требование в особенности относится к мобильным и втроенным контроллерам отображения, которые имеют тенденцию к применению множества плоскостей/ перекрытий для сбережения мощности.
такой новый атомарный API строится поверх старого API KMS. Он применяет те же самые модель и объекты (CRTC, декодеры, соединения, плоскости, ...), однако с возрастанием числа свойств объектов, которое может изменяться. Все атомарные процедуры основываются на изменении имеющихся относительных свойств для построения того же самого состояния, которое мы желаем получить для проверки или фиксации. Те свойства, которые мы желаем изменить зависят от того, хотим ли мы делать это с установками режима (по большей части, свойства CRTC, декодеров и соединений) иди переключения страниц (обычно свойства плоскостей). Сам ioctl один и тот же в обоих случаях, имея различие только в самом списке передаваемых всякий раз свойств.
В первоначальном API DRM, само применялось устройство DRM /dev/dri/cardX
как для привелигерованных
(установка режима, прочее управление отображением), так и для непривилегированных (построение изображения, GPGPU вычисления) операций.
По причинам безопасности открытие связанных с DRM файлов требует особых полномочий "эквивалентных root". Это приводило к некоторой
архитектуре, в которой только надёжные программы пространства пользователя (X сервер, графический компоновщик, ...) имели полный доступ к имевшемуся
API DRM, включая такие части полномочий как API установки режима. Остальные приложения пространства пользователя, которые желали строить изображения
или выполнять вычисления, применяли ограниченную версию API DRM без привилегированнных операций. такая архитектура накладывает серъёгные ограничения
на постоянное исполнение графических серверов (самого X сервера, компоновщика Wayland, ...), который работает в качестве хозяина DRM некоторого
у стройтсва DRM с тем, чтобы прочие программы пространства пользователя могли бы быть обеспечены применением самого устройства, даже в случае, когда
они не вовлечены в отображение графики, например, GPGPU вычисления.
Концепция "узлов построения" (render nodes) пытается решить подобные схемы посредством расщепления всего API DRM пространства
пользователя на два интерфейса, один привилегированный, а другой не привилегированный, и применять раздельные файлы устройств (или "узлов")
для каждогоиз них. Для каждого из обнаруженных GPU, соответствующий драйвер DRM - если он поддерживает такое свойство узлов построения изображений -
создаёт некий файл устройства с названием /dev/dri/renderDX
, именуемый
узлом посроения (render node) дополнительно к своему первоначальному узлу (primary node)
/dev/dri/cardX
. те клиенты, которые применяют прямую модель построения изображения и приложения,
которые желают получить преимущества от возможностей вычисления GPU могут делать это без запроса на дополнительные полномочия прсото открывая
любой узел построения и диспетчеризируя операции GPU с применением ограниченного подмножества API DRM поддерживаемого этими узлами - с предоставленными
им полномочиями файловой системы для открытия такого файла устройства. Серверы отображения, компоновщики и прочие прграммы, которым требуется API
установки режима или прочиек привилегированные операции обязаны открывать стандартный первичный узел, который предоставляет доступ к полному
API DRM и использует его как обычно. ограниченный API Узлов построения изображения в явном виде запрещает операцию GEM
flink
чтобы предотвратить совместное применение буфера, использующего ненадёжные глобальные имена GEM;
для совместно используемых буферов можно применять только первичные (PRIME, DMA-BUF) файловые дескрипторы без иного клиента, включающего определённый
графический сервер.
Основная статья: Free and open-source graphics device driver, продолжение переведённой статьи: Hardware support.