Mappage d’adresses virtuelles à un segment de mémoire
Le pilote miniport d’affichage peut spécifier, pour chaque segment d’espace mémoire ou d’espace d’ouverture qu’il définit, si les adresses virtuelles du processeur peuvent être mappées directement à une allocation située dans le segment en définissant l’indicateur de champ de bits CpuVisible dans le membre Indicateurs de la structure DXGK_SEGMENTDESCRIPTOR du segment.
Pour mapper une adresse virtuelle du processeur à un segment, le segment doit disposer d’un accès linéaire via l’ouverture PCI. En d’autres termes, le décalage de toute allocation au sein du segment doit être le même que le décalage dans l’ouverture PCI. Par conséquent, le gestionnaire de mémoire vidéo peut calculer l’adresse physique relative du bus de toute allocation en fonction du décalage de l’allocation dans le segment donné.
Le diagramme suivant illustre la façon dont les adresses virtuelles sont mappées à un segment d’espace mémoire linéaire.
Le diagramme suivant illustre la façon dont les adresses virtuelles sont mappées aux pages sous-jacentes d’un segment d’espace à ouverture linéaire.
Avant de mapper une adresse virtuelle à une partie du segment, le gestionnaire de mémoire vidéo appelle la fonction DxgkDdiAcquireSwizzlingRange du pilote miniport d’affichage afin que le pilote puisse configurer l’ouverture utilisée pour accéder aux bits de l’allocation qui peuvent être swizzled. Le pilote ne peut modifier ni le décalage dans l’ouverture PCI où l’allocation est accessible, ni la quantité d’espace que l’allocation prend dans l’ouverture. Si le pilote ne peut pas rendre l’allocation accessible au processeur en raison de ces contraintes (par exemple, le matériel est peut-être à court d’ouverture non pivotante), le gestionnaire de mémoire vidéo supprime l’allocation à la mémoire système et permet à l’application d’y accéder.
Si le contenu d’une allocation créée précédemment se trouve dans la mémoire système lorsque le pilote d’affichage en mode utilisateur appelle la fonction pfnLockCb pour demander un accès direct à la mémoire mémoire, le gestionnaire de mémoire vidéo retourne la mémoire tampon système au pilote d’affichage en mode utilisateur, et le pilote de miniport d’affichage n’est pas impliqué dans l’accès à l’allocation. Par conséquent, le contenu de l’allocation n’est pas modifié par le pilote miniport d’affichage et reste au format nonwizzled. Cela implique que lorsqu’une allocation accessible par le processeur est supprimée de la mémoire vidéo, le pilote miniport d’affichage doit annuler l’allocation afin que les bits de mémoire système résultants puissent être directement accessibles par l’application.
Si les ressources GPU associées à une allocation actuellement mappée pour l’accès direct à l’application sont supprimées, le contenu de l’allocation est transféré vers la mémoire système afin que l’application puisse continuer à accéder au contenu à la même adresse virtuelle, mais sur un support physique différent. Pour configurer le transfert, le gestionnaire de mémoire vidéo appelle la fonction DxgkDdiBuildPagingBuffer du pilote miniport d’affichage pour créer une mémoire tampon de pagination, et le planificateur GPU appelle la fonction DxgkDdiSubmitCommand du pilote pour mettre en file d’attente la mémoire tampon de pagination vers l’unité d’exécution GPU. La commande de transfert spécifique au matériel se trouve dans la mémoire tampon de pagination. Pour plus d’informations, consultez Envoi d’une mémoire tampon de commande. Le gestionnaire de mémoire vidéo garantit que la transition de la vidéo vers la mémoire système est invisible pour l’application. Toutefois, le pilote doit s’assurer que l’ordre d’octet d’une allocation via l’ouverture PCI correspond exactement à l’ordre d’octet de l’allocation lorsque l’allocation est supprimée.
Pour les segments d’espace d’ouverture, les bits sous-jacents de l’allocation étant déjà dans la mémoire système, aucun transfert (unswizzzling) de données pendant le processus d’éviction n’est requis. Par conséquent, une allocation accessible au processeur située dans un segment d’espace d’ouverture ne peut pas être réduite si elle est accessible directement par une application.
Si une surface est directement accessible via le processeur par une application, mais qu’elle est exécutée dans un segment d’espace d’ouverture, les pilotes d’affichage doivent implémenter la surface sous la forme de deux allocations différentes. Lorsque le pilote d’affichage en mode utilisateur crée une telle surface, il peut appeler la fonction pfnAllocateCb et définir le membre NumAllocations de la structure D3DDDICB_ALLOCATE sur 2 et les membres pPrivateDriverData des structures D3DDDI_ALLOCATIONINFO dans le tableau pAllocationInfo de D3DDDICB_ALLOCATE pour pointer vers des données privées sur les allocations (telles que leurs formats swizzled et unswizzled). L’allocation qui sera utilisée par le GPU contient des bits au format swizzled, et l’allocation accessible par l’application contient les bits au format nonwizzled. Le gestionnaire de mémoire vidéo appelle la fonction DxgkDdiCreateAllocation du pilote d’affichage miniport pour créer les allocations. Le pilote miniport d’affichage interprète les données privées (dans le membre pPrivateDriverData de la structure DXGK_ALLOCATIONINFO pour chaque allocation) qui sont transmises à partir du pilote d’affichage en mode utilisateur. Le gestionnaire de mémoire vidéo ignore le format des allocations ; il alloue simplement des blocs de mémoire de certaines tailles et alignements pour les allocations. Un appel à la fonction Lock du pilote d’affichage en mode utilisateur pour verrouiller la surface pour le traitement entraîne les actions suivantes :
Le pilote d’affichage en mode utilisateur appelle la fonction pfnRenderCb pour envoyer l’opération unswizzle dans la mémoire tampon de commande au runtime Direct3D et au pilote miniport d’affichage.
Le pilote d’affichage en mode utilisateur appelle la fonction pfnLockCb pour verrouiller l’allocation nonwizzled. Notez que le pilote d’affichage en mode utilisateur ne doit pas définir l’indicateur D3DDDILOCKCB_DONOTWAIT dans le membre Indicateurs de la structure D3DDDICB_LOCK.
La fonction pfnLockCb attend que le transfert (unswizzling) entre les allocations soit effectué.
La fonction pfnLockCb demande que le pilote de miniport d’affichage obtienne une adresse virtuelle pour l’allocation nonwizzzled et retourne l’adresse virtuelle au pilote d’affichage en mode utilisateur dans le membre pData de D3DDDICB_LOCK.
Le pilote d’affichage en mode utilisateur retourne l’adresse virtuelle de l’allocation nonwizzled à l’application dans le membre pSurfData de D3DDDIARG_LOCK.