В очередной раз перебирая свой ретрокомпьютер, о котором уже рассказывал на Хабре, поменял видеокарту и запустил Quake 2. Решив сравнить картинку, выставил Software rendering, и мне в голову пришла мысль: жаль, что нельзя так сделать в современных играх… Или можно? 

Короткое гугление дало исчерпывающий ответ — легко. Да и инструменты для этого общедоступны. Ниже — четверка самых популярных программных решений, позволяющих запускать 3D-приложения, даже если на сервере нет ни одного GPU с поддержкой OpenGL или Vulkan.


Что вообще значит «приложение требует GPU» 

Начну с очень грубого обобщения: сердцем любого устройства, занимающегося выводом 3D-графики, является растеризатор. В его задачи входит проецирование подготовленной 2D-геометрии в растровое отображение — сетку плоских фрагментов, готовых к дальнейшему шейдингу и выводу на экран. Ранние трехмерные ускорители вроде 3dfx Voodoo 2 фактически только это и делали, забирая часть вычислительной нагрузки на себя. Саму геометрию и трансформацию по-прежнему считал CPU.

До появления таких ускорителей создателям игр приходилось писать собственные растеризаторы, которые работали на CPU. Возможность запихнуть эту часть в кремний и дать к ней доступ разработчикам, существенно упростила жизнь, став причиной появления целого зоопарка разных API, вроде Glide, DirectX, Vulkan и тому подобным.

С тех пор растеризатор во всех современных настольных и мобильных архитектурах реализован аппаратно. Хотя были и неудачные эксперименты — вроде GPGPU Intel Larrabee, который выполнял растеризацию исключительно программно. Время наглядно продемонстрировало, что такой подход нежизнеспособен и стоит оставить все как есть.

В сухом остатке: когда приложению требуется GPU — ему нужен не доступ к железу, а лишь возможность взаимодействия с графическим API. Если на вызов поступил корректный ответ, то по большому счету нет разницы, кто ответил — железный или софтовый драйвер. Последний же может спокойно работать на CPU, пускай и значительно медленнее.

Почему серверы часто живут без GPU

Для классической серверной модели отсутствие видеокарты — это базовая норма. Нет, разумеется, какую-то простую картинку он способен выдать — в BMC/AST-чипах есть примитивный видеовыход, чтобы показать BIOS/UEFI, дать отработать установщику операционной системы или отобразить консоль восстановления. Но вот запустить там какой-нибудь Blender или WebGL становится проблемой. Типичная виртуальная машина способна переваривать десятки тысяч подключений, работать базой данных и веб-сервером, но при этом потеряться, когда софт спросит: «А где у нас тут OpenGL?»

Причина проста — раньше серверные приложения редко хотели графику, а дискретный GPU был лишней точкой отказа и дополнительным расходом электроэнергии. В современном мире на сервере легко может требоваться наличие браузера для автотестов, инструментов с WebGL/WebGPU, генераторов скриншотов, 3D-движков и Electron-приложений. А дальше выясняется, что последним надо аппаратное ускорение, а утилита для снятия скриншотов вообще-то хочет оперировать нормальным графическим контекстом.

Есть два пути: поставить GPU, что внезапно оказывается довольно дорогим и не всегда оправданным решением. Альтернатива — подсунуть иллюзию видеокарты, где программно реализовано то, что по-хорошему должно жить в кремнии.

SwiftShader (Vulkan)

Часть вывода команды vulkaninfo.exe --summary
Часть вывода команды vulkaninfo.exe --summary

Разработка канадской компании TransGaming была впервые представлена публике в 2005 году. В описании прямо указано, что он создан для геймеров, которые хотят играть в казуальные игры, но не готовы тратить деньги на новейшие видеокарты. SwiftShader давал возможность использовать трехмерную графику, даже если в компьютере не было 3D-ускорителя.

На тот момент это один из самых быстрых программных растеризаторов. Заявлялось о 50-кратном приросте производительности по сравнению с Direct3D Reference Rasterizer от Microsoft. Работал он на любом ПК с x86-процессором и поддержкой расширения Intel SSE. Поддерживались операционные системы от Windows 98 и выше. Linux, кстати, тоже — через Cedega (ранее WineX).

Со временем SwiftShader стали все меньше использовать для игр. Вместо этого ему нашлось применение в качестве fallback-механизма для отображения 3D-графики в Chrome, начиная с 18-й версии. Если по каким-либо причинам драйвер видеокарты (дискретной или интегрированной) был недоступен, браузер переключался на программный рендеринг как раз с помощью SwiftShader. 

Сейчас он по-прежнему жив, находясь под крылом Google, но уже не как проприетарный, а как open-source-продукт — исходный код доступен на GItHub. Правда, WebGL fallback в Chrome больше не стоит считать гарантированным поведением — отправлен в deprecated (Chrome 130 и новее). Если захотите попробовать его в деле, например на Windows, то надо раздобыть предварительно скомпилированные библиотеки (или заняться сборкой самостоятельно). Проще всего заглянуть в системную директорию Chrome:

C:\Program Files\Google\Chrome\Application\[version]\

