Share via


Direct3D 裝置管理員

Microsoft Direct3D 裝置管理員可讓兩個或多個物件共用相同的 Microsoft Direct3D 9 裝置。 一個物件可作為 Direct3D 9 裝置的擁有者。 若要共用裝置,裝置的擁有者會建立 Direct3D 裝置管理員。 其他物件可以從裝置擁有者取得裝置管理員的指標,然後使用裝置管理員取得 Direct3D 裝置的指標。 使用裝置的任何物件都會保留獨佔鎖定,以防止其他物件同時使用裝置。

注意

Direct3D 裝置管理員僅支援 Direct3D 9 裝置。 它不支援 DXGI 裝置。

 

若要建立 Direct3D 裝置管理員,請呼叫 DXVA2CreateDirect3DDeviceManager9。 此函式會傳回裝置管理員 IDirect3DDeviceManager9 介面的指標,以及重設權杖。 重設權杖可讓 Direct3D 裝置的擁有者在裝置管理員上設定 (並重設) 裝置。 若要初始化裝置管理員,請呼叫 IDirect3DDeviceManager9::ResetDevice。 傳入 Direct3D 裝置的指標,以及重設權杖。

下列程式碼示範如何建立和初始化裝置管理員。

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;
}

裝置擁有者必須提供方法,讓其他物件取得 IDirect3DDeviceManager9 介面的指標。 標準機制是實作 IMFGetService 介面。 服務 GUID MR_VIDEO_ACCELERATION_SERVICE。

若要在數個物件之間共用裝置,每個物件 (包括裝置擁有者) 必須透過裝置管理員存取裝置,如下所示:

  1. 呼叫 IDirect3DDeviceManager9::OpenDeviceHandle 以取得裝置的控制碼。
  2. 若要使用裝置,請呼叫 IDirect3DDeviceManager9::LockDevice 並傳入裝置控制碼。 方法會傳回 IDirect3DDevice9 介面的指標。 方法可以在封鎖模式或非封鎖模式中呼叫,視 fBlock 參數的值而定。
  3. 當您使用裝置完成時,請呼叫 IDirect3DDeviceManager9::UnlockDevice。 這個方法可讓裝置可供其他物件使用。
  4. 結束之前,請呼叫 IDirect3DDeviceManager9::CloseDeviceHandle 以關閉裝置控制碼。

您應該只在使用裝置時保留裝置鎖定,因為保留裝置鎖定可防止其他物件使用裝置。

裝置的擁有者可以隨時呼叫 ResetDevice切換至另一個裝置,通常是因為原始裝置遺失。 裝置遺失可能會因為各種原因而發生,包括監視解析、電源管理動作、鎖定和解除鎖定電腦等變更。 如需詳細資訊,請參閱 Direct3D 檔。

ResetDevice方法會使先前開啟的任何裝置控制碼失效。 當裝置控制碼無效時, LockDevice 方法會傳回 DXVA2_E_NEW_VIDEO_DEVICE。 如果發生這種情況,請關閉控制碼並再次呼叫 OpenDeviceHandle 以取得新的裝置控制碼,如下列程式碼所示。

下列範例示範如何開啟裝置控制碼並鎖定裝置。

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 影片加速 2.0