Поделиться через


Потерянные устройства (Direct3D 9)

Устройство Direct3D может находиться в рабочем состоянии или в потерянном состоянии. Рабочее состояние — это нормальное состояние устройства, в котором выполняется устройство и отображает все отрисовки должным образом. Устройство переходит в потерянное состояние, когда событие, например потеря фокуса клавиатуры в полноэкранном приложении, приводит к невозможности отрисовки. Потерянное состояние характеризуется автоматическим сбоем всех операций отрисовки, что означает, что методы отрисовки могут возвращать коды успешности, даже если операции отрисовки завершаются сбоем. В этой ситуации код ошибки D3DERR_DEVICELOST возвращается IDirect3Device9::P resent.

При разработке полный набор сценариев, который может привести к потере устройства, не указан. Некоторые типичные примеры включают потерю фокуса, например при нажатии клавиш ALT+TAB или при инициализации системного диалога. Устройства также могут быть потеряны из-за события управления питанием или когда другое приложение предполагает полноэкранную операцию. Кроме того, любой сбой из IDirect3Device9::Reset помещает устройство в потерянное состояние.

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

  • Сбой с D3DERR_DEVICELOST . Это означает, что приложение должно распознать, что устройство потеряно, чтобы приложение идентифицировало, что что-то не происходит должным образом.
  • Автоматически завершается сбоем, возвращая S_OK или любые другие коды возврата. Если функция автоматически завершается сбоем, приложение обычно не может различать результат "успешности" и "автоматический сбой".
  • Функция возвращает код возврата.
Различия между Direct3D 9 и Direct3D 9Ex:
Устройство Direct3D 9 возвращает D3DERR_DEVICELOST. После возврата из IDirect3Device9::P resentповедение эмуляции больше не работает, и все будущие вызовы завершаются ошибкой, пока устройство не будет успешно сброшено.
Устройство Direct3D 9Ex никогда не возвращает D3DERR_DEVICELOST, но может возвращать новые сообщения о состоянии (см. изменения поведения устройства).

 

Реагирование на потерянное устройство

Потерянное устройство должно повторно создать ресурсы (включая ресурсы памяти видео) после сброса. Если устройство потеряно, приложение запрашивает устройство, чтобы узнать, можно ли восстановить его в рабочем состоянии. Если нет, приложение ожидает восстановления устройства.

Если устройство можно восстановить, приложение подготавливает устройство, уничтожая все ресурсы видео-памяти и любые цепочки буферов. Затем приложение вызывает метод IDirect3Device9::Reset. Сброс является единственным методом, который имеет влияние при потере устройства и является единственным методом, с помощью которого приложение может изменить устройство с потерянного на рабочее состояние. Сброс завершится ошибкой, если приложение не освобождает все ресурсы, выделенные в D3DPOOL_DEFAULT, включая созданные методами IDirect3Device9::CreateRenderTarget и IDirect3Device9::CreateDepthStencilSurface.

В большинстве случаев высокочастотные вызовы Direct3D не возвращают никаких сведений о том, было ли потеряно устройство. Приложение может продолжать вызывать методы отрисовки, такие как IDirect3DDevice9::D rawPrimitiveбез получения уведомления о потерянном устройстве. Внутри системы эти операции удаляются до тех пор, пока устройство не будет сброшено в рабочее состояние.

Приложение может определить, что делать при обнаружении потерянного устройства, запрашивая возвращаемое значение метода IDirect3Device9::TestCooperativeLevel.

Операции блокировки

Внутри системы Direct3D делает достаточно работы, чтобы убедиться, что операция блокировки завершится успешно после потери устройства. Однако не гарантируется, что данные ресурса видео-памяти будут точными во время операции блокировки. Гарантируется, что код ошибки не будет возвращен. Это позволяет создавать приложения без проблем с потерей устройства во время операции блокировки.

Ресурсы

Ресурсы могут использовать память видео. Так как потерянное устройство отключено от памяти видео, принадлежащей адаптеру, невозможно гарантировать выделение памяти видео при потере устройства. В результате все методы создания ресурсов реализуются для успешного выполнения путем возврата D3D_OK, но на самом деле выделяют только фиктивную системную память. Так как перед изменением размера устройства необходимо уничтожить любой ресурс видео-памяти, проблема чрезмерного выделения памяти видео не возникает. Эти фиктивные поверхности позволяют выполнять операции блокировки и копирования обычно, пока приложение не вызывает IDirect3Device9::P resent и обнаруживает, что устройство потеряно.

Перед сбросом устройства из потерянного состояния в рабочее состояние необходимо освободить всю память видео. Это означает, что приложение должно выпускать все цепочки буферов, созданные с IDirect3Device9::CreateAdditionalSwapChain и все ресурсы, размещенные в классе памяти D3DPOOL_DEFAULT. Приложению не нужно выпускать ресурсы в D3DPOOL_MANAGED или D3DPOOL_SYSTEMMEM классах памяти. Другие данные состояния автоматически уничтожаются переходом к рабочему состоянию.

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

Извлеченные данные

Direct3D позволяет приложениям проверять состояния текстуры и отрисовки на основе одного прохода оборудованием с помощью IDirect3Device9::ValidateDevice. Этот метод, который обычно вызывается во время инициализации приложения, возвращает D3DERR_DEVICELOST, если устройство было потеряно.

Direct3D также позволяет приложениям копировать созданные или ранее записанные образы из ресурсов видео-памяти в ресурсы нестандартной системной памяти. Так как исходные образы таких передач могут быть потеряны в любое время, Direct3D позволяет выполнять такие операции копирования при потере устройства.

В отношении асинхронных запросов IDirect3DQuery9::GetData возвращает D3DERR_DEVICELOST, если указан флаг FLUSH, чтобы указать приложению, что IDirect3DQuery9::GetData никогда не будет возвращать S_OK.

Операция копирования IDirect3DDevice9::GetFrontBufferDataможет завершиться ошибкой D3DERR_DEVICELOST, так как при потере устройства нет основной поверхности. IDirect3Device9::CreateAdditionalSwapChain также может завершиться ошибкой с D3DERR_DEVICELOST, так как резервный буфер невозможно создать при потере устройства. Обратите внимание, что эти случаи являются единственным экземпляром D3DERR_DEVICELOST за пределами IDirect3Device9::P resent, IDirect3Device9::TestCooperativeLevelи методов IDirect3Device9::Reset.

Программируемые шейдеры

В Direct3D 9 шейдеры вершин и шейдеры пикселей не нужно повторно создавать после сброса. Они будут помнить. В предыдущих версиях DirectX потерянное устройство требует повторного создания шейдеров.

устройства Direct3D