Dela via


Spårning av allokeringsanvändning

När allokeringslistan försvinner har videominneshanteraren (VidMm) inte längre insyn i allokeringarna som refereras till i en viss kommandobuffert. Därför kan VidMm inte längre spåra allokeringsanvändning och hantera relaterad synkronisering. Det här ansvaret faller nu på användarlägesdrivrutinen (UMD). I synnerhet måste UMD hantera synkroniseringen med avseende på direkt CPU-åtkomst till allokering och namnbyte.

VidMm fördröjer asynkront allokeringsförstörelse på ett säkert sätt som både är icke-blockerande för den anropande tråden och effektivt. Som sådan behöver umd inte oroa sig för att behöva skjuta upp allokeringsförstörelse. När VidMm tar emot en begäran om allokeringsförstörelse förutsätter det som standard att kommandon som köas före destruktionsbegäran potentiellt kan komma åt allokeringen som förstörs. VidMm skjuter därför upp förstörelseoperationen tills de köade kommandona har slutförts. Om UMD vet att väntande kommandon inte kommer åt allokeringen som förstörs kan den instruera VidMm att bearbeta begäran utan att vänta genom att ange flaggan AssumeNotInUse när du anropar Deallocate2 eller DestroyAllocation2.

Lås 2

UMD ansvarar för att hantera korrekt synkronisering med avseende på direkt CPU-åtkomst. I synnerhet krävs en UMD för att:

  1. Stöd för no-overwrite och discard lock semantics, vilket innebär att UMD måste implementera sitt eget namnbytesschema.

  2. För kartåtgärder som kräver synkronisering (dvs. inte ovanstående no-overwrite eller ignorera):

    • Returnera WasStillDrawing om ett försök görs att komma åt en allokering som för närvarande är upptagen och anroparen har begärt att låsoperationen inte blockerar den anropande tråden (D3D11_MAP_FLAG_DO_NOT_WAIT).
    • Om D3D11_MAP_FLAG_DO_NOT_WAIT-flaggan inte är satt, vänta tills en allokering blir tillgänglig för CPU-åtkomst. UMD måste implementera en väntetid utan pollning. UMD använder den nya mekanismen för kontextövervakning.

För tillfället fortsätter UMD att behöva anropa LockCb/UnlockCb för att be VidMm att konfigurera en allokering för CPU-åtkomst. I de flesta fall kan UMD behålla allokeringen mappad under hela sin livslängd. Men i framtiden kommer LockCb och UnlockCb att bli inaktuella till förmån för nya Lock2Cb - och Unlock2Cb-anrop . Målet med dessa nyare callbacks är att tillhandahålla en ren ny implementering med en ny uppsättning argument och flaggor.

Swizzling-intervall tas bort från WDDM version 2. Det är drivrutinsutvecklarens ansvar att ta bort beroendet av swizzling-intervall från anrop till LockCb när de går mot en implementering som baseras på Lock2Cb.

Lock2Cb exponeras som en enkel metod för att erhålla en virtuell adress till en allokering. Det finns några begränsningar baserade på typen av allokering och det segment där det för närvarande befinner sig.

Drivrutinen anger om ett segment är CPU-tillgängligt via flaggan CpuVisible , som finns i flags-medlemmen i DXGK_SEGMENTDESCRIPTOR-strukturen .

För CPU-tillgängliga allokeringar:

  • Cachelagrade CPU-tillgängliga allokeringar måste finnas inom ett minnessegment eller inte vara residenta för att kunna låsas. Vi kan inte garantera cachesammansättning mellan processorn och ett minnessegment på grafikprocessorn (GPU).
  • Processortillgängliga allokeringar som finns i ett fullständigt CPU-tillgängligt minnessegment (ändra storlek med den storleksanpassade stapeln) är garanterat låsbara och kan returnera en virtuell adress. Inga särskilda begränsningar krävs i det här scenariot.
  • Processortillgängliga allokeringar som finns inom ett icke-CPU-tillgängligt minnessegment (med eller utan åtkomst till en CpuHostAperture) kan inte mappas till en virtuell CPU-adress av olika skäl. Om CpuHostAperture har slut på tillgängligt utrymme eller om allokeringen inte anger ett bländarsegment är det omöjligt att hämta en virtuell adress. Av denna anledning måste alla allokeringar som är tillgängliga för CPU:n och ligger i minnessegment som inte är tillgängliga för CPU:n, innehålla ett apertursegment i sitt stödda segmentuppsättning. Det här kravet garanterar att VidMm kan placera allokeringen i systemminnet och ange en virtuell adress.
  • Processortillgängliga allokeringar som redan finns i systemminnet (och/eller representeras i ett apertursegment) fungerar garanterat.

