Зачем нужен режим совместимости WebGPU?
27.03.2026 • webgpu
WebGPU вышел во всех браузерах
WebGPU – новое апи, которое позволяет работать с 3D-графикой и использовать GPU для вычислений. Он является значительным усовершенствованием над WebGL. Жёлтый (на момент написания статьи) цвет плашки говорит о том, что поддержка ограничена, и сейчас функциональность включена по дефолту не во всех ос, в остальных поддержка может иметь экспериментальную реализацию.
При быстром осмотре апи WebGPU у знакомых с WebGL разработчиков может возникнуть ощущение, что “это теперь мы делаем так, а вот это теперь делаем вот так”. Если закопаться в детали, то выяснится, что у нас появляется то, чего никогда в WebGL никогда не было.
WebGPU – более низкоуровневый инструмент. Гибкое использование текстур и методов их фильтрации в шейдерах – пожалуйста. Возможность записи в буферы напрямую в шейдерах – тоже. И таких моментов – много, особенно, если закапываться в мелочи.
WebGPU был создан для новых, современных видеокарт, и это сильно повлияло на архитектуру его апи. Однако это привело и к обратному эффекту. Для начала вспомним историю WebGL 2:
Поддержка в Сафари появилась спустя примерно 4.5 года после остальных браузеров! Ситуация с WebGPU и его поддержкой выглядит во много раз лучше. А ведь WebGL 2 – куда меньший скачок в сравнении с WebGPU. Приятно видеть современную коммуникацию между браузерами.
WebGPU слишком ушёл вперёд?
Новое апи, которое сделано с расчётом на новые видеоускорители, требует… нового видеоускорителя. Даже WebGL 2 (не очень новый) поддерживается далеко не везде, особенно, если мы говорим про десктопы.
А с WebGPU ситуация ещё жёстче: для его работы нужно апи Vulkan, Metal или околопоследние версии DirectX, которые просто не поддерживаются устройствами пользователей. Простым обновлением браузера тут не поможешь, да и обновления операционки может не хватить.
Речь идёт о 10-20-30% устройств (а возможно, и большем), в зависимости от типа устройства и ос.
Всё это приводит к тому, что пользователи, владеющими этими устройствами, никогда не получат на них полноценную поддержку WebGPU. Только покупка нового устройства приведёт к распространению поддержки, а значит, распространение займёт годы, если не больше. И даже в таком случае пользователи старых устройств будут “брошены”.
Если вы прямо сейчас хотите начать делать новое приложение (сайт) и планируете работать с каким-либо из перечисленных апи напрямую, без обёрток для совместимости над WebGL/WebGPU, то вы крепко призадумаетесь, что вам делать. Дублировать ваш код под разные апи или сконцентрироваться на одном?
Тут на помощь приходит Compatibility Mode для WebGPU.
WebGPU Compatibility Mode
Режим совместимости поддержан только в одном браузере, в Хроме. Как выглядит работа с режимом совместимости?
// Указываем, что мы хотим адаптер WebGPU, и нас устроит режим совместимости,
// если полной поддержки WebGPU нет
const adapter = await navigator.gpu.requestAdapter({ featureLevel: "compatibility" });
if (!adapter) {
return;
}
const requiredFeatures = [];
// Если поддерживается обычный режим WebGPU – используем его
if (adapter.features.has("core-features-and-limits")) {
requiredFeatures.push("core-features-and-limits");
}
const device = await adapter.requestDevice({ requiredFeatures });Также можно понять, получили ли мы WebGPU device базовой (core) версии или режима совместимости:
const haveCore = device.features.has("core-features-and-limits");На выходе из кода выше мы либо получаем обычный “девайс” WebGPU, либо девайс в режиме совместимости. Также можно и не “поднимать” апи до обычного, а ограничиться режимом совместимости – это может быть полезно при тестировании.
В данном примере используется фича core-features-and-limits. Она поддержана во всех базовых реализациях WebGPU, даже в тех, что не поддерживают режим совместимости. При этом её не будет там, где доступен только режим совместимости. Легко запутаться.
Что будет, если использовать подобный код в браузерах, которые не поддерживают режим совместимости? featureLevel: "compatibility" будет проигнорировано (в Файерфоксе даже будет выдано предупреждение, что фича в разработке и не поддержана). requestDevice (даже без requiredFeatures) выдаст обычный девайс WebGPU.
Таким образом код работает так:
- Если устройство поддерживает обычную версию
WebGPU, то будет использована она - Если поддерживается режим совместимости и не поддерживается обычный режим, то будет использован режим совместимости
- Если не поддерживается ничего из перечисленного – то не будет
adapter.
Ограничения режима совместимости
Думаю, очевидно, что режим совместимости имеет определённые ограничения по сравнению с обычным WebGPU. Но код с этими ограничениями будет работать и там и там. Теперь чуть пройдёмся по самим ограничениям:
- Меньше лимиты
Меньшее число целей (color attachment), в которое можно рисовать внутри одного шейдерного модуля (8 -> 4).
Меньше минимальный поддерживаемый размер 2d текступы (8192 -> 4096).
Меньшее допустимый размер “рабочей группы” (workgroup) в вычислительных шейдерах.
Меньше количество данных в uniform-буферах и данных, передаваемых между шейдерами (inter-stage, оно же varying в терминологии WebGL).
И так далее.
- Всевозможные ограничения текстур
Ограничения по работе с мультисемплингом и некоторыми форматами текстур, ограничения копированию сжатых текстур и текстур с мультисемплингом, ограничения по вариантам “текстура” – “семплер”, ограничения RG (red green) формата текстур и так далее.
Недоступность
depthBiasClampНедоступны некоторые функции WGSL
dpdxFine, dpdyFine, fwidthFine
- И много другое, очень много нюансов, в которые можно закопаться
Более подробно про ограничения можно почитать на странице предложения на GitHub.
Режим совместимости на практике
У меня есть пет-проект, который использует WebGPU, поэтому я проверил режим совместимости в браузере Хром 148 (Canary) на нём.
Проблемы возникли только с cube текстурами:
1) В режиме совместимости нельзя создать view cube текстуры в виде одиночной 2d текстуры
Вероятно, переработав логику определённым образом, можно будет достичь того же результата.
2) При создании cube текстуры нужно явно указывать, что для неё будет использоваться cube view:
const cubeTexture = device.createTexture({
label: 'cube texture',
// Указываем, что в будущем будет создано view с dimension: 'cube'
textureBindingViewDimension: 'cube',
size: [width, height, 6],
format: format,
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,
});
const view = cubeTexture.createView({
dimension: 'cube'
});Итого
Насколько я понял, на текущий момент режим совместимости – не только готовый инструмент для разработчиков, которые хотят подготовить свои проекты к будущей более широкой поддержке. Это реально рабочий OpenGL ES бекенд для WebGPU в Хромиумах.
Для Файерфокса работа ведётся, но ни одной публичной версии пока нет.
Все эти ограничения и поддержка браузеров не мешает пробовать режим совместимости уже сегодня. Если вы – разработчик WebGPU приложения, попробуйте включить режим совместимости! Возможно несколько результатов:
- Всё сразу заработает. Отлично! С большой вероятностью вы просто можете включить использование режима совместимости на доступных системах
- Не работает, есть ошибки. Попробуйте их поправить. Возможно, вам хватит буквально пары строк для исправления. Иначе вы просто будете в курсе ограничений, и сможете придумать обходной план, если это потребуется
Режим совместимости – большой шаг вперёд по распространению WebGPU. И всё же в большинстве случаев будет фолбек в WebGL, как мне видится. Нужны ли два фолбека – в режим совместимости и в WebGL? Если фолбек в режим совместимости легко доступен – думаю, да, не будет лишним. Через несколько лет ситуация изменится, и может быть, что можно будет оставить только один фолбек – режим совместимости WebGPU.




