Direct3D 11 på 12
D3D11On12 är en mekanism som utvecklare kan använda D3D11-gränssnitt och -objekt för att köra D3D12-API:et. D3D11on12 gör det möjligt för komponenter skrivna med D3D11 (till exempel D2D-text och användargränssnitt) att fungera tillsammans med komponenter som skrivits för D3D12-API:et. D3D11on12 möjliggör också inkrementell portning av ett program från D3D11 till D3D12, genom att göra det möjligt för delar av appen att fortsätta att rikta in sig på D3D11 för enkelhetens skull medan andra riktar in sig på D3D12 för prestanda, samtidigt som de alltid har fullständig och korrekt återgivning. D3D11On12 gör det enklare än att använda interop-tekniker för att dela resurser och synkronisera arbete mellan de två API:erna.
Initiera D3D11On12
För att börja använda D3D11On12 är det första steget att skapa en D3D12-enhet och kommandokö. Dessa objekt tillhandahålls som indata till initieringsmetoden D3D11On12CreateDevice. Du kan tänka dig den här metoden som att skapa en D3D11-enhet med den imaginära drivrutinstypen D3D_DRIVER_TYPE_11ON12, där D3D11-drivrutinen ansvarar för att skapa objekt och skicka kommandolistor till D3D12-API:et.
När du har en D3D11-enhet och en omedelbar kontext kan du QueryInterface
av enheten för gränssnittet ID3D11On12Enhet. Det här är det primära gränssnittet som används för interop mellan D3D11 och D3D12. För att både D3D11-enhetskontexten och D3D12-kommandolistorna ska fungera på samma resurser är det nödvändigt att skapa "omslutna resurser" med hjälp av CreateWrappedResource API. Den här metoden "befordrar" en D3D12-resurs så att den blir begriplig i D3D11. En omsluten resurs startar i tillståndet "förvärvad", en egenskap som manipuleras av AcquireWrappedResources och ReleaseWrappedResources metoder.
Exempel på användning
Typisk användning av D3D11On12 skulle vara att använda D2D för att återge text eller bilder ovanpå en D3D12-buffert. Se exempelexemplet D3D11On12 för exempelkod. Här är en grov beskrivning av de åtgärder som ska utföras för att göra det:
- Skapa en D3D12-enhet (D3D12CreateDevice) och en D3D12-växlingskedja (CreateSwapChain med en ID3D12CommandQueue- som indata).
- Skapa en D3D11On12-enhet med hjälp av D3D12-enheten och samma kommandokö som indata.
- Hämta växlingskedjans buffertar och skapa omslutna D3D11-resurser för var och en av dem. Indatatillståndet som används bör vara det sista sättet som D3D12 använde det (t.ex. RENDER_TARGET) och utdatatillståndet bör vara det sätt som D3D12 använder det när D3D11 har slutförts (t.ex. PRESENT).
- Initiera D2D och ange D3D11-omslutna resurser till D2D för att förbereda för återgivning.
Gör sedan följande på varje bildruta:
- Rendera till den aktuella växlingskedjans backbuffert med hjälp av en D3D12-kommandolista och kör den.
- Hämta den aktuella serverbuffertens omslutna resurs (AcquireWrappedResources).
- Utfärda D2D-återgivningskommandon.
- Släpp den omslutna resursen (ReleaseWrappedResources).
- Rensa D3D11 omedelbar kontext.
- Present (IDXGISwapChain1::P resent1).
Bakgrund
D3D11On12 fungerar systematiskt. Varje D3D11 API-anrop genomgår den typiska körningsverifieringen och tar sig till drivrutinen. På drivrutinsskiktet registrerar den särskilda 11on12-drivrutinen tillstånd och utfärdar återgivningsåtgärder till D3D12-kommandolistor. Dessa kommandolistor skickas efter behov (till exempel en fråga GetData
eller resurs Map
kan kräva att kommandon töms) eller på begäran av Flush. Om du skapar ett D3D11-objekt skapas vanligtvis motsvarande D3D12-objekt. Vissa åtgärder för fast funktionsåtergivning i D3D11, till exempel GenerateMips
eller DrawAuto
stöds inte i D3D12, och därför emulerar D3D11On12 dem med skuggningar och ytterligare resurser.
För interop är det viktigt att förstå hur D3D11On12 interagerar med de D3D12-objekt som appen har skapat och tillhandahållit. För att säkerställa att arbetet sker i rätt ordning måste den omedelbara kontexten D3D11 rensas innan ytterligare D3D12-arbete kan skickas till kön. Det är också viktigt att se till att kön som ges till D3D11On12 alltid måste vara tömbar. Det innebär att alla väntetider i kön så småningom måste uppfyllas, även om D3D11 renderar trådblock på obestämd tid. Var försiktig om du inte är beroende av när D3D11On12 infogar tömningar eller väntetider, eftersom detta kan ändras med framtida versioner. Dessutom spårar och manipulerar D3D11On12 resurstillstånd på egen hand. Det enda sättet att säkerställa samtidiga tillståndsövergångar är att använda API:erna för att hämta/släppa för att ändra tillståndsspårningen så att den matchar appens behov.
Rensa upp
För att kunna släppa en omsluten D3D11On12-resurs måste två saker hända i den här ordningen:
- Alla referenser till resursen, inklusive alla vyer av resursen, måste släppas.
- Uppskjuten destruktionsbearbetning måste ske. Det enklaste sättet att se till att detta händer är att anropa den omedelbara kontexten
Flush
API.
När båda dessa steg har slutförts bör alla referenser som tas av den omslutna resursen släppas och D3D12-resursen ägs exklusivt av D3D12-komponenten. Tänk på att D3D12 fortfarande kräver att GPU:n slutförs innan en resurs släpps helt, så se till att ha en referens på resursen innan du utför de två stegen ovan, såvida du inte redan har bekräftat att GPU:n inte längre använder resursen.
Alla andra resurser eller objekt som skapats av D3D11On12 rensas vid lämplig tidpunkt, när GPU:n har använt dem, med hjälp av D3D11:s mekanism för uppskjuten destruktion. Men om du försöker släppa själva D3D11On12-enheten medan GPU:n fortfarande körs kan destruktionen blockeras tills GPU:n har slutförts.
Begränsningar
D3D11On12-lagret implementerar en mycket stor delmängd av D3D11-API:et, men det finns några kända luckor (förutom buggar i implementeringen som kan orsaka felaktig återgivning).
Från och med Windows 10 version 1809 (10.0; Build 17763), så länge D3D11On12 körs på en drivrutin som stöder Shader Model 6.0 eller senare, kan den köra skuggningar som använder gränssnitt. I tidigare versioner av Windows implementeras inte funktionen för skuggningsgränssnitt i D3D11On12, och om du försöker använda funktionen orsakas fel och felsökningsmeddelanden.
Från och med Windows 10 version 1803 (10.0; Build 17134), växlingskedjor stöds på D3D11On12-enheter. I tidigare versioner av Windows är de inte det.
D3D11On12 har inte optimerats för prestanda. Det kommer sannolikt att finnas måttliga processorkostnader jämfört med en D3D11-standarddrivrutin, minimalA GPU-omkostnader och det är känt att det finns betydande minnesomkostnader. Därför rekommenderas det inte att använda D3D11On12 för komplicerade 3D-scener, och det rekommenderas i stället för enkla scener eller 2D-rendering.
Api
API:er som utgör 11on12-lagret beskrivs i 11on12-referens.
Relaterade ämnen