Dispositivos perdidos (Direct3D 9)

Un dispositivo Direct3D puede estar en un estado operativo o en un estado perdido. El estado operativo es el estado normal del dispositivo en el que se ejecuta el dispositivo y presenta toda la representación según lo previsto. El dispositivo realiza una transición al estado perdido cuando un evento, como la pérdida de foco del teclado en una aplicación de pantalla completa, hace que la representación sea imposible. El estado perdido se caracteriza por el error silencioso de todas las operaciones de representación, lo que significa que los métodos de representación pueden devolver códigos de éxito aunque se produzca un error en las operaciones de representación. En esta situación, IDirect3DDevice9::P resent devuelve el código de error D3DERR_DEVICELOST.

Por diseño, no se especifica el conjunto completo de escenarios que pueden hacer que un dispositivo se pierda. Algunos ejemplos típicos incluyen la pérdida de foco, como cuando el usuario presiona ALT+TAB o cuando se inicializa un cuadro de diálogo del sistema. Los dispositivos también se pueden perder debido a un evento de administración de energía o cuando otra aplicación asume la operación de pantalla completa. Además, cualquier error de IDirect3DDevice9::Reset coloca el dispositivo en un estado perdido.

Se garantiza que todos los métodos derivados de IUnknown funcionen después de que se pierda un dispositivo. Después de la pérdida del dispositivo, cada función suele tener las tres opciones siguientes:

  • Error con D3DERR_DEVICELOST: esto significa que la aplicación debe reconocer que se perdió el dispositivo, de modo que la aplicación identifique que algo no está ocurriendo según lo previsto.
  • Error silencioso, devolviendo S_OK o cualquier otro código de retorno: si se produce un error en una función silenciosamente, la aplicación generalmente no puede distinguir entre el resultado de "correcto" y un "error silencioso".
  • La función devuelve un código de retorno.
Diferencias entre Direct3D 9 y Direct3D 9Ex:
Un dispositivo Direct3D 9 devuelve D3DERR_DEVICELOST. Una vez que se haya devuelto desde IDirect3DDevice9::P resent, el comportamiento de emulación ya no funciona y todas las llamadas futuras producirán un error hasta que el dispositivo se restablezca correctamente.
Un dispositivo Direct3D 9Ex nunca devuelve D3DERR_DEVICELOST, pero puede devolver nuevos mensajes de estado (consulte cambios en el comportamiento del dispositivo).

 

Responder a un dispositivo perdido

Un dispositivo perdido debe volver a crear recursos (incluidos los recursos de memoria de vídeo) una vez restablecido. Si se pierde un dispositivo, la aplicación consulta al dispositivo para ver si se puede restaurar al estado operativo. Si no es así, la aplicación espera hasta que se pueda restaurar el dispositivo.

Si el dispositivo se puede restaurar, la aplicación prepara el dispositivo destruyendo todos los recursos de memoria de vídeo y cualquier cadena de intercambio. A continuación, la aplicación llama al método IDirect3DDevice9::Reset . Reset es el único método que tiene un efecto cuando se pierde un dispositivo y es el único método por el que una aplicación puede cambiar el dispositivo de un estado perdido a un estado operativo. Se producirá un error en el restablecimiento a menos que la aplicación libere todos los recursos asignados en D3DPOOL_DEFAULT, incluidos los creados por los métodos IDirect3DDevice9::CreateRenderTarget e IDirect3DDevice9::CreateDepthStencilSurface .

Por lo general, las llamadas de alta frecuencia de Direct3D no devuelven ninguna información sobre si el dispositivo se ha perdido. La aplicación puede seguir llamando a métodos de representación, como IDirect3DDevice9::D rawPrimitive, sin recibir una notificación de un dispositivo perdido. Internamente, estas operaciones se descartan hasta que el dispositivo se restablece al estado operativo.

La aplicación puede determinar qué hacer para encontrar un dispositivo perdido consultando el valor devuelto del método IDirect3DDevice9::TestCooperativeLevel .