Среди прочего вы увидите три файла — это как раз то, что нужно.

  • vulkan-1.dll — загрузчик, так называемый Vulkan loader. Приложение не обращается к драйверу напрямую, его необходимо слинковать с этой библиотекой. Она выполняет роль коммутатора между софтом и конкретным драйвером. В ее задачи входит найти все доступные реализации Vulkan в системе, перечислить их и загрузить нужную. После чего направлять вызовы от приложения.

  • vk_swiftshader.dll — полноценный GPU-драйвер, работающий на CPU. Внутри реализована эмуляция всего конвейера Vulkan — от программного растеризатора до JIT-компилятора шейдеров. Словом, если vulkan-1.dll решил использовать программный рендеринг, то все вызовы будут отданы в эту DLL.

  • vk_swiftshader_icd.json — манифест ICD (Installable Client Driver) с минимальным содержанием. Нужен лишь затем, чтобы загрузчик понял, какой драйвер перед ним и как его подключить.

В большинстве случаев можно просто скопировать эти три файла в директорию с приложением, которому требуется API Vulkan, и этого будет достаточно. Иногда помогает поместить их в C:\Windows\System32.

llvmpipe (OpenGL) 

Blender 5.1 в Windows Server 2025 через llvmpipe
Blender 5.1 в Windows Server 2025 через llvmpipe

В отличие от SwiftShader, который создавался изначально закрытым, llvmpipe вырос внутри экосистемы Mesa — свободной реализации графических API. Его можно назвать одним из лучших примеров того, как должен выглядеть современный движок программного рендеринга для Linux. 

В документации его называют Gallium-драйвером. Чтобы понять, как это работает, нужен дополнительный контекст. В Mesa отказались от идеи каждый раз писать весь OpenGL-драйвер с нуля — вместо этого написали один общий слой Gallium3D. А уже реализация конкретного драйвера является бэкендом для определенного железа. Llvmpipe делает то же самое, но вместо того чтобы транслировать инструкции Gallium в команды железного GPU, собирает промежуточное представление (LLVM IR) и скармливает его JIT-компилятору.

Последний же выполняет всю «грязную» работу по растеризации элементов, обработке вершин и шейдингу. Таким образом, шейдер каждый раз на лету компилируется в обычную функцию для CPU. Что интересно — в llvmpipe есть механизм параллельного исполнения (до 32 потоков). Он позволяет эффективно загрузить процессорные ядра и значительно ускорить вывод изображения.

lavapipe (Vulkan)

Еще один выходец из экосистемы Mesa. Тут получается чуть интереснее — lavapipe работает как Vulkan-фронтенд для Gallium. Вначале его назвали Vallium, но быстро смекнули, что это доставит им больше проблем, чем пользы. Непосредственно растеризацией вновь занимается llvmpipe. Причем драйвер так же честно говорит системе, что он VK_PHYSICAL_DEVICE_TYPE_CPU, но при этом поддерживает весь необходимый для работы приложений функционал.

Интересный факт: в течение длительного времени пользователи то и дело натыкались на предупреждение вида not a conformant vulkan implementation, testing use only. Чаще всего это случалось даже не специально, а когда в системе отсутствовал корректно установленный драйвер физического GPU. Срабатывал fallback, и пользователи приходили к lavapipe, зачастую того не подозревая. А само предупреждение лишь отражало формальный статус в Khronos CTS (Conformance Testing Suite). Благо с 2022 года lavapipe вполне официально conformant.

Устанавливать эту штуку отдельно не требуется. Если в вашем дистрибутиве Linux есть пакет вроде mesa-vulkan-drivers, то lavapipe там тоже есть.

WARP

Ну и на сладкое мы оставили разработку Microsoft под названием WARP (Windows Advanced Rasterization Platform). Название явно дано в честь сериала Star Trek, где варп-технологии помогали экипажу USS Энтерпрайз (NCC-1701) исследовать неизученные области глубокого космоса. Философия у него точно такая же, как и у остальных героев этой статьи — JIT-компиляция в машинный код для x86 и распараллеливание по ядрам.

WARP изначально позиционировался не как способ запускать игры на ПК без GPU, а в роли инструмента серверного рендеринга и тестирования графики. Это не какой-то отдельный продукт, а часть рантайма Direct3D. По производительности еще со времен Windows 7 его сравнивали с простенькой встройкой Intel GMA 3000. Запустить на ней что-то серьезное было нельзя, но вот для offline-рендеринга, автотестов и генерации превью годилось однозначно.

Вместо заключения

Забавно, но история в очередной раз продемонстрировала цикличность. Давным-давно Quake 2 в Software rendering был компромиссом: мы жертвовали качеством картинки и FPS ради одного — иметь возможность хотя бы запустить игру без подходящего ускорителя. Прошло более двух десятилетий, а мы по-прежнему эксплуатируем тот же самый старый трюк, но не от безысходности, а как осознанное инженерное решение.

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

Ну а энтузиастам он предоставляет уникальную возможность запустить какой-нибудь Crysis, клавший на лопатки все флагманские GPU на момент своего выхода, прямо на сервере, который для игр вообще не предназначен — примеры есть на всем известном видеохостинге. Правда, придется набраться терпения… и оперативной памяти.

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