Glide проти Direct3D: війна API, яка визначила майбутнє ігор

Було корисно?

Ви на виклику. Прийшов «простий» патч. Раптом ваша інфраструктура збірок Windows не може відтворити краш, який у QA‑лабораторії видно миттєво — лише на одному конкретному драйвері GPU, лише після завантаження рівня, лише коли V‑sync вимкнено.
Якщо цей біль здається сучасним — вітаю: ви щойно заново пережили 1990‑ті, коли графічні API були не стільки абстракціями, скільки політичними знаряддями.

Бій Glide проти Direct3D був не лише про трикутники. Йшлося про те, хто володіє часом розробника, хто несе тягар драйверів і кого звинуватять, коли кадри розлетяться на шматочки.
Ця битва визначила, як масштабуватимуться ПК‑ігри — і вона досі дає незручні уроки про платформи, портативність і експлуатаційну реальність.

Що справді стояло на кону (і чому вам це має бути не байдуже)

Поверхнева історія знайома: пропрієтарний API (Glide), побудований під апаратне забезпечення 3dfx Voodoo, проти загальноцільового Direct3D від Microsoft.
Але «API» тут не був акуратним контрактом. Це був канал розповсюдження, вибір досвіду розробника і ставка на надійність.

Glide пропонував вузький, погоджений з апаратурою інтерфейс: менше варіантів, менше сюрпризів і в багатьох випадках дуже висока продуктивність.
Direct3D пропонував широку абстракцію: більше пристроїв, більше драйверів, більше крайових випадків і, в підсумку, більше охоплення.

Якщо ви керуєте продукційними системами, ви вже бачите цей патерн.
Пропрієтарний інтерфейс дає демо, яке вражає. Стандартизований інтерфейс переживає другого вендора, третє оновлення ОС і п’ятий реорг команди.

Ігрова індустрія кінця 1990‑х була хаотичною лабораторією для цієї компромісної задачі. Перемогла не та сторона, що робила «кращі» трикутники.
Перемогла та, що зробила трикутники можливими на більшій кількості машин з найменшими постійними драмами.

Glide на практиці: швидко, вузько і небезпечно комфортно

Glide був API 3dfx для апаратів класу Voodoo. Ключова деталь: він був спроектований так, щоб чітко відображати те, на що здатний хардвер, а не описувати абстрактний «ідеальний GPU».
Це звучить як дрібниця філософії, поки ви не випустите продукт.

Коли API вирівняний з апаратурою, ви отримуєте менше «обривів продуктивності». Також менше «невизначеної поведінки», бо API просто не дозволяє виражати багато небезпечних поєднань.
В термінах експлуатації: Glide зменшував кількість станів, в які система могла увійти. Надійність це любить.

Вузькість Glide також породжувала залежність розробників. Ігри виходили з «підтримкою Glide» як головною фішкою, і для гравців з картою Voodoo все часто виглядало і працювало краще за альтернативи.
Проблема — що відбувається, якщо у вас немає тієї карти. Або коли вона стає «попереднім поколінням» у ринку, який перевинаходиться кожні 12–18 місяців.

Glide не був портативним. І не мав таким бути. З погляду 3dfx це не була помилка; це була суть.
Якщо ви будуєте найкращу дорогу, по якій можуть їздити лише ваші машини, ви не керуєте транспортною системою — ви керуєте платним проїздом.

Що Glide зробив правильно (те, що люди романтизують)

  • Передбачувана продуктивність. Менше шарів — менше сюрпризів і менший CPU‑оверход, особливо в епоху, коли процесори ледве могли нагодувати GPU.
  • Чітка ментальна модель. Розробники могли розуміти, що робить конвеєр Voodoo, і писати код, що йому відповідає.
  • Менше варіацій драйверів. Якщо ви таргетите одного вендора і вузьку сім’ю продуктів, матриця тестів скорочується драматично.

Що Glide зробив неправильно (те, що люди забувають)

  • Крихкість ринку. Ваша «платформа» настільки надійна, наскільки стабільний баланс і дорожня карта вашого вендора.
  • Залежність розробників. Локдаун працює в обидва боки: він також загороджує студію, а не лише клієнта.
  • Операційний ризик. Якщо єдиний припустимий шлях рендерингу — Glide, а вендор не встигає (фічі, драйвери, виробництво), ви застрягли на компромісах при релізі.

Direct3D на практиці: брудно, широко і неминуче

Direct3D увійшов у боротьбу з handicap‑ом: ранні версії мали погану репутацію через складність і непослідовність на різному хардвері.
Microsoft намагалася визначити графічний контракт для ринку, який ще не вирішив, що саме означає «3D‑акселерація».

