Compartir a través de


Seguimiento del uso de asignación

Con la lista de asignación que desaparece, el administrador de memoria de vídeo (VidMm) ya no tiene visibilidad sobre las asignaciones a las que se hace referencia en un búfer de comandos determinado. Como resultado, VidMm ya no está en una posición para realizar un seguimiento del uso de la asignación y controlar la sincronización relacionada. Esta responsabilidad ahora pertenece al controlador en modo de usuario (UMD). En concreto, el UMD debe controlar la sincronización con respecto al acceso directo a la CPU a la asignación y el cambio de nombre.

VidMm aplaza de forma asincrónica la destrucción de la asignación de una manera segura que no es de bloqueo para el subproceso de llamada y el rendimiento. Como tal, un UMD no tiene que preocuparse por tener que aplazar la destrucción de la asignación. Cuando VidMm recibe una solicitud de destrucción de asignación, supone de forma predeterminada que los comandos en cola antes de la solicitud de destrucción podrían tener acceso potencialmente a la asignación que se está destruyendo. VidMm aplaza así la operación de destrucción hasta que finalicen los comandos en cola. Si el UMD sabe que los comandos pendientes no tienen acceso a la asignación que se está destruyendo, puede indicar al VidMm que procese la solicitud sin esperar estableciendo la marca AssumeNotInUse al llamar a Deallocate2 o DestroyAllocation2.

Lock2

El UMD es responsable de controlar la sincronización adecuada con respecto al acceso directo a la CPU. En concreto, se requiere un UMD para:

  1. Admite la semántica de bloqueo sin sobrescribir y descartar, lo que implica que el UMD debe implementar su propio esquema de cambio de nombre.

  2. Para las operaciones de asignación que requieren sincronización (es decir, no la sobrescritura o descarte anterior):

    • Devuelve WasStillDrawing si se intenta acceder a una asignación que está ocupada actualmente y el autor de la llamada ha solicitado que la operación Bloquear no bloquee el subproceso de llamada (D3D11_MAP_FLAG_DO_NOT_WAIT).
    • O bien, si no se establece la marca de D3D11_MAP_FLAG_DO_NOT_WAIT , espere hasta que una asignación esté disponible para el acceso a la CPU. El UMD debe implementar una espera nopolante. El UMD usará el nuevo mecanismo de supervisión de contexto.

Por ahora, el UMD sigue necesitando llamar a LockCb/UnlockCb para pedir a VidMm que configure una asignación para el acceso a la CPU. En la mayoría de los casos, el UMD puede mantener la asignación asignada durante toda su duración. Sin embargo, en el futuro, LockCb y UnlockCb quedarán en desuso en favor de las nuevas llamadas Lock2Cb y Unlock2Cb. El objetivo de estas devoluciones de llamada más recientes es proporcionar una implementación limpia nueva con un nuevo conjunto de argumentos y marcas.

Los intervalos de swizzling se quitan de la versión 2 de WDDM. Es responsabilidad del desarrollador del controlador quitar la dependencia de los intervalos de desplazamiento de llamadas a LockCb a medida que avanzan hacia una implementación basada en Lock2Cb.

Lock2Cb se expone como un método sencillo para obtener una dirección virtual a una asignación. Hay algunas restricciones basadas en el tipo de asignación y el segmento actual en el que reside actualmente.

El controlador indica si un segmento es accesible para la CPU a través de la marca CpuVisible , que se encuentra en el miembro Flags de la estructura DXGK_SEGMENTDESCRIPTOR .

Para las asignaciones accesibles para CPU:

  • Las asignaciones accesibles para CPU almacenadas en caché deben residir dentro de un segmento de apertura o no estar residentes para que se bloquee. No podemos garantizar la coherencia de caché entre la CPU y un segmento de memoria en la unidad de procesamiento de gráficos (GPU).
  • Se garantiza que las asignaciones accesibles para CPU ubicadas en un segmento de memoria totalmente accesible para la CPU (cuyo tamaño se cambia de tamaño mediante la barra de tamaño redimensionable) se pueden bloquear y poder devolver una dirección virtual. No se requieren restricciones especiales en este escenario.
  • Las asignaciones accesibles para CPU ubicadas dentro de un segmento de memoria no accesible para CPU (con o sin acceso a un CpuHostAperture) pueden no asignarse a una dirección virtual de CPU por varias razones. Si CpuHostAperture está sin espacio disponible o la asignación no especifica un segmento de apertura, no es posible obtener una dirección virtual. Por este motivo, todas las asignaciones accesibles para cpu en segmentos de memoria no accesibles para CPU deben contener un segmento de apertura en su conjunto de segmentos admitidos. Este requisito garantiza que VidMm pueda colocar la asignación en la memoria del sistema y proporcionar una dirección virtual.
  • Se garantiza que las asignaciones accesibles para la CPU ya se encuentran dentro de la memoria del sistema (o asignadas a un segmento de apertura).

