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

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

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

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

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

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

Устройства Direct3D