Ось несправедлива перевага Direct3D: він був вбудований у Windows, а Windows був каналом розповсюдження для ПК‑ігор, чи подобалося це комусь, чи ні.
Якщо ви хотіли видати масмаркетну ПК‑гру, вам потрібен був API, що є в цільовій ОС без додаткового ритуалу встановлення та молитов про сумісність.

Модель Direct3D також відповідала брудній реальності мультивендорного світу. Замість однієї апаратної цілі — багато; замість одного стеку драйверів — джунглі.
Це робило Direct3D відчутно повільнішим і багатішим на баги в короткостроковій перспективі. Але в довгостроковій — воно робило Direct3D виживаним.

Кут надійності: де Direct3D тихо переміг

Direct3D створив екосистемний стимул: IHV‑и (постачальники GPU) мусили зробити свої драйвери сумісними з API Microsoft, бо ринок того вимагав.
Це зрушує тягар від кожної студії, що підтримує індивідуальні шляхи, на вендорів, які підтримують сумісність і продуктивність для спільного інтерфейсу.

Це було негарно. Але воно масштабувалося. Стандартний API перетворює «хаос по‑грі» на «відповідальність по‑драйверу», і ринок карає найгірші драйвери.
Не завжди швидко і не завжди справедливо, але з часом.

Жарт №1: Помилки драйверів схожі на блискітки — як тільки відкрив пакет, ви будете знаходити їх у не пов’язаних місцях місяцями.

Факти та історичний контекст, який корисно мати біля дошки

Кілька конкретних моментів, що важливі, коли ви намагаєтеся зрозуміти, чому ця війна закінчилася саме так:

  1. Додаткові карти 3dfx Voodoo спочатку були лише для 3D. Багато систем використовували 2D‑карту плюс Voodoo з кабелем‑прохідником.
  2. Glide був прив’язаний до конвеєра апаратури 3dfx. Така тісна зв’язка допомагала продуктивності, але обмежувала портативність та еволюцію функцій.
  3. Рання репутація Direct3D страждала від фрагментації. Різний хардвер підтримував різні можливості; розробники бачили непослідовні результати.
  4. «DirectX» об’єднував декілька мультимедійних API. Для ігор D3D отримав вигоду як частина більшої платформи: введення, звук і графіка під одним зонтом.
  5. MiniGL існував як прагматичний хак. Деякі вендори надавали урізаний шар OpenGL, адаптований під конкретні ігри, що показує, наскільки екосистема прагнула робочих шляхів.
  6. Ера Quake підвищила очікування щодо OpenGL. Навіть коли Glide був швидким, індустрія навчилася цінувати API, що не належить одному вендору.
  7. Якість драйверів стала конкурентною перевагою. Вендори, що випускали швидші та стабільніші D3D‑драйвери, вигравали увагу розробників і OEM‑угоди.
  8. 3dfx придбала STB Systems. Вертикальна інтеграція може бути мудрим кроком, але вона також змінює відносини з каналами і ризики виконання в швидкому ринку.
  9. 3dfx зрештою програла платформну битву і була придбана NVIDIA. Стратегія з пропрієтарним API не пережила компанію, котра її тримала.

Як закінчилася війна: економіка, інструменти та «податок драйвера»

Легка нарація: «Direct3D переміг через Microsoft». Це вірно так само, як «океан вологий»: точно, але неінформативно — бо пропускає механізм.

Механізм — це загальна вартість володіння для розробників і видавців.
Якщо ви керуєте студією, вам важливі не лише пікові FPS на кращій карті. Вас хвилює:

  • наскільки багато машин клієнтів зможуть запустити вашу гру взагалі,
  • як часто горять лінії підтримки,
  • наскільки дорога ваша тест‑лабораторія,
  • наскільки ризиковано ваша дата релізу, коли ринок GPU змінюється в середині проекту.

Glide оптимізував верхівку досвіду для частки ринку. Direct3D оптимізував широту досвіду по ринку, що швидко розширювався.
Коли ПК стали масовою ігровою платформою, широта перемогла чистоту.

Існує другий механізм: інструменти та інерція екосистеми. D3D став кращим. Microsoft ітерувала. Вендори адаптувалися. Розробники побудували навколо нього пайплайни.
У Glide не було багатовендорного «градієнта тиску», щоб утримувати його в чесності. Було лише дорожня карта 3dfx, і коли вона похитнулася, доля API була вирішена.

«Податок драйвера» і хто його платить

Кожен графічний стек платить «податок драйвера»: особливості продуктивності, накладні витрати перевірки стану, виявлення можливостей і вендор‑специфічні баги.
Ключове питання — куди цей податок лягає.

У світі пропрієтарних API податок платять у портах і втрачених клієнтах. У світі стандартних API податок платять інженери драйверів і роботи з конформністю.
Одне масштабується по всьому ринку; інше повторюється для кожної гри.

