Direct3D 11 op 12
D3D11On12 is een mechanisme waarmee ontwikkelaars D3D11-interfaces en -objecten kunnen gebruiken om de D3D12-API te besturen. Met D3D11on12 kunnen onderdelen die zijn geschreven met D3D11 (bijvoorbeeld D2D-tekst en gebruikersinterface) samenwerken met onderdelen die zijn geschreven op basis van de D3D12-API. D3D11on12 maakt ook incrementele overdracht van een toepassing van D3D11 naar D3D12 mogelijk door delen van de app in te schakelen om D3D11 te blijven gebruiken voor eenvoud, terwijl anderen zich op D3D12 richten voor prestaties, terwijl altijd volledige en juiste rendering wordt uitgevoerd. D3D11On12 maakt het eenvoudiger dan het gebruik van interoperabiliteitstechnieken om resources te delen en werk tussen de twee API's te synchroniseren.
- D3D11On12 initialiseren
- voorbeeldgebruik
- achtergrond
- opschonen
- beperkingen
- API's
- Verwante onderwerpen
D3D11On12 initialiseren
Als u D3D11On12 wilt gaan gebruiken, moet u eerst een D3D12-apparaat en een opdrachtwachtrij maken. Deze objecten worden geleverd als invoer voor de initialisatiemethode D3D11On12CreateDevice. U kunt deze methode beschouwen als het maken van een D3D11-apparaat met het imaginaire stuurprogrammatype D3D_DRIVER_TYPE_11ON12, waarbij het D3D11-stuurprogramma verantwoordelijk is voor het maken van objecten en het verzenden van opdrachtlijsten naar de D3D12-API.
Nadat u een D3D11-apparaat en directe context hebt, kunt u QueryInterface
van het apparaat voor de ID3D11On11On12Device-interface. Dit is de primaire interface die wordt gebruikt voor interop tussen D3D11 en D3D12. Als u zowel de D3D11-apparaatcontext als de D3D12-opdrachtlijsten op dezelfde resources wilt laten werken, moet u 'verpakte resources' maken met behulp van de CreateWrappedResource API. Deze methode bevordert een D3D12-resource om begrijpelijk te zijn in D3D11. Een verpakte resource begint met de status 'overgenomen', een eigenschap die wordt bewerkt door de AcquireWrappedResources en ReleaseWrappedResources methoden.
Voorbeeldgebruik
Normaal gesproken zou D3D11On12 D2D moeten worden gebruikt om tekst of afbeeldingen weer te geven boven op een D3D12-backbuffer. Zie het voorbeeld D3D11On12 voor voorbeeldcode. Hier volgt een ruw overzicht van de stappen die u moet uitvoeren:
- Maak een D3D12-apparaat (D3D12CreateDevice) en een D3D12-wisselketen (CreateSwapChain met een ID3D12CommandQueue als invoer).
- Maak een D3D11On12-apparaat met behulp van het D3D12-apparaat en dezelfde opdrachtwachtrij als invoer.
- Haal de buffers voor de wisselketen terug en maak D3D11 verpakte resources voor elk van deze resources. De gebruikte invoerstatus moet de laatste manier zijn waarop D3D12 deze heeft gebruikt (bijvoorbeeld RENDER_TARGET) en de uitvoerstatus moet de manier zijn waarop D3D12 deze gebruikt nadat D3D11 is voltooid (bijvoorbeeld PRESENT).
- Initialiseer D2D en geef de D3D11 verpakte resources op aan D2D om de rendering voor te bereiden.
Ga vervolgens op elk frame als volgt te werk:
- Geef deze weer in de huidige buffer voor wisselketenback met behulp van een D3D12-opdrachtlijst en voer deze uit.
- Verwerf de verpakte resource van de huidige backbuffer (AcquireWrappedResources).
- Geef D2D-renderingopdrachten uit.
- Laat de verpakte resource los (ReleaseWrappedResources).
- De D3D11-directe context leegmaken.
- Aanwezig (IDXGISwapChain1::P resent1).
Achtergrond
D3D11On12 werkt systematisch. Elke D3D11-API-aanroep doorloopt de gebruikelijke runtimevalidatie en gaat naar het stuurprogramma. Op de stuurprogrammalaag registreert het speciale 11on12-stuurprogramma de status en problemen met het renderen van bewerkingen naar D3D12-opdrachtlijsten. Deze opdrachtlijsten worden indien nodig verzonden (bijvoorbeeld een query GetData
of resource-Map
vereist dat opdrachten worden leeggemaakt) of zoals aangevraagd door Flush. Het maken van een D3D11-object resulteert doorgaans in het bijbehorende D3D12-object dat wordt gemaakt. Sommige vaste functieweergavebewerkingen in D3D11, zoals GenerateMips
of DrawAuto
, worden niet ondersteund in D3D12 en D3D11On12 emuleren ze met behulp van shaders en extra resources.
Voor interoperabiliteit is het belangrijk om te begrijpen hoe D3D11On12 communiceert met de D3D12-objecten die de app heeft gemaakt en verstrekt. Om ervoor te zorgen dat het werk in de juiste volgorde plaatsvindt, moet de directe context van D3D11 worden leeggemaakt voordat extra D3D12-werk kan worden verzonden naar die wachtrij. Het is ook belangrijk om ervoor te zorgen dat de wachtrij die aan D3D11On12 wordt gegeven, altijd leeg moet zijn. Dit betekent dat alle wachttijden in de wachtrij uiteindelijk moeten worden voldaan, zelfs als de D3D11 thread voor onbepaalde tijd blokkeert. Wees voorzichtig om niet afhankelijk te zijn van wanneer D3D11On12 wordt ingevoegd of wordt gewacht, omdat dit kan veranderen met toekomstige releases. Daarnaast houdt D3D11On12 resourcestatussen zelfstandig bij en bewerkt. De enige manier om ervoor te zorgen dat statusovergangen overeenkomen, is door gebruik te maken van de acquire/release-API's om het bijhouden van statussen aan te passen aan de behoeften van de app.
Opschonen
Als u een verpakte D3D11On12-resource wilt vrijgeven, moeten er twee dingen gebeuren in deze volgorde:
- Alle verwijzingen naar de resource, inclusief eventuele weergaven van de resource, moeten worden vrijgegeven.
- Uitgestelde vernietigingsverwerking moet plaatsvinden. De eenvoudigste manier om ervoor te zorgen dat dit gebeurt, is door de onmiddellijke context
Flush
API aan te roepen.
Nadat beide stappen zijn voltooid, moeten alle verwijzingen die door de verpakte resource worden genomen, worden vrijgegeven en wordt de D3D12-resource exclusief eigendom van het D3D12-onderdeel. Houd er rekening mee dat D3D12 nog steeds moet wachten op GPU-voltooiing voordat u een resource volledig vrijgeeft. Zorg er dus voor dat u een verwijzing op de resource bewaart voordat u de bovenstaande twee stappen uitvoert, tenzij u al hebt bevestigd dat de GPU de resource niet meer gebruikt.
Alle andere resources of objecten die zijn gemaakt door D3D11On12, worden op het juiste moment opgeschoond, wanneer de GPU klaar is met het gebruik ervan, met behulp van het uitgestelde vernietigingsmechanisme van D3D11. Als u echter probeert het D3D11On12-apparaat zelf vrij te geven terwijl de GPU nog steeds wordt uitgevoerd, kan de vernietiging blokkeren totdat de GPU is voltooid.
Beperkingen
De D3D11On12-laag implementeert een zeer grote subset van de D3D11-API, maar er zijn enkele bekende hiaten (naast fouten in de implementatie die onjuiste rendering kunnen veroorzaken).
Vanaf Windows 10 versie 1809 (10.0; Build 17763), zolang D3D11On12 wordt uitgevoerd op een stuurprogramma dat Shader Model 6.0 of hoger ondersteunt, kan het shaders uitvoeren die gebruikmaken van interfaces. In eerdere versies van Windows wordt de arceringsinterfacefunctie niet geïmplementeerd in D3D11On12 en als u probeert de functie te gebruiken, worden fouten en foutopsporingsberichten veroorzaakt.
Vanaf Windows 10 versie 1803 (10.0; Build 17134), wisselketens worden ondersteund op D3D11On12-apparaten. In eerdere versies van Windows zijn ze dat niet.
D3D11On12 is niet geoptimaliseerd voor prestaties. Er zal waarschijnlijk gemiddelde CPU-overhead zijn vergeleken met een standaard D3D11-stuurprogramma, minimale GPU-overhead en er is bekend dat er aanzienlijke geheugenoverhead is. Daarom wordt het niet aanbevolen om D3D11On12 te gebruiken voor gecompliceerde 3D-scènes en wordt het in plaats daarvan aanbevolen voor eenvoudige scènes of 2D-rendering.
Apis
API's waaruit de laag 11on12 bestaat, worden beschreven in 11on12 Reference.
Verwante onderwerpen