Operaciones de bloqueo

Internamente, Direct3D hace suficiente trabajo para asegurarse de que una operación de bloqueo se realizará correctamente después de que se pierda un dispositivo. Sin embargo, no se garantiza que los datos del recurso de memoria de vídeo sean precisos durante la operación de bloqueo. Se garantiza que no se devolverá ningún código de error. Esto permite que las aplicaciones se escriban sin preocuparse por la pérdida de dispositivos durante una operación de bloqueo.

Recursos

Los recursos pueden consumir memoria de vídeo. Dado que un dispositivo perdido está desconectado de la memoria de vídeo propiedad del adaptador, no es posible garantizar la asignación de memoria de vídeo cuando se pierde el dispositivo. Como resultado, todos los métodos de creación de recursos se implementan para que se realicen correctamente devolviendo D3D_OK, pero, de hecho, asignan solo memoria ficticía del sistema. Dado que cualquier recurso de memoria de vídeo debe destruirse antes de que se cambie el tamaño del dispositivo, no hay ningún problema de asignación excesiva de memoria de vídeo. Estas superficies ficticas permiten que las operaciones de bloqueo y copia funcionen normalmente hasta que la aplicación llame a IDirect3DDevice9::P resent y descubra que el dispositivo se ha perdido.

Toda la memoria de vídeo debe liberarse antes de que un dispositivo se pueda restablecer de un estado perdido a un estado operativo. Esto significa que la aplicación debe liberar las cadenas de intercambio creadas con IDirect3DDevice9::CreateAdditionalSwapChain y los recursos colocados en la clase de memoria D3DPOOL_DEFAULT. La aplicación no necesita liberar recursos en las clases de memoria D3DPOOL_MANAGED o D3DPOOL_SYSTEMMEM. La transición a un estado operativo destruye automáticamente otros datos de estado.

Se recomienda desarrollar aplicaciones con una única ruta de acceso de código para responder a la pérdida de dispositivos. Es probable que esta ruta de acceso de código sea similar, si no es idéntica, a la ruta de acceso de código tomada para inicializar el dispositivo en el inicio.

Datos recuperados

Direct3D permite a las aplicaciones validar los estados de textura y representación en la representación de un solo paso por parte del hardware mediante IDirect3DDevice9::ValidateDevice. Este método, que normalmente se invoca durante la inicialización de la aplicación, devolverá D3DERR_DEVICELOST si se ha perdido el dispositivo.

Direct3D también permite a las aplicaciones copiar imágenes generadas o escritas previamente de recursos de memoria de vídeo en recursos de memoria del sistema no volátiles. Dado que las imágenes de origen de estas transferencias pueden perderse en cualquier momento, Direct3D permite que dichas operaciones de copia produzcan un error cuando se pierda el dispositivo.

Con respecto a las consultas asincrónicas, IDirect3DQuery9::GetData devuelve D3DERR_DEVICELOST si se especifica la marca FLUSH, para indicar a la aplicación que IDirect3DQuery9::GetData nunca devolverá S_OK.

La operación de copia, IDirect3DDevice9::GetFrontBufferData, puede producir un error con D3DERR_DEVICELOST, ya que no hay ninguna superficie principal cuando se pierde el dispositivo. IDirect3DDevice9::CreateAdditionalSwapChain también puede producir un error con D3DERR_DEVICELOST porque no se puede crear un búfer de reserva cuando se pierde el dispositivo. Tenga en cuenta que estos casos son la única instancia de D3DERR_DEVICELOST fuera de los métodos IDirect3DDevice9::P resent, IDirect3DDevice9::TestCooperativeLevel e IDirect3DDevice9::Reset .

Sombreadores programables

En Direct3D 9, los sombreadores de vértices y los sombreadores de píxeles no necesitan volver a crearse después del restablecimiento. Se recordarán. En versiones anteriores de DirectX, un dispositivo perdido requería que se vuelvan a crear los sombreadores.

Dispositivos Direct3D