Операційні уроки: чого SRE навчається на війні API для графіки

Якщо примружитись, графічні API — це розподілені системи. Додаток, рантайм, драйвер, ядро і мікрокод GPU мають власні режими відмов.
Ваш «запит» — кадр. Ваш «SLO» — сталість часу кадру. Ваш «інцидент» — краш, скидання пристрою або підгальмовування, що викликає нудоту у гравців.

Історія Glide vs Direct3D — це кейс з управління радіусом ураження. Glide зменшував змінність, звузивши апаратні цілі. Direct3D зменшував змінність, стандартизуючи інтерфейси
і дозволяючи вендорам конкурувати в реалізації.

Жоден підхід не усуває відмови повністю. Вони її переміщують. Glide переміщує її в залежність від ринку і ризик платформи. D3D переміщує її в поведінку драйвера і еволюцію API.

Цитата, що досі має значення

Вернер Фогельс (CTO Amazon) сказав: «Все ламається, весь час.»
У графічному світі це менше філософія і більше прогноз.

Три корпоративні міні‑історії з окопів

Міні‑історія 1: Інцидент через неправильне припущення

Середня ігрова студія (назвемо її Студія A) випустила ПК‑титул з архітектурою подвійного рендерера: D3D для більшості користувачів і «швидкий шлях» для конкретної карти вендора.
Шлях вендора не називався Glide, але міг би: він припускав стабільний набір апаратних поведінок і дивні властивості драйвера.

Пізно в циклі релізу QA повідомила про випадкові краші на підмножині машин після переключення в інше вікно (alt‑tab). Не відтворювалося на дев‑ригaх команди, які були всі високопродуктивні.
Сигнатура крашу виглядала як use‑after‑free всередині рендерера. Команда трактувала його як гонку в їхньому рушії.

Справжня причина: неправильне припущення про втрату пристрою та час життя ресурсів. Вендор‑специфічний шлях вважав, що «втрата пристрою» рідкісна і що ресурси переживуть
перемикання режиму. На деяких драйверах alt‑tab викликав скидання пристрою, що робило текстури недійсними. Рухунок зберігав вказівники на ресурси, яких більше не було.

Виправлення не було гламурним. Вони реалізували надійну обробку втрати пристрою в обох рендерах, зробили власність ресурсів явною і додали тест‑каркас для симуляції скидань пристрою.
Рівень крашів впав. Кількість звернень до підтримки зменшилась. Продуктивність трохи просіла, бо валідаційні та шляхи відновлення стали реальним кодом, а не мріями.

Урок: пропрієтарні або вендор‑специфічні «швидкі шляхи» схильні тихо відключати безпекові огорожі, на які ви навіть не підозрювали, що покладались.
Припущення дешеві; інциденти — ні.

Міні‑історія 2: Оптимізація, що відкотилася проти вас

Інша компанія (Видавець B з внутрішньою командою рушія) одержима була накладними витратами на виклики відрисовування. Це розумно. Вони таргетили CPU‑зв’язану сцену.
Інженер запропонував «тінювання стану»: відстежувати останній набір стану GPU і пропускати надлишкові зміни стану.

На папері це було виграшно. У мікробенчмарках воно зменшило виклики драйверу і покращило час CPU. Це пішло в продакшн.
Потім почалися багрепорти: іноді текстури «залипали» від попередніх об’єктів, деякі матеріали рендерилися з неправильним режимом змішування — тільки на одному драйвері IHV, тільки після довгих сесій гри.

Корінь був тонким. Їхній шар тінювання передбачав, що якщо рушій не викликав «set state», стан драйвера залишився незмінним. Але драйвер виконував внутрішні інвалідизації стану
під час подій сторінування ресурсів. Модель рушія і модель драйвера розійшлися.

«Оптимізація» перетворилась на генератор десинхронізації стану. Вони відкликали її і замінили на безпечніший підхід: будувати явні незмінні об’єкти стану конвеєра там, де можливо,
і миритися з деякими надлишковими викликами там, де ні.

Продуктивність повернулась до «прийнятно», а коректність — до «реально». Команда рушія вивела довговічне правило: кешувати стан на межі API можна, але лише якщо ви також контролюєте кожну подію, що може цей стан інвалідизувати. У графіці так трапляється рідко.

Міні‑історія 3: Нудна, але правильна практика, що врятувала день

Платформна команда у великому підприємстві (так, підприємства теж випускають 3D‑додатки) вела Windows‑базований продукт візуалізації для регульованих середовищ.
Їхнім клієнтам сюрпризи були неприємніші за любов до FPS.

