TDR en Windows 8 y versiones posteriores

A partir de Windows 8, el comportamiento de detección y recuperación de tiempo de espera de GPU (TDR) permite restablecer partes de adaptadores físicos individuales, en lugar de requerir un restablecimiento en todo el adaptador.

Consulte Detección y recuperación de tiempo de espera (TDR) para obtener más información sobre TDR.

Requisitos

  • Versión mínima de WDDM: 1.2
  • Versión mínima de Windows: 8
  • Implementación del controlador: gráficos completos y representar solo: obligatorio
  • Requisitos y pruebas de WHLK: Device.Graphics... TDRResiliency

Interfaz del controlador de dispositivo TDR (DDI)

Para dar cabida a este cambio de comportamiento, los controladores de minipuerto de pantalla implementan estas funciones:

Un controlador de minipuerto de pantalla indica la compatibilidad con estas funciones estableciendo el DXGK_DRIVERCAPS. Miembro SupportPerEngineTDR , en cuyo caso debe implementar todas las funciones anteriores.

Nota

Un controlador que admita estas funciones también debe admitir la sincronización de nivel cero para la función DxgkDdiCollectDbgInfo . Esto es para asegurarse de que las llamadas de minipuerto de nivel cero no afectadas por la operación de restablecimiento pueden continuar. Vea comentarios de DxgkDdiCollectDbgInfo.

Las siguientes estructuras están asociadas a las funciones anteriores:

Nodos

Como se usa en las funciones de TDR anteriores, un nodo es una de varias partes de un único adaptador físico que se puede programar de forma independiente. Por ejemplo, un nodo 3D, un nodo de descodificación de vídeo y un nodo de copia pueden existir en el mismo adaptador físico y cada uno de ellos se puede asignar un valor ordinal de nodo independiente en el DXGKARG_QUERYDEPENDENTENGINEGROUP. NodeOrdinal miembro en una llamada a DxgkDdiQueryDependentEngineGroup.

El controlador de miniporte de pantalla notifica el número de nodos del adaptador físico en el miembro NbAsymetricProcessingNodes de DXGK_DRIVERCAPS. GpuEngineTopology.

El valor ordinal del nodo se pasa en el miembro NodeOrdinal de la estructura DXGKARG_CREATECONTEXT cuando se crea un contexto.

Motores

Como se usa en las funciones de TDR anteriores, un motor es uno de varios adaptadores físicos (o GPU) que actúan conjuntamente como un adaptador lógico. El subsistema del kernel de gráficos de DirectX admite estas configuraciones, pero requiere que cada motor tenga el mismo número de nodos.

Por ejemplo, el programador de GPU considera que el motor 0 se corresponde con el adaptador físico 0. El motor 0 debe tener el mismo número de nodos que el motor 1, que corresponde al adaptador 1.

Valor ordinal del motor en la creación del contexto

Cuando se crea un contexto, se establece un solo bit correspondiente al valor ordinal del motor en el miembro EngineAffinity de la estructura DXGKARG_CREATECONTEXT . El miembro EngineOrdinal de esta y otras estructuras relacionadas con el programador es un índice de base cero. El valor de EngineAffinity es 1 <<EngineOrdinal y EngineOrdinal es la posición de bits más alta en EngineAffinity.

Paquetes no afectados por el restablecimiento del motor

El programador de GPU puede pedir al controlador que vuelva a enviar paquetes que se enviaron demasiado tarde a la cola de hardware del motor para que se procese completamente antes de que se complete el restablecimiento del motor. El controlador debe seguir estas directrices para volver a enviar estos paquetes:

  • Paquetes de paginación: el programador de GPU le pedirá al controlador que vuelva a enviar paquetes de paginación con sus identificadores de cerca originales y en el mismo orden en que se enviaron originalmente. Los paquetes de este tipo se volverán a enviar antes de que se agreguen nuevos paquetes a la cola de hardware.
  • Representar paquetes: el programador de GPU asignará nuevos identificadores de barrera para representar paquetes y, a continuación, los volverá a enviar.

Llamada a la secuencia para restablecer un motor

Cuando DxgkDdiResetEngine se realiza correctamente, el programador de GPU garantiza que el valor LastAbortedFenceId devuelto desde la llamada de restablecimiento del motor corresponde a un identificador de barrera existente en la cola de hardware o al último identificador de barrera completado en la GPU. Esta última situación puede ocurrir cuando se vacía la cola de hardware después de que se detecte el tiempo de espera de GPU, pero antes de invocar la devolución de llamada de restablecimiento del motor.

