Потерянные устройства (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 потерянное устройство требует повторного создания шейдеров.
Связанные разделы