Команда підтримувала матрицю сумісності: збірка ОС, сімейства моделей GPU і перевірені версії драйверів.
Вони також забезпечували відтворювані збірки з зафіксованими тулчейнами і архівували символи для кожного релізу.
Ніщо з цього не було захопливим. Але також не було необов’язковим.

Одного дня клієнт оновив драйвери GPU по флоту і повідомив про періодичну корупцію рендеру. Вендор драйвера мав регресію в конкретному шейдерному шляху.
Оскільки команда зафіксувала «відомо‑добрі» драйвери і могла швидко порівняти поведінку, вони ізолювали регресію за години, а не тижні.

Вони випустили клієнтське повідомлення: відкотитися на валідавані драйвери, плюс тимчасовий рантайм‑обхід, що уникав проблемної опції компіляції шейдерів.
Клієнт залишився працездатним. Вендор отримав мінімальний репро. Зрештою з’явився виправлений драйвер.

Урок: нудні практики — фіксація, матриці, символи, відтворювані збірки — не виглядають як прогрес, поки не настане день, коли вони врятують від багатотижневого простою під маскою «графічна дивина».

Практичні завдання: команди, виводи та рішення (12+)

Це ті завдання, які ви запускаєте, коли пайплайн рендерингу нестабільний або повільний на Windows‑боксах, CI‑агентах або машинах кінцевих користувачів.
Мета не в «зібрати дані». Мета: швидко прийти до рішення.

Завдання 1: Визначити GPU і версію драйвера (Linux‑воркстейшн або середовище на кшталт Steam Deck)

cr0x@server:~$ lspci -nn | grep -E "VGA|3D"
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU116 [GeForce GTX 1660] [10de:2184] (rev a1)

Значення виводу: У вас є вендор, PCI ID і сімейство моделі.

Рішення: Виберіть правильну гілку драйвера і список відомих проблем для цієї сім’ї GPU; не вгадуйте лише по «це NVIDIA».

Завдання 2: Підтвердити завантажений kernel‑драйвер (Linux)

cr0x@server:~$ lsmod | egrep "nvidia|amdgpu|i915" | head
nvidia_drm             73728  4
nvidia_modeset       1114112  8
nvidia              56770560  345
drm_kms_helper        315392  2 nvidia_drm

Значення виводу: Який драйвер фактично активний, а не просто встановлений.

Рішення: Якщо очікуваний модуль відсутній, припиніть аналіз продуктивності. Спочатку виправте завантаження драйвера.

Завдання 3: Перевірити OpenGL‑рендерер і версію (корисно при триажі легасі‑портів/обгорток)

cr0x@server:~$ glxinfo -B | egrep "OpenGL vendor|OpenGL renderer|OpenGL version"
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: NVIDIA GeForce GTX 1660/PCIe/SSE2
OpenGL version string: 4.6.0 NVIDIA 550.54.14

Значення виводу: Підтверджує, який стек надає GL; часто корелює з тим, як поводяться обгортки (наприклад старі емулятори Glide).

Рішення: Якщо рендерер — «llvmpipe» або «Software Rasterizer», ви рендерите на CPU; всі метрики часу кадру не мають значення.

Завдання 4: Перевірити інформацію про пристрій і драйвер Vulkan (сучасний аналог для переліку можливостей)

cr0x@server:~$ vulkaninfo --summary | head -n 12
VULKANINFO SUMMARY
==================
Vulkan Instance Version: 1.3.275

Devices:
--------
GPU0:
    apiVersion         = 1.3.275
    driverVersion      = 550.54.14
    vendorID           = 0x10de
    deviceName         = NVIDIA GeForce GTX 1660

Значення виводу: Підтверджує рантайм, версію API і версію драйвера, що вплинуть на шари перекладу і компілятори шейдерів.

Рішення: Якщо driverVersion відомо як проблемний, відкотіть або зафіксуйте. Не «оптимізуйте» під зламаний драйвер, поки це не потрібно.

Завдання 5: Захопити завантаження GPU в реальному часі (NVIDIA)

cr0x@server:~$ nvidia-smi dmon -s pucm -d 1
# gpu   pwr gtemp mtemp    sm   mem   enc   dec  mclk  pclk
# Idx     W     C     C     %     %     %     %   MHz   MHz
    0    78    67     -    92    55     0     0  5000  1860
    0    81    68     -    94    58     0     0  5000  1860

Значення виводу: «sm» близько 90% вказує на GPU‑зв’язане навантаження; низький «sm» за високого CPU — CPU‑зв’язане або submit‑зв’язане.

Рішення: Якщо GPU насичений, припиніть ганятися за накладними викликів відрисовування; дивіться на вартість шейдерів, overdraw, роздільну здатність і пост‑процесінг.

Завдання 6: Перевірити насичення CPU і тиск планувальника (Linux)

cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.8.0 (server) 	01/13/2026 	_x86_64_	(16 CPU)