El controlador debe mantener el último valor de identificador de barrera completado en la GPU en todo momento, ya que también es necesario establecer el miembro DmaPreempted.LastCompletedFenceId de una estructura de notificación de interrupción de DXGKARGCB_NOTIFY_INTERRUPT_DATA adelantamiento. El último identificador de barrera completado solo debe estar avanzado en estas situaciones:

  • Cuando se completa un paquete (no se adelanta), el último identificador de barrera completado debe establecerse en el identificador de barrera del paquete completado.
  • Cuando DxgkDdiResetEngine se realiza correctamente, el último identificador de barrera completado debe establecerse en el valor del miembro LastCompletedFenceId devuelto por la llamada de restablecimiento del motor.
  • En el caso del restablecimiento en todo el adaptador, el último identificador de barrera completado en todos los nodos debe avanzar hasta el último identificador de barrera enviado en el momento del restablecimiento.

Esta es una secuencia cronológica de un restablecimiento correcto del motor, como lo ve el programador de GPU:

  1. Se emite un intento de adelantamiento.

  2. Se detecta un tiempo de espera de GPU.

  3. El programador de GPU toma una instantánea de los últimos identificadores de barrera enviados y completados, y se omiten las interrupciones del motor de tiempo de espera agotado. Se trata de una operación atómica en el nivel de interrupción del dispositivo.

  4. Si no hay paquetes en la cola de hardware en este momento, salga. Esto puede ocurrir si un paquete se completó en el período de tiempo entre los pasos 2 y 3.

  5. Todos los DPC en cola se vacían.

  6. Prepárese para el restablecimiento del motor.

  7. Llame a DxgkDdiResetEngine.

  8. Si el miembro LastAbortedFenceId es menor que el último identificador de barrera completado o es mayor que el último identificador de barrera enviado, el subsistema del kernel de gráficos de DirectX hace que se produzca una comprobación de errores del sistema. En un archivo de volcado de memoria, el mensaje BugCheck 0x119 indica el error, que tiene estos cuatro parámetros:

    • 0xA, lo que significa que el controlador ha notificado un identificador de barrera anulado no válido.
    • Último valor de LastAbortedFenceId devuelto por el controlador
    • Identificador de la barrera completada por última vez
    • Un parámetro interno del sistema operativo
  9. Si el valor LastAbortedFenceId es válido, continúe con la recuperación del restablecimiento del motor como se indica a continuación. Si un paquete de paginación se vio afectado por el restablecimiento del motor, el programador de GPU sigue el restablecimiento del motor con un restablecimiento en todo el adaptador. Todos los dispositivos a los que hace referencia ese paquete de paginación también se colocan en el estado de error. Sin embargo, el propio dispositivo del sistema no se coloca en el estado de error y reanuda la ejecución una vez completado el restablecimiento.

Casos especiales

Una situación especial puede producirse cuando se completa un paquete en la GPU entre los pasos 3 y 7 descritos anteriormente. En este caso, lastAbortedFenceId debe establecerse por el controlador en el identificador de barrera del último paquete completado si no hay paquetes en la cola de hardware desde el punto de vista del controlador. Desde el punto de vista del programador, aparecerá que este paquete se anuló y el dispositivo correspondiente se colocará en un estado de error aunque el paquete se complete finalmente.

Si el controlador no puede realizar una operación de restablecimiento porque el hardware está en un estado no válido o porque el hardware no puede restablecer los nodos, el controlador debe devolver un código de estado de error. Si el programador de GPU recibe un código de estado de error, realiza una operación de restablecimiento y reinicio de todo el adaptador siguiendo el comportamiento de TDR antes de Windows 8.

Incluso si un controlador ha optado por el comportamiento de Windows 8 y versiones posteriores de TDR, habrá casos en los que el programador de GPU solicita un restablecimiento y reinicio de todo el adaptador lógico. Por lo tanto, el controlador todavía debe implementar las funciones DxgkDdiResetFromTimeout y DxgkDdiRestartFromTimeout, y su semántica sigue siendo la misma que antes de Windows 8. Cuando un intento de restablecer un adaptador físico con DxgkDdiResetEngine conduce a un restablecimiento del adaptador lógico, el comando !analyze del depurador de Windows muestra que el valor TdrReason del contexto de recuperación de TDR se establece en un nuevo valor de TdrEngineTimeoutPromotedToAdapterReset = 9.