Приложение DirectX 11 резко замедляется, если оно не является приложением переднего плана

#directx #desktop-duplication

#directx #рабочий стол-дублирование

Вопрос:

У меня есть приложение, которое выполняет некоторое рисование через Direct2D и захватывает содержимое экрана через API дублирования рабочего стола. Это приложение на C #, но у меня есть настраиваемые многоуровневые окна для отображения, и я выполняю рендеринг через Direct2D, чтобы обойти «умное» рисование в WPF, которое ранее заставляло мое приложение не очень агрессивно конкурировать за графические ресурсы.

Если я запускаю это приложение одновременно с игрой DirectX, которая требует много графических ресурсов, то поведение, которое я получаю, выглядит следующим образом:

  1. если мое приложение является приложением переднего плана, оно работает нормально
  2. если мое приложение видно, но не приложение переднего плана, то вызовы Map Subresource и Copy Resource занимают очень разное время, иногда блокируясь на сотни миллисекунд (в соответствии с профилировщиком).) Я не уверен, что считаю, что выбросы исчисляются сотнями, но, безусловно, Map Subresource составляет в среднем 50 мс, поэтому скорость захвата падает ниже 20 кадров в секунду. При запуске на переднем плане один и тот же вызов занимает в среднем 4 мс.

Я уже проверял, может ли манипулирование приоритетами процессов и потоков что-либо сделать, но это не так. Похоже, что DirectX ограничивает мои данные, когда я не на переднем плане, независимо от приоритетов. Это проблема, потому что мое приложение должно работать с полной частотой кадров, не будучи передним планом.

Если он строго определяет приоритеты команд GPU из приложения переднего плана, то я мог видеть, что, возможно, мое приложение испытывает недостаток в каналах для / из GPU, потому что это объясняет такую остановку. Если бы я мог каким-то образом освободить это приложение от такой политики, это было бы оптимально. Например, какая-то запись в манифесте или вызов DirectX, который уведомляет драйвер (или стек) не считать мое приложение фоновым?

Я сравнил код OBS (насколько я могу разобраться), и я не вижу, что они делают по-другому. Как OBS удается продолжать дублирование / захват, даже если они явно не являются приложением переднего плана при потоковой передаче даже требовательных игр?

[править]

Рассматриваемая игра — DCS, которая всегда использует все доступные ресурсы графического процессора, если вы позволите, и использует около 1,5 ядер. Когда я говорю, что оно начинает замедляться, когда оно не находится на переднем плане, я буквально говорю о щелчке по окну из моего приложения по сравнению с щелчком в окне игры (даже без минимизации или чего-либо еще).) Когда я нахожусь на переднем плане, DCS замедляется по мере потребления ресурсов. Если DCS находится на переднем плане, он продолжает отображать на полной скорости и использует все ресурсы, и мой захват замедляется.

Я обнаружил, что могу заставить все работать хорошо, если я просто ограничу DCS до 60 кадров в секунду через vsync, чтобы он не мог использовать все ресурсы. Тогда все работает отлично. Очевидно, что это не решает проблему, но это дополнительно показывает, что, скорее всего, это какая-то проблема с ресурсами. Я в порядке, конкурируя за ресурсы, но, похоже, приоритет отдается приложению переднего плана в DirectX (или драйверу Nvidia?)

[/ править / править код]

Комментарии:

1. Это довольно неожиданно. Вы уверены, что у вас нет какой-либо третьей стороны, которая могла бы это сделать? Делает ли это то же самое с официальным образцом Microsoft ( github.com/microsoft/Windows-classic-samples/tree/master /… )? Вы пробовали использовать другое оборудование для видеокарты (NVidia против AMD против Intel против программного обеспечения)? Другой компьютер? Еще одна игра? Вы включили уровень отладки DirectX и проверили, что у вас нет сообщений?

2. @SimonMourier это хороший совет. Программа-пример структурно отличается тем, что она не возвращает захваченный кадр в центральный процессор для редактирования, а просто использует текстуру для рендеринга каждого грязного прямоугольника в виде текстурированного прямоугольника. Это означает, что технически оно может оставаться на карте, если вывод и запись отображаются на той же видеокарте. У меня нет возможности тестировать с другими видеокартами, так как у меня просто куча видеокарт nvidia :). Заставить его работать с другой игрой мне не помогло бы, на самом деле, поскольку я пишу дополнение к этой конкретной игре. [см. Редактирование вопроса]

3. PS: для ясности: да, я протестировал образец программы, и у него нет такой же проблемы, но тогда он не пытается отобразить текстуру обратно на процессор

4. Также ничего из DirectX debug. Моим следующим шагом будет взломать собственный образец приложения, чтобы делать в основном то, что я делаю, и посмотреть, наблюдаю ли я такое же замедление / конфликт.

5. Если официальный образец работает нормально, вероятно, это по какой-то причине ваш код вызывает это. Трудно сказать больше без некоторых воспроизводящих битов.

Ответ №1:

Я столкнулся с точно такой же проблемой и обнаружил, что это связано с функцией игрового режима Window. Выключение и перезагрузка исправили это для меня.

Кроме того, я использовал видеопроцессор Direct x для масштабирования своих изображений, и его производительность сильно не соответствует различным обновлениям драйверов, поэтому сейчас я решил использовать «как есть» без масштабирования.