11:32:20 AM  CPU   %usr %nice %sys %iowait %irq %soft  %steal %guest %gnice %idle
11:32:21 AM  all   68.50 0.00  9.12   0.20 0.00  0.88   0.00   0.00   0.00 21.30
11:32:21 AM    6   99.00 0.00  0.50   0.00 0.00  0.50   0.00   0.00   0.00  0.00

Значення виводу: Один «гарячий» ядро на 99% часто вказує на вузьке місце в основному потоці у шляху submit‑у відрисовування.

Рішення: Якщо одне ядро завантажене, пріоритизуйте батчинг, сортування станів і зменшення викликів API — класичні обмеження ери D3D, що й нині реальні.

Завдання 7: Знайти топ‑споживачів CPU і кількість потоків (Linux)

cr0x@server:~$ ps -eLo pid,tid,psr,pcpu,comm --sort=-pcpu | head
 4121  4121   6 98.7 game.exe
 4121  4128   3 22.1 game.exe
 4121  4135   9 10.4 game.exe
 2380  2380  11  4.0 Xorg
 3012  3012   1  1.9 pulseaudio

Значення виводу: Показує, чи ви обмежені одним потоком, чи гарячі багато воркерів.

Рішення: Якщо основний TID домінує, почніть з витрат render‑потоку і побудови кадру. Якщо багато потоків гарячі — шукайте конкуренцію або надмірну фонову роботу.

Завдання 8: Перевірити тиск пам’яті, що викликає стуттер (Linux)

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 514232  61244 921440    0    0    12    18  420  980 72  9 19  0  0
 3  0      0 489120  61244 924880    0    0     8    24  500 1100 75  8 17  0  0
 5  1      0  50200  58000 890000    0    0  1200   900  900 3000 65 12 10 13  0

Значення виводу: Зростання «b» (blocked) і IO «bi/bo» разом з низькою вільною пам’яттю може означати, що стрімінг текстур або кеш шейдерів вдаряє по диску.

Рішення: Якщо піки IO корелюють зі стуттером, працюйте над стрімінгом ресурсів, місцем кешу шейдерів і бюджетами пам’яті перед тим, як чіпати «оптимізації» GPU.

Завдання 9: Підтвердити затримку диска для кешів шейдерів і стрімінгу ресурсів (Linux)

