Direct3D-Geräte-Manager

Der Microsoft Direct3D-Geräte-Manager ermöglicht es zwei oder mehr Objekten, dasselbe Microsoft Direct3D 9-Gerät gemeinsam zu nutzen. Ein -Objekt fungiert als Besitzer des Direct3D 9-Geräts. Um das Gerät freizugeben, erstellt der Besitzer des Geräts den Direct3D-Geräte-Manager. Andere Objekte können einen Zeiger auf den Geräte-Manager vom Gerätebesitzer abrufen und dann den Geräte-Manager verwenden, um einen Zeiger auf das Direct3D-Gerät abzurufen. Jedes Objekt, das das Gerät verwendet, verfügt über eine exklusive Sperre, die verhindert, dass andere Objekte das Gerät gleichzeitig verwenden.

Hinweis

Die Direct3D-Geräte-Manager unterstützt nur Direct3D 9-Geräte. DXGI-Geräte werden nicht unterstützt.

Um den Direct3D-Geräte-Manager zu erstellen, rufen Sie DXVA2CreateDirect3DDeviceManager9auf. Diese Funktion gibt einen Zeiger auf die IDirect3DDeviceManager9-Schnittstelle des Geräte-Managers zusammen mit einem Zurücksetzungstoken zurück. Mit dem Zurücksetzungstoken kann der Besitzer des Direct3D-Geräts das Gerät im Geräte-Manager festlegen (und zurücksetzen). Rufen Sie IDirect3DDeviceManager9::ResetDeviceauf, um den Geräte-Manager zu initialisieren. Übergeben Sie zusammen mit dem Zurücksetzungstoken einen Zeiger auf das Direct3D-Gerät.

Der folgende Code zeigt, wie Sie den Geräte-Manager erstellen und initialisieren.

HRESULT CreateD3DDeviceManager(
    IDirect3DDevice9 *pDevice, 
    UINT *pReset, 
    IDirect3DDeviceManager9 **ppManager
    )
{
    UINT resetToken = 0;

    IDirect3DDeviceManager9 *pD3DManager = NULL;

    HRESULT hr = DXVA2CreateDirect3DDeviceManager9(&resetToken, &pD3DManager);

    if (FAILED(hr))
    {
        goto done;
    }

    hr = pD3DManager->ResetDevice(pDevice, resetToken);

    if (FAILED(hr))
    {
        goto done;
    }

    *ppManager = pD3DManager;
    (*ppManager)->AddRef();

    *pReset = resetToken;


done:
    SafeRelease(&pD3DManager);
    return hr;
}

Der Gerätebesitzer muss anderen Objekten eine Möglichkeit bieten, einen Zeiger auf die IDirect3DDeviceManager9-Schnittstelle abzurufen. Der Standardmechanismus besteht darin, die INTERFACESGetService-Schnittstelle zu implementieren. Die Dienst-GUID ist MR _ VIDEO _ ACCELERATION _ SERVICE.

Um das Gerät für mehrere Objekte freizugeben, muss jedes Objekt (einschließlich des Besitzers des Geräts) wie folgt über den Geräte-Manager auf das Gerät zugreifen:

  1. Rufen Sie IDirect3DDeviceManager9::OpenDeviceHandle auf, um ein Handle für das Gerät abzurufen.
  2. Rufen Sie IDirect3DDeviceManager9::LockDevice auf, und übergeben Sie das Gerätehandle, um das Gerät zu verwenden. Die -Methode gibt einen Zeiger auf die IDirect3DDevice9-Schnittstelle zurück. Die -Methode kann abhängig vom Wert des fBlock-Parameters in einem Blockierungsmodus oder in einem nicht blockierenden Modus aufgerufen werden.
  3. Wenn Sie das Gerät nicht mehr verwenden, rufen Sie IDirect3DDeviceManager9::UnlockDevice auf. Diese Methode macht das Gerät für andere Objekte verfügbar.
  4. Rufen Sie vor dem Beenden IDirect3DDeviceManager9::CloseDeviceHandle auf, um das Gerätehandle zu schließen.

Sie sollten die Gerätesperre nur während der Verwendung des Geräts halten, da das Halten der Gerätesperre verhindert, dass andere Objekte das Gerät verwenden.

Der Besitzer des Geräts kann jederzeit zu einem anderen Gerät wechseln, indem er ResetDevice aufruft.Dies liegt in der Regel daran, dass das ursprüngliche Gerät verloren gegangen ist. Geräteverluste können aus verschiedenen Gründen auftreten, z. B. Änderungen an der Monitorauflösung, Energieverwaltungsaktionen, Sperren und Entsperren des Computers usw. Weitere Informationen finden Sie in der Direct3D-Dokumentation.

Die ResetDevice-Methode macht alle Gerätehandles ungültig, die zuvor geöffnet wurden. Wenn ein Gerätehandle ungültig ist, gibt die LockDevice-Methode DXVA2 _ E NEW VIDEO _ _ _ DEVICE zurück. Schließen Sie in diesem Fall das Handle, und rufen Sie OpenDeviceHandle erneut auf, um ein neues Gerätehandle abzurufen, wie im folgenden Code gezeigt.

Das folgende Beispiel zeigt, wie Sie ein Gerätehandle öffnen und das Gerät sperren.

HRESULT LockDevice(
    IDirect3DDeviceManager9 *pDeviceManager,
    BOOL fBlock,
    IDirect3DDevice9 **ppDevice, // Receives a pointer to the device.
    HANDLE *pHandle              // Receives a device handle.   
    )
{
    *pHandle = NULL;
    *ppDevice = NULL;

    HANDLE hDevice = 0;

    HRESULT hr = pDeviceManager->OpenDeviceHandle(&hDevice);

    if (SUCCEEDED(hr))
    {
        hr = pDeviceManager->LockDevice(hDevice, ppDevice, fBlock);
    }

    if (hr == DXVA2_E_NEW_VIDEO_DEVICE)
    {
        // Invalid device handle. Try to open a new device handle.
        hr = pDeviceManager->CloseDeviceHandle(hDevice);

        if (SUCCEEDED(hr))
        {
            hr = pDeviceManager->OpenDeviceHandle(&hDevice);
        }

        // Try to lock the device again.
        if (SUCCEEDED(hr))
        {
            hr = pDeviceManager->LockDevice(hDevice, ppDevice, TRUE); 
        }
    }

    if (SUCCEEDED(hr))
    {
        *pHandle = hDevice;
    }
    return hr;
}

DirectX Video Acceleration 2.0