Direct3D-Geräte-Manager

Der Microsoft Direct3D-Geräte-Manager ermöglicht es zwei oder mehr Objekten, dasselbe Microsoft Direct3D 9-Gerät gemeinsam nutzen zu können. Ein Objekt fungiert als Besitzer des Direct3D 9-Geräts. Um das Gerät zu teilen, erstellt der Besitzer des Geräts den Direct3D-Geräte-Manager. Andere Objekte können vom Gerätebesitzer einen Zeiger auf den Geräte-Manager abrufen und dann den Geräte-Manager verwenden, um einen Zeiger auf das Direct3D-Gerät abzurufen. Jedes Objekt, das das Gerät verwendet, enthält 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 DXVA2CreateDirect3DDeviceManager9 auf. Diese Funktion gibt einen Zeiger auf die IDirect3DDeviceManager9-Schnittstelle des Geräte-Managers zusammen mit einem Zurücksetzungstoken zurück. Das Zurücksetzungstoken ermöglicht es dem Besitzer des Direct3D-Geräts, das Gerät im Geräte-Manager festzulegen (und zurückzusetzen). Um den Geräte-Manager zu initialisieren, rufen Sie IDirect3DDeviceManager9::ResetDevice auf. Ü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 eine Möglichkeit für andere Objekte bereitstellen, einen Zeiger auf die IDirect3DDeviceManager9-Schnittstelle abzurufen. Der Standardmechanismus besteht darin, die IMFGetService-Schnittstelle zu implementieren. Die Dienst-GUID ist MR_VIDEO_ACCELERATION_SERVICE.

Um das Gerät für mehrere Objekte freigeben zu können, 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 auf das Gerät zu erhalten.
  2. Um das Gerät zu verwenden, rufen Sie IDirect3DDeviceManager9::LockDevice auf, und übergeben Sie das Gerätehandle. Die -Methode gibt einen Zeiger auf die IDirect3DDevice9-Schnittstelle zurück. Die Methode kann je nach Wert des fBlock-Parameters in einem Blockierungsmodus oder in einem nicht blockierenden Modus aufgerufen werden.
  3. Wenn Sie mit dem Gerät fertig sind, 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, in der Regel, weil das ursprüngliche Gerät verloren gegangen ist. Geräteverluste können aus verschiedenen Gründen auftreten, z. B. Änderungen in der Monitorauflösung, Energieverwaltungsaktionen, Sperren und Entsperren des Computers usw. Weitere Informationen finden Sie in der Direct3D-Dokumentation.

Mit der ResetDevice-Methode werden alle Zuvor geöffneten Gerätehandles ungültig. Wenn ein Gerätehandle ungültig ist, gibt die LockDevice-MethodeDXVA2_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 zu erhalten, wie im folgenden Code gezeigt.

Das folgende Beispiel zeigt, wie Sie einen 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 VideoBeschleunigung 2.0