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 de las asignaciones a las que se hace referencia en un búfer de comandos determinado. Como resultado, VidMm ya no puede realizar un seguimiento del uso de la asignación ni gestionar la sincronización relacionada. Esta responsabilidad ahora recae en el controlador en modo de usuario (UMD). En concreto, el UMD debe controlar la sincronización con respecto al acceso directo de la CPU para la asignación de recursos y el cambio de nombre.

VidMm aplaza de forma asincrónica la destrucción de asignaciones de manera segura que no bloquea el subproceso que realiza la llamada y es eficiente en rendimiento. Por lo tanto, 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 acceder potencialmente a la asignación que se va a destruir. 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 va a destruir, 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 sobrescritura y descarte, lo que implica que el UMD debe implementar su propio esquema de cambio de nombre.

  2. Para las operaciones de mapas que requieren sincronización (es decir, no incluidas las operaciones de no sobrescritura o descarte mencionadas anteriormente):

    • Devuelve WasStillDrawing si se intenta acceder a una asignación de memoria que está ocupada actualmente y el llamador ha solicitado que la operación Lock no bloquee el subproceso de llamada (D3D11_MAP_FLAG_DO_NOT_WAIT).
    • O bien, si no se establece la marca 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 sin sondeo. El UMD usará el nuevo mecanismo de supervisión de contexto.

Por ahora, el UMD sigue necesitando llamar a LockCb y UnlockCb para solicitar 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 mapeada 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 rangos de swizzling se eliminan de la versión 2 de WDDM. Es responsabilidad del desarrollador del controlador eliminar la dependencia de los intervalos de permutación de las llamadas a LockCb a medida que avanza hacia una implementación basada en Lock2Cb.

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

El controlador indica si un segmento es accesible a la CPU mediante la bandera CpuVisible, que se encuentra en el miembro Flags de la estructura DXGK_SEGMENTDESCRIPTOR.

Para las asignaciones accesibles por la CPU

  • Las asignaciones accesibles para CPU almacenadas en caché deben residir dentro de un segmento de apertura o no estar presentes para poder ser bloqueadas. 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 a la CPU ubicadas en un segmento de memoria completamente accesible para la CPU (redimensionado mediante el resizable BAR) se pueden bloquear y devolver una dirección virtual. No se requieren restricciones especiales en este escenario.
  • Las asignaciones accesibles a la CPU ubicadas dentro de un segmento de memoria no accesible para cpu (con o sin acceso a cpuHostAperture) pueden no asignarse a una dirección virtual de CPU por varias razones. Si CpuHostAperture está fuera del espacio disponible o la asignación no especifica un segmento de apertura, es imposible obtener una dirección virtual. Por este motivo, todas las asignaciones accesibles a la CPU en segmentos de memoria no accesibles por la CPU deben contener un segmento de apertura en su conjunto de segmentos admitidos. Este requisito garantiza que VidMm pueda colocar la asignación dentro de la memoria del sistema y proporcionar una dirección virtual.
  • Se garantiza que las asignaciones accesibles para la CPU que ya se encuentran en la memoria del sistema (y/o mapeadas en un segmento de apertura) funcionarán correctamente.

Para las asignaciones no accesibles para CPU:

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

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

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

CpuHostAperture

Para admitir mejor el bloqueo con segmentos de memoria no accesibles para la CPU cuando se produce un error en el cambio de tamaño del BAR, se proporciona una CpuHostAperture en la apertura de PCI. CpuHostAperture se comporta como un administrador basado en páginas, que 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 giro.

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 necesarios para exponer CpuHostAperture al kernel de gráficos de DirectX se pueden encontrar en CpuHostAperture.

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 en caché y mantenga la compatibilidad con la CPU. Cuando una superficie se asigna como caché coherente desde el punto de vista de la GPU, la GPU debe examinar las cachés de la 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 haciendo seguimiento de las operaciones sobre una asignación que proviene de la GPU (operación de lectura/escritura de la lista de asignaciones) y de la CPU (operación de mapeo, lectura/escritura). VidMm emite una invalidación de caché cuando determina que la memoria caché puede contener:

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

En plataformas sin coherencia de E/S, la responsabilidad de realizar un seguimiento del acceso de CPU y GPU a las asignaciones recae sobre el UMD. El kernel de gráficos expone un nuevo Invalidate Cache DDI que el UMD puede usar para escribir de nuevo e invalidar el intervalo de direcciones virtuales asociado a una asignación 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 que la CPU escriba y antes de que la GPU lea, así como después de que la GPU escriba y antes de que la CPU lea. Este último podría parecer inintuito al principio. Pero, dado que la CPU podría haber leído datos especulativamente antes de que la escritura de la GPU llegue a la memoria, es necesario invalidar todas las memorias caché de la CPU para asegurarse de que la CPU vuelva a leer los datos de la RAM.