cr0x@server:~$ iostat -xz 1 3
Linux 6.8.0 (server) 	01/13/2026 	_x86_64_	(16 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          61.20    0.00    8.10    4.50    0.00   26.20

Device            r/s     w/s   rkB/s   wkB/s  avgqu-sz  await  %util
nvme0n1         120.0    90.0  4800.0  3500.0      2.10  6.20  78.00

Значення виводу: «await» у кілька мс і висока %util під навантаженням можуть створювати видимий стуттер, коли компіляція шейдерів або стрімінг зачіпає сховище.

Рішення: Якщо сховище гаряче, перенесіть кеші на швидший носій, зменшіть рантайм‑компіляцію або попередньо скомпілюйте. Не звинувачуйте GPU за диск.

Завдання 10: Перевірити скидання GPU драйвером (TDR) у логах (при аналізі Windows‑тома офлайн)

cr0x@server:~$ grep -R "Display driver" -n /mnt/windows/Windows/Logs/System.evtx.txt | head
1842: Display driver nvlddmkm stopped responding and has successfully recovered.
3229: Display driver nvlddmkm stopped responding and has successfully recovered.

Значення виводу: Класичний Timeout Detection and Recovery: драйвер скинув GPU після зависання.

Рішення: Розглядайте як інцидент надійності: зменшіть довгі шейдерні стази, уникайте патологічних навантажень GPU, перевірте версії драйверів. Не «просто збільшуйте TdrDelay» як перший крок.

Завдання 11: Перевірити, які DLL завантажує легасі‑гра або обгортка (артефакти Windows, переглянуті з Linux)

cr0x@server:~$ strings -a /mnt/windows/Games/OldTitle/game.exe | egrep -i "glide|d3d|opengl|ddraw" | head
d3d8.dll
ddraw.dll
opengl32.dll
glide2x.dll

Значення виводу: Підтверджує, що додаток може намагатися використовувати кілька бекендів рендерингу, включаючи шими ери Glide.

Рішення: Якщо присутні і Glide, і D3D, переконайтесь, що вибір шляху навмисний; зафіксуйте відомо‑добрий бекенд, щоб зменшити змінність.

Завдання 12: Виміряти стабільність часу кадру, а не лише FPS (використовуючи MangoHud у Linux)

cr0x@server:~$ cat ~/.config/MangoHud/MangoHud.conf | egrep "fps|frametime|histogram" 
fps
frametime
histogram

Значення виводу: Ви ввімкнули метрики, що показують сплески. Середній FPS брешуть; гістограма часу кадру каже правду.

Рішення: Якщо гістограма часу кадру має довгі хвости, пріоритетно шукайте джерела стуттера: компіляція шейдерів, пейджинг, синхронізації або сплески CPU.

Завдання 13: Виявити зростання і чурн кешу шейдерів (Linux)

cr0x@server:~$ du -sh ~/.cache/mesa_shader_cache ~/.cache/nvidia 2>/dev/null
1.8G	/home/cr0x/.cache/mesa_shader_cache
642M	/home/cr0x/.cache/nvidia

Значення виводу: Великі кеші можуть вказувати на багато варіантів; чурн — на перевбудови, що викликають стуттер.

Рішення: Якщо кеш величезний або часто перебудовується, зменшіть кількість варіантів шейдерів, попередньо компілюйте або виправте тригери інвалідизації кешу (оновлення драйвера, зміни шляхів).

Завдання 14: Підтвердити, що ви випадково не працюєте через шар перекладу, якого не хотіли

cr0x@server:~$ env | egrep "PROTON|DXVK|VKD3D|WINE" | head
PROTON_LOG=1
DXVK_HUD=0
VKD3D_CONFIG=none

Значення виводу: Середовище показує, чи D3D перекладається (наприклад D3D9→Vulkan), що змінює профілі продуктивності і багів.

Рішення: Якщо ви триажите нативну проблему D3D, але запускаєтесь через переклад, зупиніться. Спочатку відтворіть у правильному стеці.

Швидкий план діагностики: знайти вузьке місце без здогадок

Вам потрібна відтворювана послідовність, що уникає класичної пастки: «Я змінив три речі і стало краще, отже я геній.»
Ні. Вам пощастило. Робіть так натомість.

Перший крок: визначте, чи це краш, зависання/скидання або «просто» продуктивність

  • Краш: процес виходить; потрібні символи, дампи, кроки відтворення.
  • Зависання/скидання (TDR): замерзання екрану, відновлення драйвера; фокус на довгих GPU‑задачах і компіляції шейдерів.
  • Продуктивність: зосередьтесь на часі кадру, а не FPS; класифікуйте CPU‑зв’язане vs GPU‑зв’язане.

Другий крок: класифікуйте CPU‑зв’язане vs GPU‑зв’язане за 2 хвилини

  • Перевірте завантаження GPU (Завдання 5) і чи є «пік» на одному ядрі (Завдання 6/7).
  • Зменшіть роздільну здатність або відключіть дорогий пост‑процесинг.
  • Якщо зниження роздільності не допомагає — ймовірно, вузьке місце на CPU/драйвері/submit.

Третій крок: ізолюйте «стуттер» vs «повільно»

  • Повільно: постійно високий час кадру, стабільно.
  • Стуттер: здебільшого нормально, періодичні сплески.

Стуттер часто спричинюють сховище, компіляція шейдерів, пейджинг або синхронізації (локи, фенс, vsync). Використовуйте Завдання 8–9 і 13.

Четвертий крок: свідомо зменште матрицю тестів

  • Візьміть один відомо‑добрий драйвер і один відомо‑поганий драйвер.
  • Відтворіть на чистій машині/профілі користувача (кеші шейдерів мають значення).
  • Зафіксуйте бекенд рендерингу (D3D‑шлях, обгортка, шар перекладу).

П’ятий крок: тільки потім налаштовуйте

Якщо ви оптимізуєте до того, як зможете надійно відтворити проблему, ви не оптимізуєте. Ви граєте в азартні ігри з графіками.

Жарт №2: Якщо ви не можете відтворити графічний баг, це не «хейзенбаг» — це «у нас ще немає тестового каркасу».

Типові помилки: симптом → корінна причина → виправлення

1) «На моєму GPU працює швидко, гравці скаржаться, що повільно»

Симптом: Чудова продуктивність на дев‑машині; слабкі GPU повзають.

Корінна причина: Ваш контент розрахований на fill‑rate і пропускну здатність; ви GPU‑зв’язані на нижчих рівнях.

Виправлення: Додайте масштабовані налаштування, що реально знижують піксельну вартість (масштабування роздільності, дешевший пост‑процесинг, зменшення overdraw). Перевіряйте через завантаження GPU (Завдання 5).

2) «Випадкова втрата пристрою / скидання драйвера після патча»

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

Корінна причина: Довготривалі шейдери, нескінченні цикли або великі командні буфери, що тригерять TDR.

Виправлення: Розбийте роботу на менші шматки; спростіть або захистіть шейдери; валідуйте логи (Завдання 10) і відтворюйте з дебаг‑шарами коли можливо.

3) «Стуттер щоразу, коли з’являється новий ефект»

