Supervisión del contexto
En este artículo se proporciona información sobre la supervisión del contexto, que se introdujo en Windows 10 (WDDM 2.0).
La supervisión de contextos permite una sincronización flexible entre los motores de GPU o entre núcleos de CPU y motores de GPU. Un objeto de barrera supervisado es una forma avanzada de sincronización de barreras que permite que un núcleo de CPU o un motor de GPU envíen señales o esperen a un objeto de barrera determinado.
Creación de barreras supervisadas
El tiempo de ejecución de Direct3D crea un objeto de valla supervisado llamando a la llamada de retorno pfnCreateSynchronizationObject2Cb del controlador de modo de usuario (UMD) con una estructura D3DDDICB_CREATESYNCHRONIZATIONOBJECT2. El miembro Info de esta estructura es una estructura D3DDDI_SYNCHRONIZATIONOBJECTINFO2 que describe el objeto de sincronización a crear. El tiempo de ejecución establece Info.Type en D3DDDI_MONITORED_FENCE para indicar que la estructura Info.MonitoredFence se utilizará durante la creación.
El objeto de barrera supervisada creado tiene los atributos siguientes:
- Valor de barrera inicial.
- Marcas que especifican su comportamiento de espera y señalización.
Tras la creación, se devuelve un objeto de barrera supervisado con la siguiente información:
Elemento | Descripción |
---|---|
hSyncObject | Identificador del objeto de sincronización. Este identificador se utiliza en llamadas posteriores a Dxgkrnl. |
FenceValueCPUVirtualAddress | Asignación de solo lectura del valor de la valla (64 bits) para la CPU. Esta dirección se asigna WB (cacheable) desde el punto de vista de la CPU en plataformas que soportan coherencia de E/S, UC (no cacheable) en otras plataformas. Permite que la CPU realice un seguimiento del progreso de la barrera simplemente leyendo esta ubicación de memoria. La CPU no puede escribir en esta ubicación de memoria. Para señalar la valla, la CPU debe llamar a SignalSynchronizationObjectFromCpuCb. Los adaptadores que admiten IoMmu deben usar esta dirección para el acceso a GPU. La dirección se mapea como lectura-escritura en este caso. |
FenceValueGPUVirtualAddress | Asignación de lectura/escritura del valor de la valla (64 bits) para la GPU. Esta dirección está mapeada como requiriendo coherencia de E/S en plataformas que la admiten. Para señalar la valla, la GPU puede escribir directamente en esta dirección virtual de GPU. Las GPU de IoMmu no deben usar esta dirección. |
El valor de barrera es un valor de 64 bits con sus respectivas direcciones virtuales alineadas en un límite de 64 bits. Las GPUs deben declarar si son capaces de actualizar atómicamente valores de 64 bits visibles por la CPU a través de la marca añadida DXGK_VIDSCHCAPS::No64BitAtomics. Si una GPU solo es capaz de actualizar valores de 32 bits de forma atómica, el sistema operativo se encarga automáticamente del caso de envoltura de la valla. Sin embargo, impone la restricción de que los valores de espera y señalización pendientes no pueden estar a más de UINT_MAX/2 del último valor de señalización.
Señal de GPU
Si un motor de GPU no es capaz de escribir en una valla monitorizada utilizando su dirección virtual, la UMD utiliza la llamada de retorno SignalSynchronizationObjectFromGpuCb para poner en cola un paquete de señal de software al contexto de GPU.
Para señalar la valla desde la GPU, la UMD inserta un comando de escritura de valla en un flujo de comandos de contexto directamente sin pasar por el modo de núcleo. El mecanismo por el que el kernel supervisa el progreso de la barrera varía en función de si un motor de GPU determinado admite la implementación básica o avanzada de la barrera supervisada.
Cuando un búfer de comandos completa la ejecución en la GPU, Dxgkrnl:
- Recorre la lista de objetos valla con esperas pendientes que podrían ser señalados para este proceso.
- Lee su valor de valla actual.
- Determina si hay esperas que deban eliminarse.
Espera GPU
Para esperar en una valla monitorizada en un motor GPU, el UMD primero necesita vaciar su buffer de comandos pendientes y luego llamar a WaitForSynchronizationObjectFromGpuCb especificando el objeto de valla (hSyncObject) y el valor de valla que se está esperando. Dxgkrnl pone en cola la dependencia a su base de datos interna, luego regresa inmediatamente a la UMD para que pueda continuar poniendo en cola el trabajo detrás de la operación de espera. Los búferes de comandos enviados después de la operación de espera no están programados para su ejecución hasta que se cumpla la operación de espera.
Señal de CPU
Se agregó el callback SignalSynchronizationObjectFromCpuCb para permitir a la CPU señalar un objeto valla monitoreado. Cuando la CPU señala un objeto de barrera supervisado, Dxgkrnl actualiza la ubicación de memoria de barrera con el valor señalado. Este valor se vuelve inmediatamente visible para cualquier lector en modo usuario y libera inmediatamente cualquier espera satisfecha.
Espera CPU
Se agregó un callback WaitForSynchronizationObjectFromCpuCb para permitir que la CPU espere un objeto valla monitoreado. Hay dos formas de operaciones de espera disponibles:
- En el primer formulario, WaitForSynchronizationObjectFromCpuCb se bloquea hasta que se satisface la espera.
- En el segundo formulario, WaitForSynchronizationObjectFromCpuCb toma un identificador a un evento de CPU que se señala una vez que se satisface la condición de espera.