Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Er zijn gevallen waarin het stuurprogramma van de kernelmodus (KMD) een CPU-gebeurtenis moet signaleren om het stuurprogramma voor de gebruikersmodus (UMD) over iets te melden; bijvoorbeeld:
- Wanneer KMD detecteert dat een van de objecten een slechte status heeft en UMD moet melden.
- Tijdens GPU-foutopsporing waarbij KMD moet communiceren met UMD dat er een gebeurtenis is opgetreden. Voor IHV's met controlpanels voor GPU stelt het signaleren van CPU-gebeurtenissen door KMD de applicatie Control Panels in staat om op de hoogte te blijven van interne gebeurtenissen.
Normaal gesproken kan UMD een CPU-gebeurtenis maken en de NT-handle doorgeven aan KMD in privégegevens voor ontsnapping. Deze methode werkt niet in het scenario voor GPU-paravirtualisatie (GPU-PV), omdat NT-ingangen niet kunnen worden gebruikt binnen grenzen van virtuele machines.
Vanaf Windows 11 versie 21H2 (WDDM 3.0) is de WDDM-API uitgebreid zodat UMD een CPU-gebeurtenisobject kan maken dat kan worden gesignaleerd door KMD. Deze functie werkt zowel wanneer UMD wordt uitgevoerd op de host of op een virtuele machine met GPU-PV.
Functieproces
UMD maakt een GPU-synchronisatieobject met het D3DDDI_CPU_NOTIFICATION type. Het gemaakte object wordt zichtbaar gemaakt voor KMD door de vlag SignalByKmd in te stellen bij het aanroepen van D3DKMTCreateSynchronizationObject.
Dxgkrnl roept DXGKDDI_CREATECPUEVENT aan om KMD toe te staan een eigen object te maken.
UMD roept D3DKMTEscape aan met het bekende escape-type D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE, om KMD te informeren over het beoogde gebruik van het synchronisatieobject.
Dxgkrnl roept DXGKDDI_ESCAPE aan om de privégegevens door te geven aan KMD.
Op een bepaald moment roept KMD DXGKCB_SIGNALEVENT aan met de CpuEventObject vlag om het CPU-gebeurtenisobject te signaleren.
UMD roept D3DKMTDestroySynchronizationObject aan om het CPU-gebeurtenisobject te vernietigen.
Dxgkrnl roept DXGKDDI_DESTROYCPUEVENT aan om het CPU-gebeurtenisobject te vernietigen. DXGKCB_SIGNALEVENT mag na dit punt niet worden aangeroepen.
Het synchronisatieobject kan niet worden ingevoegd in een contextwachtrij. Het kan alleen worden gesignaleerd door KMD met behulp van DXGKCB_SIGNALEVENT.
API's in de gebruikersmodus voor het verwerken van CPU-gebeurtenissynchronisatieobjecten
Aanmaken van het KMD CPU-gebeurtenisobject
Het KMD CPU-gebeurtenisobject wordt gemaakt als een GPU-synchronisatieobject door D3D12DDICB_CREATESYNCHRONIZATIONOBJECT2 aan te roepen met:
Type is ingesteld op D3DDDI_CPU_NOTIFICATION.
vlaggen ingesteld op SignalByKmd om aan te geven dat het object wordt gesignaleerd door KMD. Deze vlag kan alleen worden ingesteld wanneer het type lid vanD3DDDI_SYNCHRONIZATIONOBJECTINFO2 is D3DDDI_CPU_NOTIFICATION.
Wanneer de vlag SignalByKmd is ingesteld, wordt DXGKDDI_CREATECPUEVENT aangeroepen om het KMD CPU-gebeurtenisobject te maken. Houd er rekening mee dat de apparaatgreep moet worden opgegeven bij het maken van het synchronisatieobject.
Het synchronisatieobject kan niet worden gebruikt in signaal- en wacht-API's (D3DKMTSignalSynchronizationObject, D3DKMTWaitForSynchronizatioObject). Het kan alleen worden gesignaleerd door KMD en UMD kan wachten op de bijbehorende CPU-gebeurtenis.
UMD escape om het gebruik van een KMD CPU-evenement-synchronisatieobject te definiëren
Er is een bekende ontsnappingsmogelijkheid toegevoegd aan D3DDDI_DRIVERESCAPETYPE. D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE wordt gebruikt om KMD op de hoogte te stellen van het beoogde gebruik van een KMD CPU-gebeurtenisobject. Een bekende escape wordt gedefinieerd door DXGKARG_ESCAPE::Flags.DriverKnownEscape = 1 in te stellen. Bekende escapes worden zelfs vanaf beveiligde virtuele machines naar de host verzonden.
Het volgende codefragment is een gebruiksvoorbeeld.
D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE Command = {};
Command.EscapeType = D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE;
Command.hSyncObject = SyncObjectHandle;
Command.Usage[0] = 1;
D3DKMT_ESCAPE Args = {};
Args.hAdapter = AdapterHandle;
Args.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
Args.Flags.DriverKnownEscape = 1;
Args.Flags.NoAdapterSynchronization = 1; // Prevent waking up the device from D3
Args.pPrivateDriverData = &Command;
Args.PrivateDriverDataSize = sizeof(Command);
NTSTATUS Status = D3DKMTEscape(&Args);
Dxgkrnl roept DXGKDDI_ESCAPE aan met het volgende:
- hDevice- ingesteld op de miniport-apparaatgreep die is gebruikt om het synchronisatieobject te maken
- pPrivateDriverData die verwijst naar een D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE-structuur
-
PrivateDriverDataSize ingesteld op
sizeof(D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE)
Een KMD CPU-gebeurtenisobject maken en vernietigen
De volgende DDIs worden gebruikt om KMD CPU-gebeurtenis-synchronisatie-objecten te maken en te vernietigen:
Een CPU-gebeurtenisobject signaleren door KMD
Als u een CPU-gebeurtenisobject wilt signaleren, roept KMD DXGKCB_SIGNALEVENT aan bij IRQL <= DISPATCH_LEVEL en met de DXGKARGCB_SIGNALEVENT structuurwaarden die als volgt zijn ingesteld:
hDxgkProcess is gelijk aan 0.
hEvent is gelijk aan de CPU-gebeurtenisobjecthandle Dxgkrnl die is doorgegeven aan DXGKDDI_CREATECPUEVENT.
CpuEventObject- moet 1 zijn.
gereserveerde moet 0 zijn.