Privacy policyContactsAbout siteOpinionsGitHubDonate
© EVILEG 2015-2018
Recommend hosting
TIMEWEB

Qt и Direct3D 12 - Первая встреча

D3D12, Direct3D, Qt, Qt Blog, QtD3D12Window

Перевод официальной новости, автор 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 и предлагаемой ей экосистемой.

What it is

QtD3D12Window module, находится в qt-labs репозитории, и является модулем Qt 5.6, который предоставляет QD3D12Window класс, похожий на QOpenGLWindow,  обрабатывается qmake правилом для компиляции HLSL шейдера через fxc, и имеет исчерпывающий комплект примеров для основного использования (наподобие Hello World samples от Microsoft).

What it is not

Прежде, чем пойти дальше, давайте разберёмся, чем этот модуль не является: он не является способом запускать существующие Qt приложения на Direct3D (то есть именно, что предоставляет ANGLE , когда дело доходит до D3D9 и 11), и в любом случае не поддерживает Qt Quick. Это также не является дополнением к Qt в его нынешнем виде, и не является полным движком и фреймворком в любом его виде (интерфейс QD3D12Window явно предлагает недостаточный функционал для сложных и многопоточных решений).

Window

Первым шагом для интеграции с пользовательским кодом рендеринга является новое графическое 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, и т.д.).

Class

QD3D12Window является зеркалом QOpenGLWindow, который в свою очередь основан на QOpenGLWidget/QGLWidget и методы initializeGL – resizeGL – paintGL, с GL переименованы на D3D, соответственно. Имеются две новых функции подклассов, которые могут быть реализованы: releaseD3D и afterPresent. Последняя вызывается каждый раз после выдачи Present call: большинство простых приложений будут ожидать GPU в этой функции. Первая же используется для того, чтобы приложение могло выжить при удалении устройства: когда графическое устройство становится недоступным, эта функция вызывается и выполняется при освобождении ресурсов во время инициализации/перерисовки/изменении размера. QD3D12Window будет затем запускать initializeD3D заново. В этом случае приложение может оставаться функциональным при обновлении драйвера или ожидании исполнения шейдеров.

Лучше, конечно, показать на примере. Взглянем на hellotriangle, который показывает, что если вы использовали раньше  QOpenGLWindow или QOpenGLWidget, то использование QD3D12Window не будет для Вас сюрпризом.

Widgets

Итак, теперь на нашем окне Мы не имеем ничего, кроме содержания отрисованного D3D12. Это отлично, но что там делают традиционные элементы управления? Этого можно добиться с QD3D12Window, сделав дочернее окно через QWidget::createWindowContainer(). Это связано с обычными ограничениями, о которых Вам в первую очередь следует прочитать в документации. Тем не менее это будет отлично работать для самых простых целей.

Shaders

Обработка кода шейдеров и их компиляция является другой интересной темой. С  OpenGL в Qt и Qt Quick делается ставка на runtime компиляцию из-за того, что это является единственным общедоступным решением не зависящим от производителей и особенностей платформ. С другими графическими API в будущем, ожидается, что Qt больше сфокусируется на автономной компиляции, и интеграции в систему сборки настолько, насколько это возможно. Помимо очевидных преимуществ в производительности это значительно улучшает рабочий процесс разработки: получение компилятором информации об ошибках во время сборки при запуске через Ctrl+B, в Qt Creator сможете легко почувствовать, как новый способ превосходит "старый" путь отладки во время работы приложения.

QtD3D12Window модуль поставляется с простым правилом qmake, которое позволяет вызывать fxc.exe во время сборки. Все примеры используют его для создания заголовочных файлов, где компилируется байт-код, представляющий собой массив символов. Взгляните на .pro файл одного из них и настройку shader.

Это не является совершенно новым Qt: комплект ANGLE в qtbase выполняет компиляцию шейдеров тем же способом. Однако,  то что скрыто не может быть использовано в коде на прикладном уровне D3D, как файл hlsl.prf здесь, то может быть скопировано в папку mkspecs/features в Qt SDK, что сделает его доступным для любого Qt приложения.

Graphics Debugging

QD3D12Window автоматически включает уровень отладки D3D12. Это является невероятно полезным с точки зрения множества обычных ошибок, совершаемых при старте работы с D3D12, особенно, когда получаете полезные отладочные сообщения. Однако, вы можете отключить их, когда встанет вопрос о тестировании производительности.

Другим полезным инструментов является graphics debugger включённый в Visual Studio. Одним из способов запустить Qt приложение является выполнение devenv /debugexe qtapplication.exe из командной строки разработчика и нажатие Alt+F5. (в качестве альтернативы, создание файлов проекта Visual Studio с qmake -tp vc может также хорошо работать). Он оказался весьма полезным во время разработки простых примеров – например, его возможность посмотреть графические ресурсы и также посмотреть, правильно ли сформированы уровни MIPMAP.

Примеры

Как упоминалось раннее, модуль поставляется с комплектом примеров, которые охватывают основы и могут быть полезны для начала разработки с D3D12. Смотрите readme файл для ознакомления.

Источник Qt Blog .

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Comments

Only authorized users can post comments.
Please, Log in or Sign up
МБ
April 21, 2019, 9:40 a.m.
Моисей Бушуев

Qt - Test 001. Signals and slots

  • Result:0points,
  • Rating points-10
AA
April 17, 2019, 7:40 p.m.
Anton Ablin

Qt - Test 001. Signals and slots

  • Result:73points,
  • Rating points1
E
April 17, 2019, 6:16 p.m.
Evgeny

Qt - Test 001. Signals and slots

  • Result:100points,
  • Rating points10
Last comments
April 21, 2019, 4:22 p.m.
Евгений Легоцкой

Через метод setIcon table.horizontalHeaderItem(0).setIcon("qrc://path/to/icon.png")
April 21, 2019, 3:48 p.m.
Евгений Легоцкой

Добрый день! Спасибо за комментарий. Там действительно лучше будет сделать с инициализацией по умолчанию.
U
April 18, 2019, 3:37 p.m.
Unreal_man

А как иконку в хедер задать?
u
April 18, 2019, 2:15 a.m.
uaa

доброго времени,большое спасибо за пример для начинающего)при адаптации к своему проекту столкнулся с таким ньансом:в vepolyline.h в 47 строке нужна инициализация по умолчанию: int m_pointF...
E
April 11, 2019, 12:49 p.m.
Evgeny

Спасибо за ответ) У меня компоновщик на нее ругался просто. Оказалось, просто забыл Q_OBJECT в начале класса указать.
Now discuss on the forum
April 24, 2019, 11:22 a.m.
Ruslan Polupan

Согласен. но ситуация не поменялась. Такое чуство что данные не записываются в модель.
April 24, 2019, 6:20 a.m.
Ruslan Polupan

я так понимаю надо инфорация об устройствах.Я бы пробовал так rust@suse:~> lsblk -PNAME="sda" MAJ:MIN="8:0" RM="0" SIZE="111,8G" RO="0" TYPE="disk" MOUNTPOINT=""NAME="sda1" MAJ:MIN="8...
April 21, 2019, 4:16 p.m.
Евгений Легоцкой

Приветствую Нужно сохранять где-то выбранное значение, а потом восстанавливать его. Или использовать QSettings или добавить метод open(), в который передавать начальные значения для того...
R
April 19, 2019, 9:55 a.m.
RED_Spider

мені важко це зараз навіть перевірити, тому що знайшов коміт, це ще було в 2016 році, і цей код не буде працювати коректно зараз, єдине скажу що це були QThread
Join us in social networks

For registered users on the site there is a minimum amount of advertising