2013-08-01 5 views
1

Я работаю над приложением QT, для которого я интегрировал DirectX 11 в собственный виджет. Приложение отображает прокручивающийся дисплей - графическое представление данных, считываемых из файла. Пользователь может ускорить и замедлить скорость прокрутки.Как определить причину возникновения драйвера DirectX 11

По большей части, это отлично работает. DirectX 11 рендеринга представлен моему пользовательскому виджету так же, как я ожидал. Проблема в том, что графический драйвер случайно зависает и выдает из строя мою программу. Я говорю «случайный», потому что я тестировал это с одним и тем же файлом данных, и он никогда не сбой в той же точке в файле, через определенное время или с определенной скоростью прокрутки (чем быстрее скорость прокрутки, тем больше работы выполняется на GPU на кадр).

Когда приложение зависает, мой экран замерзает на мгновение, идет черным, а затем возвращается с хорошим сообщением от NVidia о том, что он восстановился после сбоя драйвера. Выход отладки в Visual Studio содержит следующее:

D3D11: Removing Device.

D3D11 ERROR: ID3D11Device::RemoveDevice: Device removal has been triggered for the following reason (DXGI_ERROR_DEVICE_HUNG: The Device took an unreasonable amount of time to execute its commands, or the hardware crashed/hung. As a result, the TDR (Timeout Detection and Recovery) mechanism has been triggered. The current Device Context was executing commands when the hang occurred. The application may want to respawn and fallback to less aggressive use of the display hardware). [ EXECUTION ERROR #378: DEVICE_REMOVAL_PROCESS_AT_FAULT]

Я обнаружил, что просто закомментировать IDXGISwapChain1 :: Present вызов, приложение будет запускаться через файл в молниеносной скоростью. Графически он все еще нажимает данные на графический процессор и рисует для рендеринга цели, он просто не отображается в моем окне.

Я надеюсь, что это поможет с идеями о том, какие типы вещей вызывает зависание драйверов. Мои шейдеры невероятно просты - в основном просто позиционируют мои вершины с помощью матрицы проекций. И учитывая то, что я описал в предыдущем абзаце, шейдеры все равно должны прокручиваться через вершины и пиксели, даже если Present не вызывается, да?

Я был подозрительным, что это может быть проблема совместимости с Qt. Я знаю, что DirectX официально не поддерживается Qt. Поэтому я попытался создать отдельное окно с помощью CreateWindowEx и использовать его для моей своп-цепи вместо пользовательского виджета Qt. Он отобразился в этом окне, но также повесил драйвер так же, как и раньше.

Я также подозрительно относился к ошибке с драйвером на своем ноутбуке, поэтому я попытался запустить приложение на настольном ПК Beefier, который регулярно запускает другое приложение DirectX 11 (без Qt) без заминки (стоит упомянуть, что это другое приложение отображает аналогичные данные на дисплее прокрутки, с использованием более сложных шейдеров). Но мой QT-приложение зависает и на этом ПК.

Кто-нибудь знает, как я могу получить более подробное описание того, что вызывает зависание драйвера?

Благодарим вас за любую помощь, которую вы можете предложить.

UPDATE: 2013-08-01 17:16 CST В настоящее время я изучаю возможную проблему синхронизации потоков, которая может быть виновницей. Будет продолжаться завтра утром и пост, если я решит это самостоятельно.

+0

У вас включен отладочный слой? Вы пытались использовать устройство Reference, а также WARP, чтобы узнать, воспроизводятся ли эти проблемы на этих двух устройствах? –

+0

Я попробовал устройство REF, которое было болезненно медленным, но там все еще происходило. Не пробовал WARP - не могу сказать, что я знаком с этим типом устройства. –

+0

Ну, если он висит на контрольном устройстве, то он, вероятно, будет висящим на любом устройстве. –

ответ

2

После некоторого тестирования сегодня, похоже, проблема с резьбой. Сегодня я работал несколько раз без графического сбоя. Поэтому моя проблема должна быть исправлена, если только мне не повезло с моими испытаниями сегодня (или, к сожалению, не повезло - если это показывает свое уродливое лицо снова через день или два).

Я знал, что непосредственный контекст устройства не является потокобезопасным. Однако вместо использования отложенных контекстов я использовал критические разделы для синхронизации моих потоков и координации использования контекста устройства. Я не понял, что небезопасно вызывать IDXGISwapChain1 :: Present, в то время как другой поток использует контекст устройства. Имеет смысл, но поскольку он не вызывается непосредственно из контекста устройства, я его не замечал.Я буквально переместил вызов Present() несколькими строками в мой критический блок секций, и с тех пор он не дал мне сбой.

+0

+1 для экономии времени на царапину головы - у меня была точно такая же проблема, фоновые потоки загружали текстуры и синхронизировались вокруг контекста, но я также не осознавал необходимость защиты вызова «Present». Простое исправление и очень ценится. Благодаря! –