Sdílení zařízení Surface mezi grafickými rozhraními API pro Windows
Toto téma obsahuje technický přehled interoperability pomocí sdílení plochy mezi grafickými rozhraními API systému Windows, včetně Rozhraní Direct3D 11, Direct2D, DirectWrite, Direct3D 10 a Direct3D 9Ex. Pokud už máte funkční znalosti těchto rozhraní API, může vám tento dokument pomoct použít více rozhraní API k vykreslení na stejnou plochu v aplikaci navržené pro operační systémy Windows 7 nebo Windows Vista. Toto téma také obsahuje pokyny osvědčených postupů a odkazy na další zdroje informací.
Poznámka
Pro interoperabilitu Direct2D a DirectWrite v modulu runtime DirectX 11.1 můžete použít zařízení Direct2D a kontexty zařízení k přímému vykreslení zařízení Direct3D 11.
Toto téma obsahuje následující části.
- Úvod
- Přehled interoperability rozhraní API
- scénáře interoperability
- závěr
Úvod
V tomto dokumentu se interoperabilita grafického rozhraní API systému Windows týká sdílení stejného vykreslovacího povrchu různými rozhraními API. Tento druh interoperability umožňuje aplikacím vytvářet poutavé displeje pomocí několika grafických rozhraní API systému Windows a usnadnit migraci na nové technologie zachováním kompatibility s existujícími rozhraními API.
V systémech Windows 7 (a Windows Vista SP2 s sadou Windows 7 Interop Pack, Vista 7IP) jsou rozhraní API pro vykreslování grafiky Direct3D 11, Direct2D, Direct3D 10.1, Direct3D 10.0, Direct3D 9Ex, Direct3D 9c a starší rozhraní API Direct3D, stejně jako rozhraní GDI a GDI+. Windows Imaging Component (WIC) a DirectWrite jsou související technologie pro zpracování obrázků a Direct2D provádí vykreslování textu. Rozhraní API pro akceleraci videa DirectX (DXVA) založené na Direct3D 9c a Direct3D 9Ex se používá ke zpracování videa.
Vzhledem k tomu, že se rozhraní API grafického rozhraní Windows vyvíjejí směrem k tomu, aby byla založená na Direct3D, Microsoft investoval větší úsilí do zajištění interoperability napříč rozhraními API. Nově vyvinutá rozhraní API Direct3D a rozhraní API vyšší úrovně založená na rozhraních API Direct3D také poskytují podporu v případě potřeby pro přemostění kompatibility se staršími rozhraními API. Pro ilustraci můžou aplikace Direct2D používat Direct3D 10.1 sdílením zařízení Direct3D 10.1. Rozhraní API Direct3D 11, Direct2D a Direct3D 10.1 můžou využívat také rozhraní API DirectX Graphics Infrastructure (DXGI) 1.1, která umožňuje synchronizované sdílené povrchy, které plně podporují interoperabilitu mezi těmito rozhraními API. Rozhraní API založená na DXGI 1.1 vzájemně spolupracuje s GDI a GDI+ přidružením, a to získáním kontextu zařízení GDI z povrchu DXGI 1.1.
Nesynchronizované sdílení povrchu podporuje modul runtime Direct3D 9Ex. Video aplikace založené na dxva můžou pro interoperabilitu DXVA s Direct3D 9Ex a DXGI použít pomocnou rutinu Direct3D 9Ex pro interoperabilitu DXVA s Direct3D 11 pro výpočetní shader nebo může spolupracovat s Direct2D pro 2D ovládací prvky nebo vykreslování textu. WIC a DirectWrite také vzájemně spolupracuje s rozhraními GDI, Direct2D a přidružením dalších rozhraní API Direct3D.
Direct3D 10.0, Direct3D 9c a starší moduly runtime Direct3D nepodporují sdílené plochy. Kopie systémové paměti budou nadále používány pro interoperabilitu s rozhraními API založenými na GDI nebo DXGI.
Všimněte si, že scénáře interoperability v tomto dokumentu odkazují na několik grafických rozhraní API, která se vykreslují na sdílenou plochu vykreslování, a ne na stejné okno aplikace. Synchronizace pro samostatná rozhraní API cílící na různé povrchy, které se pak skládají do stejného okna, je mimo rozsah tohoto dokumentu.
Přehled interoperability rozhraní API
Interoperabilitu rozhraní API grafického rozhraní Windows pro sdílení zařízení Surface je možné popsat ve scénářích rozhraní API-to-API a odpovídajících funkcích interoperability. Od Windows 7 a od windows Vista SP2 s 7IP zahrnují nová rozhraní API a přidružené moduly runtime Direct2D a související technologie: Direct3D 11 a DXGI 1.1. Ve Windows 7 byl také vylepšen výkon GDI. Direct3D 10.1 byl představen v systému Windows Vista SP1. Následující diagram znázorňuje podporu interoperability mezi rozhraními API.
V tomto diagramu znázorňují šipky scénáře interoperability, ve kterých může být stejná plocha přístupná připojenými rozhraními API. Modré šipky označují mechanismy interoperability zavedené v systému Windows Vista. Zelené šipky označují podporu interoperability pro nová rozhraní API nebo vylepšení, která pomáhají starším rozhraním API spolupracovat s novějšími rozhraními API. Například zelené šipky představují sdílení zařízení, synchronizovanou podporu sdíleného povrchu, pomocníka pro synchronizaci Direct3D 9Ex/DXGI a získání kontextu zařízení GDI z kompatibilního povrchu.
Scénáře interoperability
Od windows 7 a Windows Vista 7IP podporují hlavní nabídky z grafických rozhraní API systému Windows více rozhraní API pro vykreslování na stejnou plochu DXGI 1.1.
Direct3D 11, Direct3D 10.1, Direct2D – vzájemná interoperabilita
Rozhraní API Direct3D 11, Direct3D 10.1 a Direct2D (a související rozhraní API, jako jsou DirectWrite a WIC), můžou vzájemně spolupracovat pomocí sdílení zařízení Direct3D 10.1 nebo synchronizovaných sdílených ploch.
Sdílení zařízení Direct3D 10.1 s Direct2D
Sdílení zařízení mezi Direct2D a Direct3D 10.1 umožňuje aplikaci bez problémů a efektivně vykreslit na stejnou plochu DXGI 1.1 pomocí stejného základního objektu zařízení Direct3D. Direct2D poskytuje možnost volat rozhraní API Direct2D pomocí existujícího zařízení Direct3D 10.1 s využitím faktu, že Direct2D je postaven na modulech runtime Direct3D 10.1 a DXGI 1.1. Následující fragmenty kódu ukazují, jak Direct2D získá cíl vykreslení zařízení Direct3D 10.1 z povrchu DXGI 1.1 přidruženého k zařízení. Cíl vykreslení zařízení Direct3D 10.1 může provádět volání výkresu Direct2D mezi rozhraními BeginDraw a EndDraw API.
// Direct3D 10.1 Device and Swapchain creation
HRESULT hr = D3D10CreateDeviceandSwapChain1(
pAdapter,
DriverType,
Software,
D3D10_CREATE_DEVICE_BGRA_SUPPORT,
featureLevel,
D3D10_1_SDK_VERSION,
pSwapChainDesc,
&pSwapChain,
&pDevice
);
hr = pSwapChain->GetBuffer(
0,
__uuidof(IDXGISurface),
(void **)&pDXGIBackBuffer
));
// Direct3D 10.1 API rendering calls
...
hr = D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
&m_spD2DFactory
));
pD2DFactory->CreateDxgiSurfaceRenderTarget(
pDXGIBackBuffer,
&renderTargetProperties,
&pD2DBackBufferRenderTarget
));
...
pD2DBackBufferRenderTarget->BeginDraw();
//Direct2D API rendering calls
...
pD2DBackBufferRenderTarget->EndDraw();
pSwapChain->Present(0, 0);
poznámky
- Přidružené zařízení Direct3D 10.1 musí podporovat formát BGRA. Toto zařízení bylo vytvořeno voláním D3D10CreateDevice1 s parametrem D3D10_CREATE_DEVICE_BGRA_SUPPORT. Formát BGRA se podporuje od verze Direct3D 10 na úrovni funkce 9.1.
- Aplikace by neměla vytvořit více ID2D1RenderTargets asociace ke stejnému zařízení Direct3D10.1.
- Pro zajištění optimálního výkonu udržujte vždy alespoň jeden prostředek, jako jsou textury nebo povrchy přidružené k zařízení.
Sdílení zařízení je vhodné pro zpracování jednovláknové použití jednoho vykreslovacího zařízení sdíleného rozhraními API pro vykreslování Direct3D 10.1 a Direct2D. Synchronizované sdílené plochy umožňují vícevláknové, probíhající a zastaralé využití více vykreslovacích zařízení používaných rozhraními API Direct3D 10.1, Direct2D a Direct3D 11.
Další metodou interoperability Direct3D 10.1 a Direct2D je použití ID3D1RenderTarget::CreateSharedBitmap, který vytvoří objekt ID2D1Bitmap z IDXGISurface. Do rastrového obrázku můžete napsat scénu Direct3D10.1 a vykreslit ji pomocí Direct2D. Další informace naleznete v tématu ID2D1RenderTarget::CreateSharedBitmap – metoda.
Rasterizace softwaru Direct2D
Sdílení zařízení s Direct3D 10.1 se nepodporuje při použití rendereru softwaru Direct2D, například zadáním D2D1_RENDER_TARGET_USAGE_FORCE_SOFTWARE_RENDERING v D2D1_RENDER_TARGET_USAGE při vytváření cíle vykreslování Direct2D.
Direct2D může použít softwarový rasterizátor WARP10 ke sdílení zařízení s Direct3D 10 nebo Direct3D 11, ale výkon výrazně klesá.
DXGI 1.1 Synchronizované sdílené povrchy
Rozhraní API Direct3D 11, Direct3D 10.1 a Direct2D používají rozhraní DXGI 1.1, která poskytuje funkce pro synchronizaci čtení z a zápisu na stejnou plochu paměti videa (DXGISurface1) dvěma nebo více zařízeními Direct3D. Vykreslovací zařízení používající synchronizované sdílené plochy můžou být zařízení Direct3D 10.1 nebo Direct3D 11, která běží ve stejném procesu nebo napříč procesy.
Aplikace můžou používat synchronizované sdílené plochy k vzájemné spolupráci mezi libovolnými zařízeními založenými na DXGI 1.1, jako jsou Direct3D 11 a Direct3D 10.1 nebo mezi Direct3D 11 a Direct2D, získáním zařízení Direct3D 10.1 z cílového objektu vykreslení Direct2D.
V rozhraních API Direct3D 10.1 a novějších zajistěte, aby bylo možné použít DXGI 1.1, aby se zařízení Direct3D vytvořilo pomocí objektu adaptéru DXGI 1.1, který se vypíše z objektu továrny DXGI 1.1. Volání CreateDXGIFactory1 vytvořit IDXGIFactory1 objektu a EnumAdapters1 vytvořit výčet IDXGIAdapter1 objektu. Objekt IDXGIAdapter1 musí být předán jako součást volání D3D10CreateDevice nebo D3D10CreateDeviceAndSwapChain. Další informace o rozhraních API DXGI 1.1 najdete v průvodci programováním pro DXGI.
Rozhraní api
D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX
Při vytváření synchronizovaného sdíleného prostředku nastavte D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX v D3D10_RESOURCE_MISC_FLAG.
typedef enum D3D10_RESOURCE_MISC_FLAG {
D3D10_RESOURCE_MISC_GENERATE_MIPS = 0x1L,
D3D10_RESOURCE_MISC_SHARED = 0x2L,
D3D10_RESOURCE_MISC_TEXTURECUBE = 0x4L,
D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX = 0x10L,
D3D10_RESOURCE_MISC_GDI_COMPATIBLE = 0x20L,
} D3D10_RESOURCE_MISC_FLAG;
D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX
Umožňuje synchronizaci prostředku pomocí rozhraní API IDXGIKeyedMutex::AcquireSync a ReleaseSync. Následující rozhraní API pro vytvoření prostředku Direct3D 10.1, která všechna přebírají parametr D3D10_RESOURCE_MISC_FLAG, byla rozšířena tak, aby podporovala nový příznak.
- ID3D10Device1::CreateTexture1D
- ID3D10Device1::CreateTexture2D
- ID3D10Device1::CreateTexture3D
- ID3D10Device1::CreateBuffer
Pokud se některé z uvedených funkcí volají se sadou příznaků D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX, může být vrácené rozhraní dotazováno na rozhraní IDXGIKeyedMutex, které implementuje rozhraní AcquireSync a ReleaseSync API pro synchronizaci přístupu k povrchu. Zařízení, které vytváří povrch a jakékoli jiné zařízení, které otevírá povrch (pomocí OpenSharedResource), se vyžaduje k volání IDXGIKeyedMutex::AcquireSync před vykreslením příkazů na povrch a IDXGIKeyedMutex::ReleaseSync po dokončení vykreslování.
Zařízení WARP a REF nepodporují sdílené prostředky. Pokus o vytvoření prostředku s tímto příznakem na zařízení WARP nebo REF způsobí, že metoda vytvoření vrátí kód chyby E_OUTOFMEMORY.
ROZHRANÍ IDXGIKEYEDMUTEX
Nové rozhraní v DXGI 1.1, IDXGIKeyedMutex, představuje klíčovaný mutex, který umožňuje výhradní přístup ke sdílenému prostředku, který je používán více zařízeními. Referenční dokumentaci k tomuto rozhraní a jeho dvou metod, AcquireSync a ReleaseSync, naleznete v IDXGIKeyedMutex.
Ukázka: Synchronizované sdílení povrchu mezi dvěma zařízeními Direct3D 10.1
Následující příklad ukazuje sdílení povrchu mezi dvěma zařízeními Direct3D 10.1. Synchronizovaný sdílený povrch je vytvořen zařízením Direct3D10.1.
// Create Sync Shared Surface using Direct3D10.1 Device 1.
D3D10_TEXTURE2D_DESC desc;
ZeroMemory( &desc, sizeof(desc) );
desc.Width = width;
desc.Height = height;
desc.MipLevels = 1;
desc.ArraySize = 1;
// must match swapchain format in order to CopySubresourceRegion.
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D10_USAGE_DEFAULT;
// creates 2D texture as a Synchronized Shared Surface.
desc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
ID3D10Texture2D* g_pShared = NULL;
g_pd3dDevice1->CreateTexture2D( &desc, NULL, &g_pShared );
// QI IDXGIResource interface to synchronized shared surface.
IDXGIResource* pDXGIResource = NULL;
g_pShared->QueryInterface(__uuidof(IDXGIResource), (LPVOID*) &pDXGIResource);
// obtain handle to IDXGIResource object.
pDXGIResource->GetSharedHandle(&g_hsharedHandle);
pDXGIResource->Release();
if ( !g_hsharedHandle )
return E_FAIL;
// QI IDXGIKeyedMutex interface of synchronized shared surface's resource handle.
hr = g_pShared->QueryInterface( __uuidof(IDXGIKeyedMutex),
(LPVOID*)&g_pDXGIKeyedMutex_dev1 );
If ( FAILED( hr ) || ( g_pDXGIKeyedMutex_dev1 == NULL ) )
return E_FAIL;
Stejné zařízení Direct3D10.1 může získat synchronizovanou sdílenou plochu pro vykreslování voláním AcquireSync a uvolněním povrchu pro vykreslování druhého zařízení voláním ReleaseSync. Pokud synchronizovanou sdílenou plochu nesdílíte s žádným jiným zařízením Direct3D, může tvůrce získat a uvolnit synchronizovanou sdílenou plochu (pro zahájení a ukončení vykreslování) získáním a uvolněním pomocí stejné hodnoty klíče.
// Obtain handle to Sync Shared Surface created by Direct3D10.1 Device 1.
hr = g_pd3dDevice2->OpenSharedResource( g_hsharedHandle,__uuidof(ID3D10Texture2D),
(LPVOID*) &g_pdev2Shared);
if (FAILED (hr))
return hr;
hr = g_pdev2Shared->QueryInterface( __uuidof(IDXGIKeyedMutex),
(LPVOID*) &g_pDXGIKeyedMutex_dev2);
if( FAILED( hr ) || ( g_pDXGIKeyedMutex_dev2 == NULL ) )
return E_FAIL;
// Rendering onto Sync Shared Surface from D3D10.1 Device 1 using D3D10.1 Device 2.
UINT acqKey = 1;
UINT relKey = 0;
DWORD timeOut = 5;
DWORD result = g_pDXGIKeyedMutex_dev2->AcquireSync(acqKey, timeOut);
if ( result == WAIT_OBJECT_0 )
// Rendering calls using Device 2.
else
// Handle unable to acquire shared surface error.
result = g_pDXGIKeyedMutex_dev2->ReleaseSync(relKey));
if (result == WAIT_OBJECT_0)
return S_OK;
Druhé zařízení Direct3D10.1 může získat synchronizovanou sdílenou plochu pro vykreslování voláním AcquireSync a uvolněním povrchu pro vykreslování prvního zařízení voláním ReleaseSync. Všimněte si, že zařízení 2 dokáže získat synchronizovanou sdílenou plochu pomocí stejné hodnoty klíče jako zařízení 1 zadaného ve volání ReleaseSync.
// Rendering onto Sync Shared Surface from D3D10.1 Device 1 using D3D10.1 Device 1.
UINT acqKey = 0;
UINT relKey = 1;
DWORD timeOut = 5;
DWORD result = g_pDXGIKeyedMutex_dev1->AcquireSync(acqKey, timeOut);
if (result == WAIT_OBJECT_0)
// Rendering calls using Device 1.
else
// Handle unable to acquire shared surface error.
result = g_pDXGIKeyedMutex_dev1->ReleaseSync(relKey));
if ( result == WAIT_OBJECT_0 )
return S_OK;
Další zařízení sdílející stejnou plochu se můžou střídat a uvolnit povrch pomocí dalších kláves, jak je znázorněno v následujících voláních.
// Within Device 1's process/thread:
// Rendering onto Sync Shared Surface from D3D10.1 Device 1 using D3D10.1 Device 1
result = g_pDXGIKeyedMutex_dev1->AcquireSync(0, timeOut);
// Rendering calls using Device 1
...
result = g_pDXGIKeyedMutex_dev1->ReleaseSync(1);
...
////////////////////////////////////////////////////////////////////////////
// Within Device 2's process/thread:
// Rendering onto Sync Shared Surface from D3D10.1 Device 1 using D3D10.1 Device 2
result = g_pDXGIKeyedMutex_dev2->AcquireSync(1, timeOut);
// Rendering calls using Device 2
...
result = g_pDXGIKeyedMutex_dev1->ReleaseSync(2);
////////////////////////////////////////////////////////////////////////////
// Within Device 3's process/thread:
// Rendering onto Sync Shared Surface from D3D10.1 Device 1 using D3D10.1 Device 3
result = g_pDXGIKeyedMutex_dev1->AcquireSync(2, timeOut);
// Rendering calls using Device 3
...
result = g_pDXGIKeyedMutex_dev1->ReleaseSync(0);
...
Všimněte si, že skutečná aplikace se může vždy vykreslit na zprostředkující povrch, který se pak zkopíruje do sdíleného povrchu, aby se zabránilo tomu, že jakékoli zařízení čeká na jiném zařízení, které sdílí plochu.
Použití synchronizovaných sdílených povrchů s Direct2D a Direct3D 11
Podobně pro sdílení mezi rozhraními API Direct3D 11 a Direct3D 10.1 je možné synchronizovanou sdílenou plochu vytvořit buď ze zařízení ROZHRANÍ API, a sdílet je s ostatními zařízeními rozhraní API nebo mimo proces.
Aplikace, které používají Direct2D, můžou sdílet zařízení Direct3D 10.1 a používat synchronizovaný sdílený povrch pro spolupráci s Direct3D 11 nebo jinými zařízeními Direct3D 10.1 bez ohledu na to, jestli patří ke stejnému procesu nebo různým procesům. Pro jednoprocesové aplikace s jedním vláknem je sdílení zařízení nejvýkonnější a nejefektivnější metodou interoperability mezi Direct2D a Direct3D 10 nebo Direct3D 11.
Software Rasterizer
Synchronizované sdílené povrchy nejsou podporovány, pokud aplikace používají rastrátory softwaru Direct3D nebo Direct2D, včetně referenční rasterizátoru a WARP, namísto použití hardwaru grafické akcelerace.
Interoperabilita mezi rozhraními API založenými na Direct3D 9Ex a DXGI
Rozhraní API Direct3D 9Ex zahrnovala koncept sdílení povrchu, aby ostatní rozhraní API mohla číst ze sdíleného povrchu. Pokud chcete sdílet čtení a zápis do sdíleného povrchu Direct3D 9Ex, musíte do samotné aplikace přidat ruční synchronizaci.
Direct3D 9Ex Shared Surfaces Plus pomocník pro ruční synchronizaci
Nejzákladnější úlohou interoperability Direct3D 9Ex a Direct3D 10 nebo 11 je předání jediné plochy z prvního zařízení (zařízení A) na druhé (zařízení B), aby při získání úchytu na povrchu bylo zaručeno dokončení vykreslování zařízení A. Zařízení B proto může tuto plochu používat bez obav. To je velmi podobné klasickému problému producenta-spotřebitele a tato diskuze modeluje problém tímto způsobem. První zařízení, které používá povrch, a pak ho znovu zpochybní producent (Device A) a zařízení, které na začátku čeká, je příjemce (Zařízení B). Každá skutečná aplikace je propracovanější než tato a zřetězí několik stavebních bloků pro producenty a vytvoří požadovanou funkci.
Stavební bloky producenta-příjemce jsou implementovány v pomocné rutině pomocí fronty povrchů. Povrchy jsou zapsány do fronty producentem a vyřadit z fronty spotřebitele. Pomocník zavádí tři rozhraní COM: ISurfaceQueue, ISurfaceProducer, a ISurfaceConsumer.
přehled pomocníka High-Level
Objekt ISurfaceQueue je stavební blok pro použití sdílených ploch. Vytvoří se s inicializovaným zařízením Direct3D a popisem pro vytvoření pevného počtu sdílených ploch. Objekt fronty spravuje vytváření prostředků a otevírání kódu. Počet a typ povrchů jsou pevné; po vytvoření povrchů je aplikace nemůže přidat ani odebrat.
Každá instance objektu ISurfaceQueue poskytuje určitou jednosměrnou ulici, která se dá použít k odesílání povrchů z výrobního zařízení do spotřebujícího zařízení. Několik takových jednosměrných ulic se dá použít k povolení scénářů sdílení povrchu mezi zařízeními konkrétních aplikací.
vytvoření nebo životnost objektu
Existují dva způsoby vytvoření objektu fronty: prostřednictvím CreateSurfaceQueue, nebo prostřednictvím Clone metoda ISurfaceQueue. Vzhledem k tomu, že rozhraní jsou objekty MODELU COM, platí standardní správa životnosti modelu COM.
model producenta/spotřebitele
Enqueue (): Producent volá tuto funkci, která označuje, že je hotová s povrchem, který se teď může zpřístupnit jinému zařízení. Po návratu z této funkce už zařízení producenta nemá oprávnění k povrchu a je nebezpečné ho dál používat.
Dequeue (): Spotřeba zařízení volá tuto funkci, aby získalo sdílenou plochu. Rozhraní API zaručuje, že všechny odvrácené povrchy jsou připravené k použití.
metadat
Rozhraní API podporuje přidružení metadat ke sdíleným povrchem.
Enqueue() má možnost zadat další metadata, která se předají spotřebě zařízení. Metadata musí být v době vytvoření menší než maximální známá.
Dequeue() může volitelně předat vyrovnávací paměť a ukazatel na velikost vyrovnávací paměti. Fronta vyplní vyrovnávací paměť metadaty z odpovídajícího volání enqueue.
klonování
Každý objekt ISurfaceQueue řeší jednosměrnou synchronizaci. Předpokládáme, že velká většina aplikací používajících toto rozhraní API bude používat uzavřený systém. Nejjednodušší uzavřený systém se dvěma zařízeními odesílajícími povrchy tam a zpět vyžaduje dvě fronty. ISurfaceQueue objekt má Clone() metoda, aby bylo možné vytvořit více front, které jsou všechny součástí stejného většího kanálu.
Clone vytvoří nový objekt ISurfaceQueue z existujícího objektu a sdílí všechny otevřené prostředky mezi nimi. Výsledný objekt má přesně stejné plochy jako zdrojová fronta. Klonované fronty můžou mít různé velikosti metadat od sebe.
povrchy
ISurfaceQueue přebírá odpovědnost za vytváření a řízení jeho povrchů. Není platné vytvořit výčet libovolných povrchů. Povrch by navíc měl mít jenom jednoho aktivního "vlastníka". Měl by být buď v konkrétní frontě, nebo ho používat konkrétní zařízení. Není platné ho mít ve více frontách nebo aby zařízení po zařazení do fronty pokračovala v používání povrchu.
Podrobnosti rozhraní API
IsurfaceQueue
Fronta zodpovídá za vytváření a údržbu sdílených prostředků. Poskytuje také funkce zřetězování více front pomocí klonování. Fronta obsahuje metody, které otevírají produkční zařízení a spotřebovávají zařízení. Kdykoli je možné otevřít pouze jeden z nich.
Fronta zveřejňuje následující rozhraní API:
Rozhraní api | Popis |
---|---|
CreateSurfaceQueue | Vytvoří objekt ISurfaceQueue (kořenová fronta). |
ISurfaceQueue::OpenConsumer | Vrátí rozhraní pro spotřebovávající zařízení, které má být vyřazeno z fronty. |
ISurfaceQueue::OpenProducer | Vrátí rozhraní pro produkční zařízení k zařazení do fronty. |
ISurfaceQueue::Clone | Vytvoří objekt ISurfaceQueue, který sdílí povrchy s objektem kořenové fronty. |
CreateSurfaceQueue
typedef struct SURFACE_QUEUE_DESC {
UINT Width;
UINT Height;
DXGI_FORMAT Format;
UINT NumSurfaces;
UINT MetaDataSize;
DWORD Flags;
} SURFACE_QUEUE_DESC;
členové
Šířka, Výška Rozměry sdílených ploch. Všechny sdílené povrchy musí mít stejné rozměry.
Formát Formát sdílených ploch. Všechny sdílené plochy musí mít stejný formát. Platné formáty závisí na zařízeních, která budou použita, protože různé páry zařízení můžou sdílet různé typy formátů.
NumSurfaces Počet povrchů, které jsou součástí fronty. Jedná se o pevné číslo.
MetaDataSize Maximální velikost vyrovnávací paměti metadat.
Flags Flags to control the behavior of the queue. Viz poznámky.
HRESULT CreateSurfaceQueue(
[in] SURFACE_QUEUE_DESC *pDesc,
[in] IUnknown *pDevice,
[out] IDXGIXSurfaceQueue **ppQueue
);
parametrů
pDesc [in] Popis fronty sdíleného povrchu, která se má vytvořit.
pDevice [in] Zařízení, které by mělo být použito k vytvoření sdílených ploch. Jedná se o explicitní parametr z důvodu funkce v systému Windows Vista. U ploch sdílených mezi Direct3D 9 a Direct3D 10 musí být povrchy vytvořeny pomocí Direct3D 9.
ppQueue [out] Při návratu obsahuje ukazatel na objekt ISurfaceQueue.
návratové hodnoty
Pokud pDevice nemůže sdílet prostředky, vrátí tato funkce DXGI_ERROR_INVALID_CALL. Tato funkce vytvoří prostředky. Pokud selže, vrátí chybu. Pokud bude úspěšný, vrátí S_OK.
poznámky
Vytvoření objektu fronty také vytvoří všechny povrchy. Předpokládá se, že všechny povrchy mají 2D cíle vykreslení a vytvoří se s nastavenými příznaky D3D10_BIND_RENDER_TARGET a D3D10_BIND_SHADER_RESOURCE (nebo ekvivalentními příznaky pro různé moduly runtime).
Vývojář může zadat příznak, který označuje, jestli bude fronta přístupná více vlákny. Pokud nejsou nastaveny žádné příznaky (Příznaky == 0), fronta bude použita více vlákny. Vývojář může zadat přístup s jedním vláknem, který vypne synchronizační kód a v těchto případech zajistí zlepšení výkonu. Každá naklonovaná fronta má svůj vlastní příznak, takže je možné, aby různé fronty v systému měly různé ovládací prvky synchronizace.
Otevření producenta
HRESULT OpenProducer(
[in] IUnknown *pDevice,
[out] IDXGIXSurfaceProducer **ppProducer
);
parametrů
pDevice [in]
Zařízení producenta, které zařadí povrchy do fronty povrchu.
ppProducer [out] Vrátí objekt do rozhraní producenta.
návratové hodnoty
Pokud zařízení nemůže sdílet plochy, vrátí DXGI_ERROR_INVALID_CALL.
Otevření příjemce
HRESULT OpenConsumer(
[in] IUnknown *pDevice,
[out] IDXGIXSurfaceConsumer **ppConsumer
);
parametrů
pDevice [in]
Spotřební zařízení, které odvrácí povrchy z fronty povrchu.
ppConsumer [out] Vrátí objekt do rozhraní příjemce.
návratové hodnoty
Pokud zařízení nemůže sdílet plochy, vrátí DXGI_ERROR_INVALID_CALL.
poznámky
Tato funkce otevře všechny plochy ve frontě pro vstupní zařízení a uloží je do mezipaměti. Následná volání dequeue jednoduše přejdou do mezipaměti a nemusí znovu otevírat povrchy pokaždé.
Klonování idXGIXSurfaceQueue
typedef struct SHARED_SURFACE_QUEUE_CLONE_DESC {
UINT MetaDataSize;
DWORD Flags;
} SHARED_SURFACE_QUEUE_CLONE_DESC;
členovéMetaDataSize a příznaky mají stejné chování jako u CreateSurfaceQueue.
HRESULT Clone(
[in] SHARED_SURFACE_QUEUE_CLONE_DESC *pDesc,
[out] IDXGIXSurfaceQueue **ppQueue
);
parametrů
pDesc [in] Struktura, která poskytuje popis objektu Clone, který se má vytvořit. Tento parametr by měl být inicializován.
ppQueue [out] Vrátí inicializovaný objekt.
poznámky
Můžete klonovat z jakéhokoli existujícího objektu fronty, i když není kořenovým objektem.
IDXGIXSurfaceConsumer
- Pro IDirect3DDevice9 by měl být REFIID __uuidof(IDirect3DTexture9).
- Pro ID3D10Device by měl být REFIID __uuidof(ID3D10Texture2D).
- Pro ID3D11Device by měl být REFIID __uuidof(ID3D11Texture2D).
HRESULT Dequeue(
[in] REFIID id,
[out] void **ppSurface,
[in,out] void *pBuffer,
[in,out] UINT *pBufferSize,
[in] DWORD dwTimeout
);
parametrů
ID [in]
REFIID 2D povrchu spotřebovaného zařízení.
ppSurface [out] Vrátí ukazatel na povrch.
pBuffer [in, out] Volitelný parametr a pokud není NULL, při vrácení obsahuje metadata, která byla předána v odpovídajícím volání enqueue.
pBufferSize [in, out] Velikost pBufferv bajtech. Vrátí počet bajtů vrácených v pBuffer. Pokud volání fronty nezadalo metadata, pBuffer je nastavena na hodnotu 0.
dwTimeout [in] Určuje hodnotu časového limitu. Další podrobnosti najdete v poznámkách.
návratové hodnoty
Tato funkce může vrátit WAIT_TIMEOUT, pokud je zadána hodnota časového limitu a funkce se nevrátí před hodnotou časového limitu. Viz poznámky. Pokud nejsou k dispozici žádné povrchy, vrátí funkce ppSurface nastavena na NULL, pBufferSize nastavena na 0 a návratová hodnota je 0x80070120 (WIN32_TO_HRESULT(WAIT_TIMEOUT)).
poznámky
Toto rozhraní API může blokovat, pokud je fronta prázdná. Parametr dwTimeout funguje stejně jako rozhraní API pro synchronizaci Windows, jako je WaitForSingleObject. Pro neblokující chování použijte časový limit 0.
ISurfaceProducer
Toto rozhraní poskytuje dvě metody, které aplikaci umožňují vytvořit výčet povrchů. Po zařazení povrchu do fronty už není ukazatel povrchu platný a není bezpečný pro použití. Jedinou akcí, kterou má aplikace provést s ukazatelem, je uvolnit ji.
Metoda | Popis |
---|---|
ISurfaceProducer::Enqueue | Zařadí povrch do objektu fronty. Po dokončení tohoto volání je producent hotový s povrchem a povrch je připravený pro jiné zařízení. |
ISurfaceProducer::Flush | Používá se, pokud by aplikace měly mít neblokující chování. Podrobnosti najdete v poznámkách. |
enqueue
HRESULT Enqueue(
[in] IUnknown *pSurface,
[in] void *pBuffer,
[in] UINT BufferSize,
[in] DWORD Flags
);
parametrů
pSurface [in]
Povrch výrobního zařízení, které musí být vyčíslené. Tato plocha musí být vyřaděná plocha ze stejné sítě front.
pBuffer [in] Volitelný parametr, který slouží k předávání metadat. Měla by odkazovat na data, která se předají volání dequeue.
BufferSize [in] Velikost pBufferv bajtech.
Příznaky [in] Volitelný parametr, který řídí chování této funkce. Jediný příznak je SURFACE_QUEUE_FLAG_ DO_NOT_WAIT. Podívejte se na poznámky pro Flush. Pokud se nepředá žádný příznak (Příznaky == 0), použije se výchozí blokující chování.
návratové hodnoty
Tato funkce může vrátit DXGI_ERROR_WAS_STILL_DRAWING, pokud se použije příznak SURFACE_QUEUE_FLAG_DO_NOT_WAIT.
poznámky
- Tato funkce umístí povrch do fronty. Pokud aplikace nezadá SURFACE_QUEUE_FLAG_DO_NOT_WAIT, tato funkce blokuje a provede synchronizaci GPU-CPU, aby se zajistilo, že je veškeré vykreslování na zaplněné ploše dokončené. Pokud bude tato funkce úspěšná, bude k dispozici plocha pro vyřazení z fronty. Pokud chcete neblokující chování, použijte příznak DO_NOT_WAIT. Podrobnosti najdete v části Flush().
- Podle pravidel počítání odkazů modelu COM bude povrch vrácený dequeue addRef(), takže to aplikace nemusí udělat. Po volání enqueue musí aplikace uvolnit povrch, protože už ji nepoužívají.
vyprázdnění
HRESULT Flush(
[in] DWORD Flags,
[out] UINT *nSurfaces
);
parametrů
příznaky [in]
Jediný příznak je SURFACE_QUEUE_FLAG_ DO_NOT_WAIT. Viz poznámky.
nSurfaces [out] Vrátí počet povrchů, které jsou stále čekající a neprázdné.
návratové hodnoty
Tato funkce může vrátit DXGI_ERROR_WAS_STILL_DRAWING, pokud se použije příznak SURFACE_QUEUE_FLAG_DO_NOT_WAIT. Tato funkce vrátí S_OK, pokud byly některé povrchy úspěšně vyprázdněny. Tato funkce vrátí DXGI_ERROR_WAS_STILL_DRAWING pouze v případě, že nebyly vyprázdněny žádné povrchy. Společně návratová hodnota a nSurfaces indikovat aplikaci, jaká práce byla provedena a jestli je nějaká práce ponechána.
poznámky
Funkce Flush je smysluplná pouze v případě, že předchozí volání fronty použilo příznak DO_NOT_WAIT; jinak to bude no-op. Pokud volání enqueue použil příznak DO_NOT_WAIT, vrátí enqueue okamžitě a GPU-CPU synchronizace není zaručena. Povrch je stále považován za zařazení do fronty, výrobní zařízení jej nemůže nadále používat, ale není k dispozici pro odstranění fronty. Chcete-li se pokusit potvrdit povrch pro odstranění fronty, musí být volána funkce Flush. Vyprázdnění se pokusí potvrdit všechny povrchy, které jsou aktuálně ve frontě. Pokud se do funkce Flush nepředá žádný příznak, zablokuje a vymaže celou frontu a připraví všechny povrchy v ní k vyřazení z fronty. Pokud se použije příznak DO_NOT_WAIT, fronta zkontroluje povrchy a zjistí, jestli jsou některé z nich připravené; tento krok neblokuje. Povrchy, které dokončily synchronizaci GPU-CPU, budou připravené pro zařízení příjemce. Povrchy, které jsou stále čekající, nebudou ovlivněny. Funkce vrátí počet povrchů, které je stále potřeba vyprázdnit.
Poznámka
Vyprázdnění neruší sémantiku fronty. Rozhraní API zaručuje, že se nejprve zobrazí fronta, která se potvrdí před pozdějším zařazením povrchů do fronty, bez ohledu na to, kdy dojde k GPU-CPU synchronizaci.
Pomocná rutina vzájemné spolupráce Direct3D 9Ex a DXGI: Jak používat
Očekáváme, že většina případů použití zahrnuje dvě zařízení, která sdílejí řadu povrchů. Vzhledem k tomu, že se jedná o nejjednodušší scénář, tento dokument podrobně popisuje, jak tato rozhraní API použít k dosažení tohoto cíle, popisuje neblokující variantu a končí stručným oddílem o inicializaci pro tři zařízení.
Dvě zařízení
Ukázková aplikace, která používá tohoto pomocníka, může společně používat Direct3D 9Ex a Direct3D 11. Aplikace může zpracovávat obsah s oběma zařízeními a prezentovat obsah pomocí Direct3D 9. Zpracování může znamenat vykreslování obsahu, dekódování videa, spouštění výpočetních shaderů atd. Pro každý rámec aplikace nejprve zpracuje Direct3D 11, pak zpracuje s Direct3D 9 a nakonec bude prezentovat s Direct3D 9. Kromě toho zpracování s Direct3D 11 vytvoří určitá metadata, která bude potřeba spotřebovat v režimu Direct3D 9. Tato část popisuje použití pomocné rutiny ve třech částech, které odpovídají této sekvenci: inicializace, hlavní smyčka a vyčištění.
inicializace
Inicializace zahrnuje následující kroky:
- Inicializace obou zařízení
- Vytvořte kořenovou frontu: m_11to9Queue.
- Klonujte z kořenové fronty: m_9to11Queue.
- Volání Metody OpenProducer/OpenConsumer v obou frontách
Názvy front používají čísla 9 a 11 k označení, které rozhraní API je producent a který je příjemcem: m_producentkpříjemcefronty. Proto m_11to9Queue označuje frontu, pro kterou zařízení Direct3D 11 vytváří povrchy, které zařízení Direct3D 9 spotřebovává. Podobně m_9to11Queue označuje frontu, pro kterou Direct3D 9 vytváří povrchy, které Direct3D 11 spotřebovává.
Kořenová fronta je zpočátku plná a všechny klonované fronty jsou zpočátku prázdné. To by nemělo být problém pro aplikaci s výjimkou prvního cyklu enqueues a dequeues a dostupnosti metadat. Pokud se dequeue zeptá na metadata, ale žádná nebyla nastavena (buď proto, že se nic nenachází, nebo enqueue nenastavila nic), dequeue zjistí, že nebyla přijata žádná metadata.
inicializovat obě zařízení.
m_pD3D9Device = InitializeD3D9ExDevice(); m_pD3D11Device = InitializeD3D11Device();
vytvoření kořenové fronty.
Tento krok také vytvoří povrchy. Omezení velikosti a formátu jsou stejná jako při vytváření libovolného sdíleného prostředku. Velikost vyrovnávací paměti metadat je pevná při vytváření a v tomto případě jen předáváme UINT.
Fronta se musí vytvořit s pevným počtem povrchů. Výkon se bude lišit v závislosti na scénáři. Když máte více ploch, zvyšuje se pravděpodobnost, že jsou zařízení zaneprázdněná. Pokud je například jenom jedna plocha, nebude mezi těmito dvěma zařízeními žádná paralelizace. Na druhou stranu zvýšení počtu ploch zvyšuje nároky na paměť, což může snížit výkon. Tento příklad používá dva povrchy.SURFACE_QUEUE_DESC Desc; Desc.Width = 640; Desc.Height = 480; Desc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; Desc.NumSurfaces = 2; Desc.MetaDataSize = sizeof(UINT); Desc.Flags = 0; CreateSurfaceQueue(&Desc, m_pD3D9Device, &m_11to9Queue);
klonovat kořenovou frontu.
Každá klonovaná fronta musí používat stejné povrchy, ale může mít různé velikosti vyrovnávací paměti metadat a různé příznaky. V tomto případě neexistují žádná metadata z Direct3D 9 na Direct3D 11.SURFACE_QUEUE_CLONE_DESC Desc; Desc.MetaDataSize = 0; Desc.Flags = 0; m_11to9Queue->Clone(&Desc, &m_9to11Queue);
otevřete zařízení producenta a příjemce.
Aplikace musí provést tento krok před voláním Enqueue a Dequeue. Otevření producenta a příjemce vrátí rozhraní, která obsahují rozhraní API enqueue/dequeue.// Open for m_p9to11Queue. m_p9to11Queue->OpenProducer(m_pD3D9Device, &m_pD3D9Producer); m_p9to11Queue->OpenConsumer(m_pD3D11Device, &m_pD3D11Consumer); // Open for m_p11to9Queue. m_p11to9Queue->OpenProducer(m_pD3D11Device, &m_pD3D11Producer); m_p11to9Queue->OpenConsumer(m_pD3D9Device, &m_pD3D9Consumer);
hlavní smyčky
Použití fronty se modeluje po klasickém problému producenta/příjemce. Představte si to z hlediska jednotlivých zařízení. Každé zařízení musí provést tyto kroky: vyřazení z fronty, zpracování na povrchu a následné zařazení do fronty pro výrobu. U zařízení Direct3D 11 je využití Direct3D 9 téměř stejné.
// Direct3D 9 Device.
IDirect3DTexture9* pTexture9 = NULL;
REFIID surfaceID9 = _uuidof(IDirect3DTexture9);
UINT metaData;
UINT metaDataSize;
while (!done)
{
// Dequeue surface.
m_pD3D9Consumer->Dequeue(surfaceID9, (void**)&pSurface9,
&metaData, &metaDataSize, INFINITE);
// Process the surface.
ProcessD3D9(pSurface9);
// Present the surface using the meta data.
PresentD3D9(pSurface9, metaData, metaDataSize);
// Enqueue surface.
m_pD3D9Producer->Enqueue(pSurface9, NULL, 0, 0);
}
Čištění
Tento krok je velmi jednoduchý. Kromě běžných kroků pro vyčištění rozhraní API Direct3D musí aplikace uvolnit vrácené rozhraní COM.
m_pD3D9Producer->Release();
m_pD3D9Consumer->Release();
m_pD3D11Producer->Release();
m_pD3D11Consumer->Release();
m_p9to11Queue->Release();
m_p11to9Queue->Release();
Neblokující použití
Předchozí příklad dává smysl pro případ použití s více vlákny, ve kterém má každé zařízení vlastní vlákno. Příklad používá blokující verze rozhraní API: INFINITE pro vypršení časového limitu a bez příznaku k zařazení do fronty. Pokud chcete pomocnou rutinu použít neblokujícím způsobem, musíte provést jenom několik změn. Tato část ukazuje neblokující použití u obou zařízení na jednom vlákně.
inicializace
Inicializace je shodná s výjimkou příznaků. Vzhledem k tomu, že aplikace je jednovláknová, použijte tento příznak k vytvoření. Tím se vypne některý synchronizační kód, který může zlepšit výkon.
SURFACE_QUEUE_DESC Desc;
Desc.Width = 640;
Desc.Height = 480;
Desc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
Desc.NumSurfaces = 2;
Desc.MetaDataSize = sizeof(UINT);
Desc.Flags = SURFACE_QUEUE_FLAG_SINGLE_THREADED;
CreateSurfaceQueue(&Desc, m_pD3D9Device, &m_11to9Queue);
SURFACE_QUEUE_CLONE_DESC Desc;
Desc.MetaDataSize = 0;
Desc.Flags = SURFACE_QUEUE_FLAG_SINGLE_THREADED;
m_11to9Queue->Clone(&Desc, &m_9to11Queue);
Otevření zařízení producenta a konzumenta je stejné jako v příkladu blokování.
použití fronty
Frontu můžete používat mnoha způsoby neblokujícími způsoby s různými charakteristikami výkonu. Následující příklad je jednoduchý, ale má nízký výkon kvůli nadměrnému otáčení a dotazování. I přes tyto problémy ukazuje příklad, jak použít pomocnou rutinu. Přístup je neustále sedět ve smyčce a dequeue, procesu, fronty a vyprázdnění. Pokud některý z kroků selže, protože prostředek není k dispozici, aplikace se jednoduše pokusí znovu další smyčku.
// Direct3D 11 Device.
ID3D11Texture2D* pSurface11 = NULL;
REFIID surfaceID11 = __uuidof(ID3D11Texture2D);
UINT metaData;
while (!done)
{
//
// D3D11 Portion.
//
// Dequeue surface.
hr = m_pD3D11Consumer->Dequeue(surfaceID11,
(void**)&pSurface11,
NULL, 0, 0);
// Only continue if we got a surface.
if (SUCCEEDED(hr))
{
// Process the surface and return some meta data.
ProcessD3D11(pSurface11, &metaData);
// Enqueue surface.
m_pD3D11Producer->Enqueue(pSurface11, &metaData,
sizeof(UINT),
SURFACE_QUEUE_FLAG_DO_NOT_WAIT);
}
// Flush the queue to check if any surfaces completed.
m_pD3D11Producer->Flush(NULL,SURFACE_QUEUE_FLAG_DO_NOT_WAIT);
//
// Do the same with the Direct3D 9 Device.
//
// Dequeue surface.
hr = m_pD3D9Consumer->Dequeue(surfaceID9,
(void**)&pSurface9,
&metaData,
&metaDataSize, 0);
// Only continue if we got a surface.
if (SUCCEEDED(hr)))
{
// Process the surface.
ProcessD3D9(pSurface9);
// Present the surface using the meta data.
PresentD3D9(pSurface9, metaData, metaDataSize);
// Enqueue surface.
m_pD3D9Producer->Enqueue(pSurface9, NULL, 0,
SURFACE_QUEUE_FLAG_DO_NOT_WAIT);
}
// Flush the queue to check if any surfaces completed.
m_pD3D9Producer->Flush(NULL,SURFACE_QUEUE_FLAG_DO_NOT_WAIT);
}
Složitější řešení může zkontrolovat návratovou hodnotu z fronty a z vyprazdňování a zjistit, jestli je potřeba vyprázdnit.
Tři zařízení
Rozšíření předchozích příkladů o pokrytí více zařízení je jednoduché. Inicializace provede následující kód. Po vytvoření objektů Producer/Consumer je kód, který je použije, stejný. Tento příklad obsahuje tři zařízení a proto tři fronty. Povrchy proudí z Direct3D 9 do Direct3D 10 do Direct3D 11.
SURFACE_QUEUE_DESC Desc;
Desc.Width = 640;
Desc.Height = 480;
Desc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
Desc.NumSurfaces = 2;
Desc.MetaDataSize = sizeof(UINT);
Desc.Flags = 0;
SURFACE_QUEUE_CLONE_DESC Desc;
Desc.MetaDataSize = 0;
Desc.Flags = 0;
CreateSurfaceQueue(&Desc, m_pD3D9Device, &m_11to9Queue);
m_11to9Queue->Clone(&Desc, &m_9to10Queue);
m_11to9Queue->Clone(&Desc, &m_10to11Queue);
Jak už bylo zmíněno dříve, klonování funguje stejným způsobem bez ohledu na to, která fronta se klonuje. Například druhé volání klonování mohlo být mimo objekt m_9to10Queue.
// Open for m_p9to10Queue.
m_p9to10Queue->OpenProducer(m_pD3D9Device, &m_pD3D9Producer);
m_p9to10Queue->OpenConsumer(m_pD3D10Device, &m_pD3D10Consumer);
// Open for m_p10to11Queue.
m_p10to11Queue->OpenProducer(m_pD3D10Device, &m_pD3D10Producer);
m_p10to11Queue->OpenConsumer(m_pD3D11Device, &m_pD3D11Consumer);
// Open for m_p11to9Queue.
m_p11to9Queue->OpenProducer(m_pD3D11Device, &m_pD3D11Producer);
m_p11to9Queue->OpenConsumer(m_pD3D9Device, &m_pD3D9Consumer);
Závěr
Můžete vytvářet řešení, která používají interoperabilitu k využití výkonu více rozhraní API DirectX. Interoperabilita grafického rozhraní API systému Windows teď nabízí společný modul runtime pro správu povrchů DXGI 1.1. Tento modul runtime umožňuje synchronizovanou podporu sdílení plochy v nově vyvinutých rozhraních API, jako jsou Direct3D 11, Direct3D 10.1 a Direct2D. Vylepšení interoperability mezi novými rozhraními API a existujícími rozhraními API pomáhají migraci aplikací a zpětnou kompatibilitu. Rozhraní API pro uživatele Direct3D 9Ex a DXGI 1.1 můžou spolupracovat, jak je znázorněno s synchronizačním mechanismem dostupným ve starších ukázkových aplikacích Win32, které najdete v archivovaném galerii kódů MSDN Microsoft Samples úložišti.