Asignar direcciones virtuales a un segmento de memoria
El controlador de minipuerto de pantalla puede especificar, para cada segmento de espacio de memoria o espacio de apertura que defina, si las direcciones virtuales de CPU se pueden asignar directamente a una asignación ubicada en el segmento estableciendo la marca de campo de bits CpuVisible en el miembro Flags de la estructura DXGK_SEGMENTDESCRIPTOR del segmento.
Para asignar una dirección virtual de CPU a un segmento, el segmento debe tener acceso lineal a través de la apertura PCI. En otras palabras, el desplazamiento de cualquier asignación dentro del segmento debe ser el mismo que el desplazamiento en la apertura PCI. Por lo tanto, el administrador de memoria de vídeo puede calcular la dirección física relativa al bus de cualquier asignación en función del desplazamiento de la asignación dentro del segmento especificado.
En el diagrama siguiente se muestra cómo se asignan las direcciones virtuales a un segmento de espacio de memoria lineal.
En el diagrama siguiente se muestra cómo se asignan las direcciones virtuales a las páginas subyacentes de un segmento de espacio de apertura lineal.
Antes de asignar una dirección virtual a una parte del segmento, el administrador de memoria de vídeo llama a la función DxgkDdiAcquireSwizzlingRange del controlador de minipuerto de pantalla para que el controlador pueda configurar la apertura que se usa para acceder a bits de la asignación que podría ser desenredada. El controlador no puede cambiar el desplazamiento en la apertura PCI donde se accede a la asignación ni la cantidad de espacio que ocupa la asignación en la apertura. Si el controlador no puede hacer que la CPU de asignación sea accesible dadas estas restricciones (por ejemplo, el hardware posiblemente se ha agotado de apertura desenlace), el administrador de memoria de vídeo expulsa la asignación a la memoria del sistema y permite que la aplicación tenga acceso a los bits allí.
Si el contenido de una asignación creada anteriormente está en memoria del sistema cuando el controlador de pantalla en modo de usuario llama a la función pfnLockCb para solicitar acceso directo a la memoria, el administrador de memoria de vídeo devuelve el búfer de memoria del sistema al controlador de pantalla en modo de usuario y el controlador de miniporte de pantalla no está implicado en el acceso a la asignación. Por lo tanto, el controlador de minipuerto de pantalla no modifica el contenido de la asignación y permanece en formato desenredado. Esto implica que, cuando se expulsa una asignación accesible a la CPU de la memoria de vídeo, el controlador de minipuerto de pantalla debe desenredar la asignación para que la aplicación pueda acceder directamente a los bits de memoria del sistema resultantes.
Si se expulsan los recursos de GPU asociados a una asignación asignada actualmente para el acceso directo a la aplicación, el contenido de la asignación se transfiere a la memoria del sistema para que la aplicación pueda seguir accediendo al contenido en la misma dirección virtual, pero a un medio físico diferente. Para configurar la transferencia, el administrador de memoria de vídeo llama a la función DxgkDdiBuildPagingBuffer del controlador de miniporte de pantalla para crear un búfer de paginación y el programador de GPU llama a la función DxgkDdiSubmitCommand del controlador para poner en cola el búfer de paginación en la unidad de ejecución de GPU. El comando de transferencia específico del hardware está en el búfer de paginación. Para obtener más información, vea Envío de un búfer de comandos. El administrador de memoria de vídeo garantiza que la transición del vídeo a la memoria del sistema sea invisible para la aplicación. Sin embargo, el controlador debe asegurarse de que el orden de bytes de una asignación a través de la apertura PCI coincide exactamente con el orden de bytes de la asignación cuando se expulsa la asignación.
En el caso de los segmentos de espacio de apertura, los bits subyacentes de la asignación ya están en la memoria del sistema, por lo que no se requiere ninguna transferencia (desenlazamiento) de datos durante el proceso de expulsión. Por lo tanto, una asignación accesible para cpu ubicada en un segmento de espacio de apertura no se puede activar si una aplicación accede directamente a ella.
Si una aplicación accederá directamente a una superficie a través de la CPU, pero se activará en un segmento de espacio de apertura, los controladores de pantalla deben implementar la superficie como dos asignaciones diferentes. Cuando el controlador de visualización en modo de usuario crea esta superficie, puede llamar a la función pfnAllocateCb y puede establecer el miembro NumAllocations de la estructura de D3DDDICB_ALLOCATE en 2 y los miembros pPrivateDriverData de las estructuras D3DDDI_ALLOCATIONINFO de la matriz pAllocationInfo de D3DDDICB_ALLOCATE para que apunten a datos privados sobre las asignaciones (como sus formatos desenredados y desenredados). La asignación que usará la GPU contiene bits en formato desenredado y la asignación a la que tendrá acceso la aplicación contiene los bits en formato desenredado. El administrador de memoria de vídeo llama a la función DxgkDdiCreateAllocation del controlador de minipuerto de pantalla para crear las asignaciones. El controlador de minipuerto de pantalla interpreta los datos privados (en el miembro pPrivateDriverData de la estructura DXGK_ALLOCATIONINFO para cada asignación) que se pasa desde el controlador de pantalla en modo de usuario. El administrador de memoria de vídeo no es consciente del formato de las asignaciones; simplemente asigna bloques de memoria de determinados tamaños y alineaciones para las asignaciones. Una llamada a la función Lock del controlador de pantalla en modo de usuario para bloquear la superficie para su procesamiento provoca las siguientes acciones:
El controlador de pantalla en modo de usuario llama a la función pfnRenderCb para enviar la operación nowizzle en el búfer de comandos al tiempo de ejecución de Direct3D y en al controlador de miniporte de pantalla.
El controlador de pantalla en modo de usuario llama a la función pfnLockCb para bloquear la asignación nowizzled. Tenga en cuenta que el controlador de pantalla en modo de usuario no debe establecer la marca D3DDDILOCKCB_DONOTWAIT en el miembro Flags de la estructura D3DDDICB_LOCK.
La función pfnLockCb espera hasta que se realiza la transferencia (desenlazamiento) entre asignaciones.
La función pfnLockCb solicita que el controlador de minipuerto de pantalla obtenga una dirección virtual para la asignación no desenredada y devuelva la dirección virtual al controlador de pantalla en modo de usuario en el miembro pData de D3DDDICB_LOCK.
El controlador de pantalla en modo de usuario devuelve la dirección virtual de la asignación nowizzled a la aplicación en el miembro pSurfData de D3DDDIARG_LOCK.