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

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

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

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

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

 

Реакция на потерю устройства

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

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

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

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

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

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

Ресурсы

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

Перед переводом устройства из потерянного состояния в рабочее вся видеопамять должна быть освобождена. Это означает, что приложение должно освободить все цепочки буферов, созданные с помощью IDirect3DDevice9::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, так как при потере устройства нет основной поверхности. IDirect3DDevice9::CreateAdditionalSwapChain также может завершиться сбоем с D3DERR_DEVICELOST, так как не удается создать задний буфер при потере устройства. Обратите внимание, что эти случаи являются единственным экземпляром D3DERR_DEVICELOST за пределами методов IDirect3DDevice9::P resent, IDirect3DDevice9::TestCooperativeLevel и IDirect3DDevice9::Reset .

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

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

Устройства Direct3D