Я работаю над приложением QT, для которого я интегрировал DirectX 11 в пользовательский виджет. Приложение отображает прокрутку — графическое представление данных, считываемых из файла. Пользователь может ускорять и замедлять скорость прокрутки.
По большей части это работает отлично. Рендеринг DirectX 11 отображается в моем пользовательском виджете, как я и ожидал. Проблема в том, что графический драйвер случайным образом зависает и вылетает моя программа. Я говорю «случайно», потому что я тестировал это с одним и тем же файлом данных, и он никогда не зависает в одной и той же точке файла, по прошествии определенного времени или с определенной скоростью прокрутки (чем выше скорость прокрутки, тем больше работу, выполняемую графическим процессором за кадр).
Когда приложение зависает, мой экран на мгновение зависает, становится черным, а затем возвращается с приятным сообщением от NVidia о том, что оно восстановилось после сбоя драйвера. Выходные данные отладки в Visual Studio содержат следующее:
D3D11: Удаление устройства.
ОШИБКА D3D11: ID3D11Device::RemoveDevice: Удаление устройства было инициировано по следующей причине (DXGI_ERROR_DEVICE_HUNG: Устройству потребовалось неоправданное количество времени для выполнения своих команд, или произошло сбой/зависание оборудования. В результате TDR (обнаружение тайм-аута и Восстановление) был запущен. Текущий контекст устройства выполнял команды, когда произошло зависание. Приложение может захотеть перезапуститься и вернуться к менее агрессивному использованию аппаратного обеспечения дисплея). [ОШИБКА ВЫПОЛНЕНИЯ #378: DEVICE_REMOVAL_PROCESS_AT_FAULT]
Я обнаружил, что просто закомментировав вызов IDXGISwapChain1::Present, приложение будет работать с файлом с молниеносной скоростью. С точки зрения графики он по-прежнему передает данные в графический процессор и рисует для целей рендеринга, он просто никогда не отображается в моем окне.
Я надеюсь на помощь с идеями о том, какие типы вещей вызывают зависание драйвера. Мои шейдеры невероятно просты — в основном я просто позиционирую вершины с помощью проекционной матрицы. И, учитывая то, что я описал в предыдущем абзаце, шейдеры все равно должны проходить через вершины и пиксели, даже когда Present не вызывается, да?
Я подозревал, что это может быть проблема совместимости с Qt — я знаю, что Qt официально не поддерживает DirectX. Поэтому я попытался создать отдельное окно с помощью CreateWindowEx и использовать его для своей цепочки обмена вместо пользовательского виджета Qt. Он отображался в этом окне, но также зависал драйвер, как и раньше.
Я также подозревал ошибку драйвера в моем ноутбуке, поэтому я попытался запустить приложение на более мощном настольном ПК, который регулярно запускает другое приложение DirectX 11 (не Qt) без заминок (стоит упомянуть, что это другое приложение отображает аналогичные данные в прокрутки, используя гораздо более сложные шейдеры). Но мое приложение QT также зависает на этом ПК.
Кто-нибудь знает, как я могу получить более подробное описание того, что заставляет драйвер зависать?
Заранее благодарим вас за любую помощь, которую вы можете предложить.
ОБНОВЛЕНИЕ: 01.08.2013, 17:16 CST В настоящее время я изучаю возможную проблему с синхронизацией потоков, которая может быть причиной. Продолжу завтра утром и опубликую, если решу это самостоятельно.