För icke-CPU-tillgängliga allokeringar:

  • CPU-tillgängliga allokeringar stöds av avsnittsobjekt som inte kan peka direkt på GPU:ers rambuffert. För att låsa en icke-CPU-tillgänglig allokering måste allokeringen ha stöd för ett bländarsegment i den segmentuppsättning som stöds, eller redan finnas i systemminnet (får inte finnas på enheten).

Om en tilldelning är låst medan den inte är resident på enheten men inte har stöd för en minnessegmenttyp, får tilldelningen inte tilldelas ett minnessegment under tiden den är låst.

Lock2 innehåller för närvarande inga flaggor och Reserverade flaggbitar måste vara 0.

CpuHostAperture

För att bättre stödja låsning för icke-CPU-tillgängliga minnessegment när storleksändringen av BAR misslyckas, tillhandahålls en CpuHostAperture i PCI-aperturen. CpuHostAperture fungerar som en sidbaserad hanterare, som sedan kan mappas direkt till regioner med videominne via DxgkDdiMapCpuHostAperture-enhetensdrivrutinsgränssnitt (DDI). VidMm kan sedan mappa ett intervall av virtuellt adressutrymme direkt till ett icke-sammanhängande intervall av CpuHostAperture och låta CpuHostAperture mappa sedan vidare till videominnet utan behov av att swizzla intervall.

Den maximala mängden låsbart minne som processorn kan referera till inom minnessegment som inte är CPU-tillgängliga är begränsad till storleken på CpuHostAperture. Information om hur du exponerar CpuHostAperture för DirectX-grafikkärnan finns i CPU-värdaperturen.

I/O-samtidighet

På x86/x64 idag måste alla GPU:er ha stöd för I/O-samtidighet över PCIe för att en GPU ska kunna läsa eller skriva till en cachebar systemminnesyta och upprätthålla samtidighet med processorn. När en yta mappas som cache-koherent ur GPU:ns synvinkel måste GPU:n övervaka CPU-cacheminnena vid åtkomst av ytan. Den här typen av samtidighet används vanligtvis för resurser som processorn förväntas läsa från, till exempel vissa mellanlagringsytor.

På vissa Arm-plattformar stöds inte I/O-samtidighet direkt i maskinvara. På dessa plattformar måste I/O-samtidighet emuleras genom att processorcachehierarkin ogiltigförklaras manuellt. VidMm gör det genom att spåra åtgärder till en allokering som kommer från GPU:n (läs-/skrivåtgärd för allokeringslista) och CPU (kartåtgärd, läsning/skrivning). VidMm genererar en cache-ogiltighet när den fastställer att cachen kan innehålla:

  • Data som måste skrivas tillbaka (CPU-skrivning, GPU-läsning)
  • Inaktuella data som måste ogiltigförklaras (GPU-skrivning, CPU-läsning).

På en plattform utan I/O-samordning ligger ansvaret hos UMD att övervaka CPU- och GPU-åtkomst till allokeringar. Grafikkärnan exponerar en ny Invalidate CacheDDI som UMD kan använda för att skriva tillbaka och ogiltigförklara det virtuella adressintervall som är associerat med en cachebar allokering. På plattformar som inte har stöd för I/O-koherens måste UMD anropa den här funktionen efter CPU-skrivning och före GPU-läsning samt efter skrivning och före CPU-läsning. Det senare kan verka ointuitivt till en början. Men eftersom processorn spekulativt kan ha läst data innan GPU-skrivningen når minnet, är det nödvändigt att ogiltigförklara alla CPU-cacheminnen för att säkerställa att processorn läser om data från RAM-minnet.