Para asignaciones no accesibles para CPU:

  • Las asignaciones accesibles para CPU están respaldadas por objetos de sección que no pueden apuntar directamente al búfer de fotogramas de GPU. Para bloquear una asignación no accesible para cpu, la asignación debe admitir un segmento de apertura en el conjunto de segmentos admitido o ya estar en memoria del sistema (no debe estar residente en el dispositivo).

Si una asignación se bloquea correctamente mientras la asignación no reside en el dispositivo, pero no admite un segmento de apertura, la asignación no se debe confirmar en un segmento de memoria durante la duración del bloqueo.

Lock2 no contiene actualmente ninguna marca y los bits de marca reservada deben ser 0.

CpuHostAperture

Para admitir mejor el bloqueo con segmentos de memoria no accesibles para CPU al cambiar el tamaño de la BARRA, se proporciona una cpuHostAperture en la apertura PCI. CpuHostAperture se comporta como un administrador basado en páginas, que luego se puede asignar directamente a regiones de memoria de vídeo a través de la función de interfaz de controlador de dispositivo (DDI) DxgkDdiMapCpuHostAperture. Después, VidMm puede asignar un intervalo de espacio de direcciones virtuales directamente a un intervalo no contiguoso de CpuHostAperture y, a continuación, hacer que CpuHostAperture se asigne a la memoria de vídeo sin necesidad de intervalos de desplazamiento.

La cantidad máxima de memoria bloqueable a la que puede hacer referencia la CPU dentro de segmentos de memoria no accesibles para CPU se limita al tamaño de CpuHostAperture. Los detalles para exponer CpuHostAperture al kernel de gráficos de DirectX se pueden encontrar en la apertura del host de CPU.

Coherencia de E/S

En la actualidad, en x86/x64, todas las GPU deben admitir la coherencia de E/S a través de PCIe para permitir que una GPU lea o escriba en una superficie de memoria del sistema almacenable en caché y mantenga la coherencia con la CPU. Cuando una superficie se asigna como coherente con la memoria caché desde el punto de vista de la GPU, la GPU debe posponer las memorias caché de CPU al acceder a la superficie. Esta forma de coherencia se usa normalmente para los recursos de los que se espera que la CPU lea, como algunas superficies de ensayo.

En algunas plataformas arm, la coherencia de E/S no se admite directamente en el hardware. En estas plataformas, la coherencia de E/S debe emularse invalidando manualmente la jerarquía de caché de CPU. VidMm lo hace mediante el seguimiento de operaciones a una asignación procedente de la GPU (operación de lectura y escritura de la lista de asignación) y la CPU (operación de asignación, lectura y escritura). VidMm emite una invalidación de caché cuando determina que la caché puede contener:

  • Datos que deben escribirse (escritura de CPU, lectura de GPU)
  • Datos obsoletos que deben invalidarse (escritura de GPU, lecturas de CPU).

En la plataforma sin coherencia de E/S, la responsabilidad de realizar un seguimiento del acceso de CPU y GPU a las asignaciones cae en el UMD. El kernel de gráficos expone un nuevo DDI de caché invalidarque el UMD puede usar para volver a escribir e invalidar el intervalo de direcciones virtuales asociado a una asignación almacenable en caché. En las plataformas que no admiten la coherencia de E/S, se requiere que el UMD llame a esta función después de la escritura de CPU y antes de que la GPU lea, así como después de la escritura y antes de leer la CPU. Este último podría parecer inintuitivo al principio. Pero, dado que la CPU podría haber leído datos especulativamente antes de que la escritura de GPU lo haga en la memoria, es necesario invalidar todas las memorias caché de CPU para asegurarse de que la CPU vuelve a leer los datos de la RAM.