Що дає вулкан в іграх
DirectX 12 або Vulkan - що краще в іграх?
Багато сучасних ігор під час запуску в Windows пропонують вибір між двома графічними API - DirectX 12 або Vulkan, що може викликати у користувачів питання: що краще вибрати.
У цій статті докладно про відмінності Vulkan від DirectX і про те, які переваги та недоліки можна отримати при виборі кожної опції для запуску вашої гри.
Що таке DirectX та Vulkan
І DirectX і Vulkan є API для взаємодії програми, а в поточному контексті - ігри, з обладнанням вашого комп'ютера. У той час як Vulkan – API тільки для графіки, DirectX – набір різних API, але при виборі між ним та Vulkan в іграх зазвичай мається на увазі лише графічна частина – Direct3D.
Обидва призначені для того, щоб полегшити розробку ігор незалежно від конкретного обладнання користувача, забезпечивши при цьому максимально високу продуктивність в іграх. І той, і інший графічний API може працювати з відеокартами AMD, NVIDIA та іншими.
У той час як DirectX – розробка Microsoft і використовується лише в операційних системах цієї компанії, починаючи з Windows 10, Vulkan може бути використаний у Windows, MacOS, Linux, Android та інших операційних системах.
Що вибрати - Vulkan або DirectX 12
Багато сучасних ігор дозволяють використовувати як Vulkan, так і DirectX як графічний API. Чіткої відповіді на запитання якої з цих API краще немає, але:
- Більшість тестів показують вищу частоту кадрів (FPS) в іграх при виборі Vulkan, за рахунок того, що для цього API потрібно менше ресурсів комп'ютера, а також краще реалізована робота на багатоядерних процесорах.Однак це може залежати від конкретної гри та обладнання комп'ютера користувача.
- Є думка, що вибір DirectX 12 у Windows дозволяє досягти стабільнішої роботи гри, в деяких випадках - уникнути збоїв.
- Вибір Vulkan часто дозволяє знизити навантаження на процесор, тобто в цьому плані може бути ефективнішим.
- Візуальних відмінностей у картинці при однакових налаштуваннях графіки у грі при використанні Vulkan та DirectX зазвичай немає.
- Робота гри при виборі того чи іншого API може залежати від конкретної гри та від того, наскільки успішно розробники реалізували роботу з Vulkan та/або DirectX.
Єдино правильної відповіді на запитання «Що вибрати – Vulkan або DirectX 12» немає. Численні тести в мережі та досвід користувачів показують, що продуктивність у кожному з варіантів вибору залежатиме:
- Від гри.
- Від налаштувань графіки у грі.
- Від графічного обладнання та покоління відеокарти: наприклад, більшість тестів показують, що для сучасних відеокарт NVIDIA кращий Vulkan, а для AMD зазвичай швидшим виявляється DirectX 12
- У деяких випадках – від інших характеристик комп'ютера, таких як продуктивність процесора.
Підсумовуючи, оптимальний варіант - перевірити роботу і DirectX, і Vulkan, переключивши API в налаштуваннях гри, після чого зробити висновок, який з варіантів виявився кращим у вашому випадку, або залишити параметри за замовчуванням, якщо при їх використанні у вас і так немає будь-яких проблем із продуктивністю у грі.
А раптом і це буде цікаво:
- Найкращі безкоштовні програми для Windows
- SuperMSConfig – утиліта для налаштування Windows 11
- Flyby11 — просте оновлення до Windows 11 24H2 на комп'ютері, що не підтримується.
- Образ ISO містить відкликаний завантажувач UEFI Rufus — пояснення
- Комп'ютер не бачить флешку – що робити?
- ViGEmBus Driver — що це, як завантажити та встановити
- Windows 11
- Windows 10
- Android
- Завантажувальна флешка
- Лікування вірусів
- Відновлення даних
- Установка з флешки
- Налаштування роутера
- Все про Windows
- У контакті
- Однокласники
- Живі шпалери на робочий стіл Windows 11 та Windows 10
- Найкращі безкоштовні програми на кожен день
- Як скачати Windows 10 64-біт та 32-біт оригінальний ISO
- Як дивитися ТБ онлайн безкоштовно
- Безкоштовні програми для відновлення даних
- Найкращі безкоштовні антивіруси
- Засоби видалення шкідливих програм (яких не бачить ваш антивірус)
- Вбудовані системні утиліти Windows 10, 8 і 7, про які багато хто не знає
- Безкоштовні програми віддаленого керування комп'ютером
- Запуск Windows 10 з флешки без встановлення
- Найкращий антивірус для Windows 10
- Безкоштовні програми для ремонту флешок
- Що робити, якщо сильно гріється та вимикається ноутбук
- Програми для чищення комп'ютера від непотрібних файлів
- Найкращий браузер для Windows
- Безкоштовний офіс для Windows
- Запуск Android ігор та програм у Windows (Емулятори Android)
- Що робити, якщо комп'ютер не бачить флешку
- Управління Android з комп'ютера
- SuperMSConfig – утиліта для налаштування Windows 11
- Flyby11 — просте оновлення до Windows 11 24H2 на комп'ютері, що не підтримується.
- Образ ISO містить відкликаний завантажувач UEFI Rufus — пояснення
- Комп'ютер не бачить флешку – що робити?
- ViGEmBus Driver — що це, як завантажити та встановити
- Як очистити папку FileRepository у DriverStore
- Буфер обміну на iPhone - використання та особливості
- Universal USB Installer – створення завантажувальних накопичувачів Linux та Windows
- Код 10 Неможливо запустити цей пристрій — як виправити?
- Запуск програм Linux з графічним інтерфейсом у Windows 11 та 10
- Бездротовий доступ до файлів Android у Провіднику Windows 11
- Як увімкнути захист адміністратора у Windows 11 та 10
- Безпечний режим на Mac — завантаження та додаткова інформація
- Складовий USB пристрій - що це в Windows та виправлення помилок
- Комп'ютер вимикається сам собою — чому і що робити?
- Windows
- Android
- iPhone, iPad та Mac
- Програми
- Завантажувальна флешка
- Лікування вірусів
- Відновлення даних
- Ноутбуки
- Wi-Fi та налаштування роутера
- Інтернет та браузери
- Для початківців
- Безпека
- Ремонт комп'ютерів
- Windows
- Android
- iPhone, iPad та Mac
- Програми
- Завантажувальна флешка
- Лікування вірусів
- Відновлення даних
- Ноутбуки
- Wi-Fi та налаштування роутера
- Інтернет та браузери
- Для початківців
- Безпека
- Ремонт комп'ютерів
Vulkan API (glNext) від Khronos Group
Відносно нещодавно вийшов новий Vulkan API – можна сказати, спадкоємець OpenGL, хоча заснований Vulkan на API Mantle від AMD.
Звичайно, розвиток та підтримка OpenGL не припинилося, а також у світ вийшов і DirectX 12. Що там з DirectX 12 і чому його поставили лише на Windows 10 – я, на жаль (а може й на щастя) не знаю. Але ось кросплатформовий Vulkan мене зацікавив. У чому особливості Vulkan і як правильно його використовувати я постараюся розповісти вам у цій статті.
Отже, навіщо потрібний Vulkan і де може бути використаний? В іграх та додатках, що працюють з графікою? Звісно! Обчислювати, як це робить CUDA чи OpenCL? Без проблем. Чи для цього нам потрібно вікно або дисплей? Звичайно, ні, ви можете самі вказати, куди транслювати ваш результат або не транслювати його взагалі. Але про все по порядку.
Оформлення API та основи
Мабуть, варто почати із найпростішого. Оскільки над Vulkan API працювали Khronous Group, синтаксис дуже схожий на OpenGL. У всьому API є префікс vk. Наприклад функції (іноді навіть з дуже довгими назвами) виглядають так: vkDoSomething(. ), імена структур або хендлів: VkSomething, а всі константні вирази (макроси, макродзвінки та елементи перерахувань): VK_SOMETHING. Також, є особливий вид функцій команди, яким додається префікс Cmd: vkCmdJustDoIt(. ).
Писати на Vulkan можна як C, так і C++. Але другий варіант дасть, звичайно, більше зручності. Є (і створюватимуться) порти іншими мовами. Хтось уже зробив порт на Delphi, хтось бажає (навіщо?) порт на Python.
Отже, як створити рендер контекст? Ніяк. Тут його нема. Натомість придумали інші речі з іншими назвами, які навіть нагадуватимуть DirectX.
Початок роботи та основні поняття
Vulkan поділяє два поняття – це пристрій (device) та хост (host). Пристрій виконуватиме всі команди, надіслані йому, а хост їх надсилатиме. Фактично наш додаток і є хост — у Vulkan така термінологія.
Для роботи з Vulkan нам знадобиться хендли на його екземпляр (instance), і може бути навіть не один, а також на пристрій (device), знову ж таки, не завжди може вистачати одного.
Vulkan може бути легко завантажений динамічно.У SDK (розробили LunarG), якщо був оголошений макрос VK_NO_PROTOTYPES і завантажувати бібліотеку Vulkan своїми руками (не лінковником, а певними засобами в коді), то насамперед потрібна буде функція vkGetInstanceProcAddr, за допомогою якої можна дізнатися адреси основних функцій Vul без екземпляра, включаючи функцію його створення, та функції, які працюють з екземпляром, включаючи функцію його руйнування та функцію створення пристрою. Після створення пристрою можна отримати функції, які працюють із ним (а також його дочірніми хендлами) через vkGetDeviceProcAddr.
Цікавий факт: у Vulkan завжди потрібно заповнити певну структуру даними, щоб створити будь-який об'єкт. І все в Vulkan працює приблизно таким чином: заздалегідь підготував можна використовувати часто і з високою продуктивністю. У інформацію про екземплярі можна також помістити інформацію про вашу програму, версії движка, версії використовуваного API та іншу інформацію.
Шари та розширення
У чистому Vulkan немає сильних перевірок вхідних даних на правильність. Йому сказали щось зробити – він зробить. Навіть якщо це призведе до помилки програми, драйвера або відеокарти. Це зробили заради продуктивності. Тим не менш, можна без проблем підключити перевірочні шари, а також розширення до екземпляра та/або пристрою, якщо це необхідно.
Шари (layers)
В основному, призначення шарів – перевірити вхідні дані на помилки та відстежувати роботу Vulkan. Працюють вони дуже просто: припустимо, викликаємо функцію, і потрапляє вона у верхній шар, заданий при створенні пристрою або екземпляра раніше. Він все перевіряє на правильність, після чого передає виклик у наступний.І так буде, доки справа не дійде до ядра Vulkan. Звичайно, можна створити власні шари. Наприклад, Steam випустила шар SteamOverlay (хоча й не знаю, що він взагалі робить). Тим не менш, шари будуть мовчати, але не доведуть до краху програми. Як дізнатися, чи все правильно зроблено? Для цього є спеціальне розширення!
Розширення (extensions)
Як випливає із назви, вони розширюють роботу Vulkan додатковим функціоналом. Наприклад, одне розширення (debug report) виводитиме помилки (і не тільки) з усіх шарів. Для цього потрібно буде вказати необхідну Callback функцію, а що робити з інформацією, що надійшла в цю функцію вирішувати вже вам. Врахуйте, що це Callback і затримка може дорого обійтися, особливо якщо виводити всю отриману інформацію прямо в консоль. Після обробки повідомлення, можна вказати, передавати виклик функції далі (наступний шар) чи ні — можна уникнути критичних помилок, але постаратися працювати далі з менш небезпечними помилками.
Є також інші розширення, про деякі я розповім пізніше в цій статті.
Пристрій
Vulkan поділяє поняття фізичного устрою та логічного. Фізичним пристроєм може бути ваша відеокарта (і не одна) або процесор, який підтримує графіку. Логічне пристрій створюється на основі фізичного: збирається інформацію про фізичні пристрої, вибирається необхідне, готується інша необхідна інформація та створюється пристрій. Може бути кілька логічних пристроїв на основі одного фізичного, але об'єднувати для єдиної роботи фізичні пристрої (поки що?) не можна.
Отже, що за інформацію ми збираємо? Це, звичайно ж, формати, пам'ять, можливості, що підтримуються, і, звичайно ж, сімейства черг.
Черги (queue) та сімейства черг (queue family)
Пристрій може (або не може) робити наступні 4 речі: малювати графіку, робити різні обчислення, копіювати дані, а також працювати з розрідженою пам'яттю (sparse memory management). Ці можливості представлені у вигляді сімейств черг: кожна родина підтримує певні (можливо все відразу) можливості. І якщо ідентичні сімейства були розділені, Vulkan все одно представить їх як одне сімейство, щоб ми не так сильно страждали з кодом і вибирали потрібну родину.
Після того, як ви вибрали потрібну (або потрібну) родину, з них можна отримати черги. Черги - це місце, куди надходитимуть команди для пристрою (потім пристрій їх братиме з черг і виконуватиме). Черг та сімейств, до речі, не дуже багато. NVIDIA зазвичай має 1 сімейство з усіма можливостями на 16 черг. Після того, як ви закінчили з підбором сімейств та кількістю черг, можна створювати пристрій.
Команди, їх виконання та синхронізація
Усі команди для пристрою поміщаються у спеціальний контейнер – командний буфер. Тобто. немає жодної функції в Vulkan, яка сказала б пристрою зробити щось відразу, і при завершенні операції повернути управління додатком. Є лише функції заповнення командного буфера певними командами (наприклад, намалювати щось або скопіювати зображення). Тільки після запису командного буфера на хості ми можемо його відправити в чергу, яка, як відомо, перебуває у пристрої.
Командний буфер буває двох видів: первинний та вторинний. Первинний вирушає у чергу. Вторинний не може бути відправлений — він запускається у первинному. Записуються команди в такому самому порядку, в якому були викликані функції. У чергу вони надходять у такому порядку. А от здійсняться вони можуть майже в хаотичному порядку. Щоб не було повного хаосу в додатку, розробники Vulkan передбачили засоби синхронізації.
Тепер найважливіше: хост не очікує завершення виконання команд та командних буферів. Принаймні доти, поки не вкажете це явним способом. Після відправлення командних буферів у чергу управління відразу повертається додатку.
Є 4 примітиви синхронізації: паркан (fence), семафор (semaphore), подія (event) та бар'єр (barrier).
Паркан найпростіший метод синхронізації - він дозволяє хосту чекати на виконання певних речей. Наприклад, завершення виконання командного буфера. Але використовується паркан рідко.
Семафор - Спосіб синхронізації всередині пристрою. Не можна подивитися його стан чи почекати його на хості, не можна також чекати його всередині командного буфера, але можемо вказати, який семафор повинен подати сигнал при завершенні виконання всіх команд буфера, і який семафор чекати перед тим, як розпочати виконання команд у буфері. Лише чекатиме не весь буфер, а його певна стадія.
Як уже було сказано, не обов'язково команди у черзі виконаються по порядку. Якщо бути точніше, то наступні команди не чекатимуть на завершення попередніх. Вони можуть виконуватися паралельно, або виконання попередньої команди може завершитися набагато пізніше. І це цілком нормально. Але деякі команди залежать від виконання інших. Ви можете розділити їх на два береги: «до» та «після», а також вказати, які стадії берега «до» повинні обов'язково виконатися (тобто команди можуть завершитися не повністю або не всі), перш ніж почнуть виконуватись зазначені стадії команд берега "після". Наприклад, зображення може призупинитися, щоб зробити певні речі, а потім знову продовжити малювати. Також може бути і ланцюжок залежностей, але не йтимемо глибоко в ліси Сибіру Vulkan.
Події - Елемент «тонкого» налаштування. Подати сигнал можна як з хоста, так і пристрою, чекати можна також і на пристрої, і на хості. Подія визначає залежність двох сетів команд (до і після) у командному буфері. І для події є також спеціальна псевдо-стадія, яка дозволяє чекати на хост.
Бар'єр знову може бути використаний тільки у пристрої, а ще точніше - у командному буфері, оголошуючи залежності першого та другого сету команд. Також можна додатково вказати бар'єри пам'яті, які бувають трьох видів: глобальний бар'єр, бар'єр буфера та бар'єр зображення. Вони не дадуть ненароком прочитати дані, які записуються і/або навпаки, в залежності від зазначених параметрів.
Конвеєри
Нижче показано два конвеєри Vulkan:
Тобто. у Vulkan є два конвеєри: графічний і обчислювальний. За допомогою графічного ми, звичайно ж, можемо малювати, а обчислювальний... обчислювати. Що ще? Результати обчислень можуть потім вирушити до графічного конвеєра. Так можна з легкістю заощадити час на системі частинок, наприклад.
Змінити порядок чи змінити самі стадії конвеєра не можна. Виняток становлять програмовані стадії (шейдери).Також можна відправляти різні дані в шейдери (і не тільки) через дескриптори.
Для конвеєра можна створити кеш, який може бути використаний (знов і знову) і в інших конвеєрах і навіть після перезапуску програми.
Конвеєр необхідно налаштувати та асоціювати з командним буфером, перш ніж останній буде використовувати команди конвеєра.
Так як конвеєр, це фактично вся інформація про те, як потрібно працювати з даними, що надходять, то зміна конвеєра (а це інформація про шейдерів, дескрипторів, растеризації та інше) може дорого обійтися за часом. Тому розробники надали можливість наслідування конвеєра. При зміні конвеєра на дочірній, батьківський або між дочірніми піде менше витрат продуктивності. Але це також і зручність для розробників, наприклад ООП.
Прохід малювання, графічний конвеєр та фреймбуфер
Отже, отримуємо наступну матрьошку:
Щоб можна було використовувати команди отрисовки, потрібен графічний конвеєр. У графічному конвеєрі необхідно вказати прохід малювання (Render Pass), який містить інформацію про підпроходах (subpass), їх залежностей один від одного та прикріплення (attachment). Прикріплення - інформація про зображення, яке буде використовуватися в framebuffer'ах. Framebuffer створюється спеціально для певного проходу малювання. Щоб розпочати прохід, потрібно вказати як сам прохід (а також, якщо потрібно, підпрохід), так і framebuffer. Після початку проходу можна малювати. Можна також перемикатися між підпроходами. Після завершення малювання можна завершити прохід.
Управління пам'яттю та ресурси
Пам'ять у Vulkan розподіляється хостом і тільки хостом (за винятком swapchain).Якщо зображення (або інші дані) потрібно помістити у пристрій, виділяється пам'ять. Спочатку створюється ресурс певних розмірів, потім запитується його вимоги до пам'яті, виділяється йому пам'ять, потім ресурс асоціюється з ділянкою цієї пам'яті і лише потім можна копіювати у ресурс необхідні дані. Також, є пам'ять, яка може бути безпосередньо змінена з хоста (host visible), є локальна пам'ять пристрою (пам'ять відеокарти, наприклад) та також інші види пам'яті, що впливають на швидкість доступу до них.
У Vulkan можна написати свій розподіл пам'яті хоста, налаштувавши Callback функції. Але врахуйте, що вимоги до пам'яті, це її розмір, а й вирівнювання (alignment).
Самі ресурси бувають двох видів: буфери (buffers) та зображення (images). І ті й інші розділяються за призначенням, але якщо буфер — це просто колекція різних даних (вершинний, індексний або буфер констант), то зображення завжди має свій формат.
Виділяйте ділянку пам'яті, куди можете помістити відразу кілька ресурсів. Кількість виділень обмежена і вам може не вистачити. Натомість кількість асоціацій не обмежена.
Шейдери
Vulkan підтримує 6 видів шейдерів: вершинний, контроль тесселяції, аналіз тесселяції, геометричний, фрагментний (він же піксельний) та обчислювальний. Написати їх можна на SPIR-V, що читається, а потім зібрати в байт код, який в додатку ми запечатаємо в модуль, тобто. створимо shader-модуль із цього коду. Звичайно, ми можемо написати його на звичному GLSL і потім конвертувати в SPIR-V (транслятор вже є).І, звичайно, ви можете написати свій транслятор і навіть асемблер — вихідники та специфікації викладені в OpenSource, ніщо не заважає написати вам збирач для свого High Level SPIR-V. А може, хтось уже написав.
Байт-код потім транслюється в команди, специфічні для кожної відеокарти, але робиться це набагато швидше, ніж із сирого GLSL коду. Подібна практика застосовується і в DirectX - HLSL спочатку перетворюються на байт код, і цей байт код може бути збережений і потім використаний, щоб не компілювати шейдери знову і знову.
Вікна та дисплеї
А закінчить цю статтю розповідь про WSI (Window System Integration) та ланцюжок перемикань (swapchain). Для того, щоб виводити щось у вікно або на екран, потрібні спеціальні розширення.
Для вікон це базове розширення площини та розширення площини, специфічної для кожної системи (win32, xlib, xcb, android, mir, wayland). Для дисплея (тобто FullScreen) потрібне розширення display, але загалом і те й інше використовують розширення swapchain.
Ланцюжок перемикань не пов'язаний із графічним конвеєром, тому простий Clear Screen виходить без налаштування всього цього. Все досить просто. Існує певний движок показу (presentation engine), в якому є черга зображень. Одне зображення відображається на екрані, інші чекають своєї черги. Кількість зображень ми можемо також вказати. Існує також кілька режимів, які дозволять дочекатися сигналу вертикальної синхронізації.
Метод роботи приблизно такий: ми запитуємо індекс вільного зображення, викликаємо командний буфер, який скопіює результат із Framebuffer у це зображення, і відправляємо команду про відправлення зображення у чергу.Звучить легко, але з урахуванням того, що буде потрібно синхронізація — все трохи складніше, оскільки єдине, на що очікує хост — це індекс зображення, яке незабаром буде доступним. Командний буфер чекає сигналу семафора, який свідчить про доступність зображення, і потім сам подати сигнал через семафор про те, що виконання буфера, в результаті і копіювання, завершено. І зображення справді надійде у чергу за сигналом останнього семафору. Всього два семафори: про доступність зображення для копіювання та доступність зображення для показу (тобто про завершення копіювання).
До речі, я перевірив, що один і той же командний буфер справді вирушав у чергу кілька разів. Можете подумати самі, що це означає.
У цій статті я спробував розповісти про найважливіші частини Vulkan API, але багато що все ще не розказано і це ви можете дізнатися самі. Стабільного вам FPS та приємного кодингу.