Симптом: Гладко, а потім сплеск при появі нових матеріалів/зон.

Корінна причина: Рантайм‑компіляція шейдерів і промахи кешу.

Виправлення: Попередньо компілюйте шейдери; прогрівайте кеші; моніторте приріст кешів (Завдання 13) і затримки сховища (Завдання 9).

4) «Корупція, яка зникає при відключенні оптимізації»

Симптом: Неправильні текстури/режими змішування, періодично.

Корінна причина: Десинхронізація кешування/тінювання стану з драйвером; невизначена поведінка, що покладається на випадковий стан.

Виправлення: Зробіть стан конвеєра явним; уникайте хитромудрого елімінації стану, якщо не можете гарантувати інвалідизацію у всіх подіях.

5) «Працює лише на одному вендорі»

Симптом: Працює на вендорі A, ламається на вендорі B.

Корінна причина: Ви покладаєтесь на невизначену поведінку або баг/особливість драйвера.

Виправлення: Використовуйте validation‑шари і тести на конформність; якщо це баг вендора — зробіть мінімальне репро і подайте звіт. Паралельно випустіть обхід, відфільтрований по вендору + версії драйвера з чистим логуванням, щоб потім його можна було прибрати.

6) «Продуктивність падає після оновлення драйверів»

Симптом: Та сама збірка, новий драйвер, гірший час кадру.

Корінна причина: Регресія в компіляторі шейдерів, поведінці кешу або плануванні.

Виправлення: Фіксуйте версії драйверів для QA і релізів; ведіть матрицю сумісності; тестуйте «відомо‑добрі» і «останні» окремо.

7) «Alt‑tab ламає рендер або викликає краш»

Симптом: Втрата текстур, чорний екран, краш після зміни фокусу.

Корінна причина: Неправильна обробка втрати пристрою; ресурси не відновлено або посилання неправильні.

Виправлення: Реалізуйте надійні потоки скидання пристрою і явне відстеження життєвого циклу ресурсів; додайте автоматизовані тести для втрати пристрою і перемикань режимів.

Чек‑листи / покроковий план

Чек‑лист A: Випуск рендерера через різноманіття вендорів (чого Direct3D змусив усіх навчитися)

  1. Визначте матрицю підтримки. Версії ОС, сімейства GPU і гілки драйверів, які ви тестуєте і за які відповідаєте.
  2. Зафіксуйте і архівуйте. Версії тулчейнів, шейдери, символи і артефакти збірки для кожного релізу.
  3. Побудуйте відтворювану графічну тест‑сцену. Детермінований шлях камери, детермінований порядок завантаження ресурсів, фіксовані сид‑и.
  4. Вимірюйте час кадру. Відстежуйте p50/p95/p99 часу кадру, а не лише середній FPS.
  5. Бюджетуйте варіації шейдерів. Якщо система матеріалів може згенерувати 10 000 варіантів — вона їх і згенерує.
  6. Плануйте втрату пристрою. Ставте її як нормальну подію, а не апокаліпсис.
  7. Гейт для обхідних рішень. Перевірки версій драйверів і ID вендорів; логувати, коли обхід увімкнено.
  8. Тримайте мінімальний репро‑пайплайн. Коли вдарить баг драйвера, вам потрібне маленьке, легко передаване відтворення.

Чек‑лист B: Дебаг регресії продуктивності за тиждень, а не за квартал

  1. Відтворіть на чистій машині/профілі користувача.
  2. Підтвердіть вибір бекенду (Завдання 11/14).
  3. Класифікуйте CPU vs GPU‑зв’язаність (Завдання 5–7).
  4. Перевірте джерела стуттера: пам’ять/IO/кеш шейдерів (Завдання 8–9/13).
  5. Порівняйте відомо‑добрі vs відомо‑погані версії драйверів.
  6. Бісектуйте зміни в контенті й у коді окремо.
  7. Розкочуйте пом’якшення за прапорами; вимірюйте вплив.
  8. Запишіть результат операційними термінами: що зламалось, чому зламалось, як уникнути в майбутньому.

Чек‑лист C: Якщо мусите підтримувати пропрієтарний «швидкий шлях» (як робити це без ненависті)

  1. Вимагайте тестів паритету: швидкий шлях має проходити той самий набір коректності.
  2. Побудуйте вимикач: конфіг, змінне оточення, безпечний фолбек.
  3. Інструментуйте вибір бекенду і інформацію про драйвер у телеметрії.
  4. Обмежуйте радіус ураження: дозволяйте лише для відомо‑добрих комбінацій апаратури/драйверів.
  5. Призначте власника. «Усі» відповідають означає, що ніхто не ремонтує.

FAQ

1) Чи був Glide технічно кращим за Direct3D?

