- 1. Що це
- 2. Чим це не є
- 3. Вікно
- 4. Клас
- 5. Віджети
- 6. Шейдери
- 7. Налагодження графіки
- 8. Приклади
Переклад офіційної новини, автор Laszlo Agocs
Особа графічних API змінюється. Qt Quick 2 був випущений у 2012 році з Qt 5.0 і спирався на OpenGL і OpenGL ES 2.0. З тих пір були введені зміни та покращення - був введений Qt Quick 2D Renderer, були проведені експерименти з програмною розтеризацією, та додано систему забезпечення для новітніх версій OpenGL у весь графічний стек Qt. Однак, як зауважив Lars у своєму виступі на Всесвітньому саміті Qt 2015, ситуація змінюється: нові, низькорівневі, ефективніші API, такі як Vulkan, Metal та Direct3D 12, мають намір стати широко доступними. Деякі з них орієнтовані на конкретні платформи, роблячи їх найкращим вибором у питанні таргетування на конкретні платформи, тоді як інші, як очікується, будуть підтримувати широкий спектр платформ. У той же час, роблячи комплексні прогнози, прискорення з графічним API не завжди є найкращим вибором: традиційно, робочий стіл інтерфейсу користувача на застарілому залозі іноді краще запустити зі застарілим відмальовуванням на базі CPU.
Таким чином, що не дивно, одним із напрямків досліджень у майбутніх версіях Qt є створення графічного стек, і зокрема, Qt Quick, більш гнучким, з підтримкою різних графічних API, а також з підтримкою програмного рендерингу.
Такі дослідження часто призводять до корисних ефектів, і цей запис про одне таке. Простий Qt модуль включає інтеграцію з Direct3D 12 в окремому Qt вікні - або в якості альтернативи додаток заснований на QWidget - і робить це процес легким для початку експериментів із сучасними методами D3D, в той час як Ви продовжуєте насолоджуватися знайомими API, інструментами та середовищем розробки Qt та пропонованої їй екосистемою.
Що це
QtD3D12Window module, знаходиться в qt-labs репозиторії, і є модулем Qt 5.6, який надає QD3D12Window клас, схожий на QOpenGLWindow, обробляється qmake правилом для компіляції HLSL шейдера через fxc, і має вичерпний приклад. ).
Чим це не є
Перш ніж піти далі, давайте розберемося, чим цей модуль не є: він не є способом запускати існуючі Qt програми на Direct3D (тобто саме, що надає ANGLE , коли справа доходить до D3D9 і 11), і в жодному разі не підтримує Qt Quick. Це також не є доповненням до Qt у його нинішньому вигляді, і не є повним двигуном та фреймворком у будь-якому його вигляді (інтерфейс QD3D12Window явно пропонує недостатній функціонал для складних та багатопотокових рішень).
Вікно
Першим кроком для інтеграції з кодом рендерингу є нове графічне API, яке створює мету рендерингу в нативному вікні заснованому на QWindow. В даний час OpenGL є єдиним вибором і глибокого інтегрований в Qt як внутрішньо (QPA інтерфейси, плагіни платформи), так і зовні (публічні API, див QOpenGL класи в QtGui). Очікується, що це зміниться в майбутньому, але зараз для нашого автономного експерименту з D3D ми зробимо все самостійно. Платформенний плагін вікна в Qt дозволяє легко отримати нативний дескриптор вікна, ніби ми використовували QWindow::winId(), який повертає id вікна в Windows в Qt додаток. Ми можемо використовувати DXGI для перерахування доступних адаптерів, і можемо вибрати або апаратний, або WARP адаптер, і створити ланцюжок підкачки (swap). QD3D12Window обробить все це, причому досить добре для основних типових додатків.
Говорячи про DXGI, відзначимо, що це перший подібний набіг на графічний адаптер та керування пристроєм: у той час як з OpenGL та його віконними інтерфейсами зазвичай такі можливості обмежені, інші ж API (особливо платформозалежні та прив'язані до певної моделі драйвера) можуть пропонувати більше можливостей з пошуку адаптерів та внесення змін до налаштувань, видалення скидання протягом життєвого циклу програми. Така функціональність на тих платформах, де доступні API, отримає більше уваги Qt в майбутньому.
При реалізації QD3D12Window, з'ясувалося, що не потрібно створювати будь-який загальний клас - завдяки тому, що QOpenGLWindow і QRasterWindow були введені в Qt 5.4: Загальний базовий клас QPaintDeviceWindow що, звичайно вводить в оману у випадку з D3D, оскільки наше вікно малювання, заснованої на QPainter) надає всю необхідну інфраструктуру, що дозволяє сфокусуватися в підкласі на особливості графічного API розробки основного функціоналу, такого як метод update(). Це хороші новини, що цей доробок дозволяє легко експериментувати з іншими API в майбутньому (QMetalWindow, QVulkanWindow, і т.д.).
Клас
QD3D12Window є дзеркалом QOpenGLWindow, який у свою чергу заснований на QOpenGLWidget/QGLWidget та методи initializeGL – resizeGL – paintGL, з GL перейменовані на D3D відповідно. Є дві нові функції підкласів, які можуть бути реалізовані: releaseD3D і afterPresent. Остання викликається щоразу після видачі Present call: більшість простих програм чекатимуть GPU у цій функції. Перша використовується для того, щоб програма могла вижити при видаленні пристрою: коли графічний пристрій стає недоступним, ця функція викликається і виконується при звільненні ресурсів під час ініціалізації/перемальовки/зміни розміру. QD3D12Window буде потім запускати initializeD3D заново. У цьому випадку програма може залишатися функціональною при оновленні драйвера або очікуванні виконання шейдерів.
Краще, звісно, показати на прикладі. Поглянемо на hellotriangle, який показує, що якщо ви використовували раніше QOpenGLWindow або QOpenGLWidget, то використання QD3D12Window не буде Вам сюрпризом.
Віджети
Отже, тепер у нашому вікні Ми не маємо нічого, крім змісту відмальованого D3D12. Це добре, але що там роблять традиційні елементи управління? Цього можна досягти з QD3D12Window, зробивши дочірнє вікно через QWidget::createWindowContainer(). Це пов'язано із звичайними обмеженнями, про які Вам насамперед слід прочитати у документації. Проте це буде чудово працювати для найпростіших цілей.
Шейдери
Обробка коду шейдерів та його компіляція є іншою цікавою темою. З OpenGL у Qt і Qt Quick робиться ставка на runtime компіляцію через те, що це є єдиним загальнодоступним рішенням, що не залежить від виробників та особливостей платформ. З іншими графічними API в майбутньому очікується, що Qt більше сфокусується на автономній компіляції, і інтеграції в систему складання настільки, наскільки це можливо. Крім очевидних переваг у продуктивності це значно покращує робочий процес розробки: отримання компілятором інформації про помилки під час складання при запуску через Ctrl+B, Qt Creator зможете легко відчути, як новий спосіб перевершує "старий" шлях налагодження під час роботи програми.
QtD3D12Window модуль поставляється з простим правилом qmake, яке дозволяє викликати fxc.exe під час збирання. Всі приклади використовують його для створення заголовних файлів, де компілюється байт-код, що є масивом символів. Подивіться на .pro файл одного з них та налаштування shader.
Це не є абсолютно новим Qt: комплект ANGLE qtbase виконує компіляцію шейдерів тим же способом. Однак, що приховано не може бути використане в коді на прикладному рівні D3D, як файл hlsl.prf . prf) тут, то може бути скопійовано в папку mkspecs/features у Qt SDK, що зробить його доступним для будь-якої програми Qt.
Налагодження графіки
QD3D12Window автоматично включає рівень налагодження D3D12. Це є неймовірно корисним з точки зору безлічі звичайних помилок, що здійснюються при старті роботи з D3D12, особливо коли отримуєте корисні налагоджувальні повідомлення. Однак, ви можете відключити їх, коли постане питання про тестування продуктивності.
Іншим корисним інструментом є graphics debugger включений до Visual Studio. Одним із способів запустити Qt програму є виконання devenv /debugexe qtapplication.exe з командного рядка розробника та натискання Alt+F5. (як альтернатива, створення файлів проекту Visual Studio з qmake -tp vc може також добре працювати). Він виявився дуже корисним під час розробки простих прикладів – наприклад, його можливість подивитися графічні ресурси та також подивитися, чи правильно сформовані рівні MIPMAP.
Приклади
Як згадувалося раніше, модуль поставляється з комплектом прикладів, які охоплюють основи і можуть бути корисними для початку розробки з D3D12. Дивіться readme файл для ознайомлення.
Источник Qt Blog .