У вузькому сенсі — мапування на апаратуру Voodoo і передбачувана продуктивність — часто так. У платформному сенсі — портативність, довговічність, різноманіття вендорів — ні.
«Кращий» залежить від того, чи ваша мета — пік продуктивності на одній цілі, чи виживання на ринку.

2) Чому розробники підтримували Glide, якщо він був пропрієтарним?

Тому що він працював і продавав копії. Якщо найкрасивіша версія вашої гри запускалась на наймоднішій карті, маркетинг дякував, і гравці помічали.
У короткій перспективі це був раціональний вибір.

3) Чому Direct3D переміг, хоча ранні версії були болісними?

Через дистрибуцію і екосистему. Direct3D постачався з Windows і покращувався з часом. Вендори мали стимул оптимізувати драйвери під нього. Інструменти і досвід розробника наздогнали.
Glide не зміг пережити апаратного вендора, до якого був прив’язаний.

4) Де в цій історії OpenGL?

OpenGL мав значення, особливо для певних рушіїв і для робочих станційної спадщини. Але споживчий імпульс Windows‑ігор, OEM‑угоди і пакет DirectX штовхнули D3D у звичну лінію.
Індустрія також зрозуміла, що «стандарт» допомагає лише тоді, коли драйвери якісні і інструменти доступні.

5) Який сучасний еквівалент Glide?

Розширення вендорів, пропрієтарні апскейлери та ексклюзивні API або фічі платформи. Вони можуть бути чудовими. Але несуть ризик платформи.
Використовуйте їх за перевірками можливостей і з чистим фолбеком.

6) Чи є Direct3D априорі стабільнішим за пропрієтарні API?

Не априорі. Стабільність приходить від інвестицій екосистеми, валідації та дисципліни в експлуатації.
Стандартні API зазвичай залучають більше зусиль з конформності і ширше тестування, що зазвичай допомагає з часом.

7) Якщо я дебажу стуттер, чому ви весь час говорите про сховище?

Тому що стуттер часто — це «GPU чекав на щось інше». Компіляція шейдерів, пейджинг і стрімінг часто торкаються диска.
Якщо ваші сплески часу кадру співпадають з IO або перебудовами кешу, вузьке місце не в GPU — воно в пайплайні навколо нього.

8) Чи варто фіксувати версії драйверів GPU в продакшні?

Так, якщо вам важлива передбачуваність. Фіксуйте для валідаваних конфігурацій і тестуйте «останні» окремо, щоб планувати оновлення, а не отримувати сюрпризи.
Це особливо важливо для корпоративної візуалізації, середовищ кіберспорту і кіосків.

9) Як уникнути зворотного ефекту «state shadowing»?

Розглядайте явний стан конвеєра як джерело правди. Коли кешуєте, переконайтеся, що можете інвалідизувати правильно при кожній значущій події: втрата пристрою, видалення ресурсів, зміни контексту й поведінка драйвера.
Якщо ви не можете змоделювати інвалідизацію — не прикидайтеся, що можете.

10) Що робити, якщо проблема відтворюється лише на драйвері одного вендора?

По‑перше, припустіть, що ви покладаєтесь на невизначену поведінку. Валідуйте, зведіть до мінімального репро і тільки тоді реєструйте як баг драйвера.
Паралельно випустіть обхід, що гейтується по вендору + версії драйвера з чистим логуванням, щоб потім можна було його відкликати.

Наступні кроки, що не марнують тиждень

Glide проти Direct3D — це не лише війна API; це попередній перегляд того, як платформи виграють. Та платформа, що знижує довгостроковий операційний біль, перемагає, навіть якщо спочатку вона незграбна.
Glide зробив найкращу версію гри на одному класі апаратури. Direct3D зробив її придатною для випуску на весь ринок ПК.

Якщо ви зараз будуєте або підтримуєте рендеринговий стек, сприйміть нудні уроки серйозно:

  • Визначте матрицю підтримки і забезпечте її зафіксованими драйверами та відтворюваними збірками.
  • Інструментуйте час кадру і швидко класифікуйте вузькі місця використовуючи план дій.
  • Побудуйте мінімальний репро‑каркас для багів драйверів — майбутнє «ви» подякує сьогоднішньому «вам».
  • Використовуйте пропрієтарні швидкі шляхи обережно: гейтовані, протестовані і з вимикачем.

Дискусія 1990‑х була «швидко проти сумісно». Сучасна дискусія — «швидко проти керовано». Обирайте керованість першою. Потім робіть швидко.

← Попередня
Швидкість відновлення в Proxmox: налаштування PBS, вибір стиснення та чому відновлення повільні
Наступна →
Proxmox VFIO «device is in use»: як правильно від’єднувати PCI-пристрої від хоста

Залишити коментар